blob: 12f72f525f7ae4fe98b7244c460567968941b5e1 [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"
Victor Stinnerd5d9e812019-05-13 12:35:37 +020013#ifdef MS_WINDOWS
14 /* include <windows.h> early to avoid conflict with pycore_condvar.h:
15
16 #define WIN32_LEAN_AND_MEAN
17 #include <windows.h>
18
19 FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */
20# include <windows.h>
21#endif
22
Victor Stinner4a21e572020-04-15 02:35:41 +020023#include "pycore_ceval.h" // _PyEval_ReInitThreads()
24#include "pycore_import.h" // _PyImport_ReInitLock()
25#include "pycore_pystate.h" // _PyInterpreterState_GET()
26#include "structmember.h" // PyMemberDef
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020027#ifndef MS_WINDOWS
Victor Stinnerd5d9e812019-05-13 12:35:37 +020028# include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010029#else
Victor Stinnerd5d9e812019-05-13 12:35:37 +020030# include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020031#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000032
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020033/* On android API level 21, 'AT_EACCESS' is not declared although
34 * HAVE_FACCESSAT is defined. */
35#ifdef __ANDROID__
Victor Stinner5eca75d2020-04-15 15:07:31 +020036# undef HAVE_FACCESSAT
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020037#endif
38
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000039#include <stdio.h> /* needed for ctermid() */
40
Ronald Oussorene8b1c032020-11-22 11:18:40 +010041/*
42 * A number of APIs are available on macOS from a certain macOS version.
43 * To support building with a new SDK while deploying to older versions
44 * the availability test is split into two:
45 * - HAVE_<FUNCTION>: The configure check for compile time availability
46 * - HAVE_<FUNCTION>_RUNTIME: Runtime check for availability
47 *
48 * The latter is always true when not on macOS, or when using a compiler
49 * that does not support __has_builtin (older versions of Xcode).
50 *
51 * Due to compiler restrictions there is one valid use of HAVE_<FUNCTION>_RUNTIME:
52 * if (HAVE_<FUNCTION>_RUNTIME) { ... }
53 *
54 * In mixing the test with other tests or using negations will result in compile
55 * errors.
56 */
57#if defined(__APPLE__)
58
59#if defined(__has_builtin) && __has_builtin(__builtin_available)
60# define HAVE_FSTATAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
61# define HAVE_FACCESSAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
62# define HAVE_FCHMODAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
63# define HAVE_FCHOWNAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
64# define HAVE_LINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
65# define HAVE_FDOPENDIR_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
66# define HAVE_MKDIRAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
67# define HAVE_RENAMEAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
68# define HAVE_UNLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
69# define HAVE_OPENAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
70# define HAVE_READLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
71# define HAVE_SYMLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
72# define HAVE_FUTIMENS_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
73# define HAVE_UTIMENSAT_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
74# define HAVE_PWRITEV_RUNTIME __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)
75
76# define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *)
77
78#else /* Xcode 8 or earlier */
79
80 /* __builtin_available is not present in these compilers, but
81 * some of the symbols might be weak linked (10.10 SDK or later
82 * deploying on 10.9.
83 *
84 * Fall back to the older style of availability checking for
85 * symbols introduced in macOS 10.10.
86 */
87
88# ifdef HAVE_FSTATAT
89# define HAVE_FSTATAT_RUNTIME (fstatat != NULL)
90# endif
91
92# ifdef HAVE_FACCESSAT
93# define HAVE_FACCESSAT_RUNTIME (faccessat != NULL)
94# endif
95
96# ifdef HAVE_FCHMODAT
97# define HAVE_FCHMODAT_RUNTIME (fchmodat != NULL)
98# endif
99
100# ifdef HAVE_FCHOWNAT
101# define HAVE_FCHOWNAT_RUNTIME (fchownat != NULL)
102# endif
103
104# ifdef HAVE_LINKAT
105# define HAVE_LINKAT_RUNTIME (linkat != NULL)
106# endif
107
108# ifdef HAVE_FDOPENDIR
109# define HAVE_FDOPENDIR_RUNTIME (fdopendir != NULL)
110# endif
111
112# ifdef HAVE_MKDIRAT
113# define HAVE_MKDIRAT_RUNTIME (mkdirat != NULL)
114# endif
115
116# ifdef HAVE_RENAMEAT
117# define HAVE_RENAMEAT_RUNTIME (renameat != NULL)
118# endif
119
120# ifdef HAVE_UNLINKAT
121# define HAVE_UNLINKAT_RUNTIME (unlinkat != NULL)
122# endif
123
124# ifdef HAVE_OPENAT
125# define HAVE_OPENAT_RUNTIME (openat != NULL)
126# endif
127
128# ifdef HAVE_READLINKAT
129# define HAVE_READLINKAT_RUNTIME (readlinkat != NULL)
130# endif
131
132# ifdef HAVE_SYMLINKAT
133# define HAVE_SYMLINKAT_RUNTIME (symlinkat != NULL)
134# endif
135
136#endif
137
138#ifdef HAVE_FUTIMESAT
139/* Some of the logic for weak linking depends on this assertion */
140# error "HAVE_FUTIMESAT unexpectedly defined"
141#endif
142
143#else
144# define HAVE_FSTATAT_RUNTIME 1
145# define HAVE_FACCESSAT_RUNTIME 1
146# define HAVE_FCHMODAT_RUNTIME 1
147# define HAVE_FCHOWNAT_RUNTIME 1
148# define HAVE_LINKAT_RUNTIME 1
149# define HAVE_FDOPENDIR_RUNTIME 1
150# define HAVE_MKDIRAT_RUNTIME 1
151# define HAVE_RENAMEAT_RUNTIME 1
152# define HAVE_UNLINKAT_RUNTIME 1
153# define HAVE_OPENAT_RUNTIME 1
154# define HAVE_READLINKAT_RUNTIME 1
155# define HAVE_SYMLINKAT_RUNTIME 1
156# define HAVE_FUTIMENS_RUNTIME 1
157# define HAVE_UTIMENSAT_RUNTIME 1
158# define HAVE_PWRITEV_RUNTIME 1
159#endif
160
161
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000162#ifdef __cplusplus
163extern "C" {
164#endif
165
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000166PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000167"This module provides access to operating system functionality that is\n\
168standardized by the C Standard and the POSIX standard (a thinly\n\
169disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000170corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171
Martin v. Löwis0073f2e2002-11-21 23:52:35 +0000172
Ross Lagerwall4d076da2011-03-18 06:56:53 +0200173#ifdef HAVE_SYS_UIO_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200174# include <sys/uio.h>
Ross Lagerwall4d076da2011-03-18 06:56:53 +0200175#endif
176
Christian Heimes75b96182017-09-05 15:53:09 +0200177#ifdef HAVE_SYS_SYSMACROS_H
178/* GNU C Library: major(), minor(), makedev() */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200179# include <sys/sysmacros.h>
Christian Heimes75b96182017-09-05 15:53:09 +0200180#endif
181
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000182#ifdef HAVE_SYS_TYPES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200183# include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000184#endif /* HAVE_SYS_TYPES_H */
185
186#ifdef HAVE_SYS_STAT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200187# include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000188#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000189
Guido van Rossum36bc6801995-06-14 22:54:23 +0000190#ifdef HAVE_SYS_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200191# include <sys/wait.h> // WNOHANG
Guido van Rossum36bc6801995-06-14 22:54:23 +0000192#endif
Benjamin Peterson5c0c3252019-11-05 21:58:31 -0800193#ifdef HAVE_LINUX_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200194# include <linux/wait.h> // P_PIDFD
Benjamin Peterson5c0c3252019-11-05 21:58:31 -0800195#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000197#ifdef HAVE_SIGNAL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200198# include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000199#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +0000200
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201#ifdef HAVE_FCNTL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200202# include <fcntl.h>
203#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000205#ifdef HAVE_GRP_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200206# include <grp.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000207#endif
208
Barry Warsaw5676bd12003-01-07 20:57:09 +0000209#ifdef HAVE_SYSEXITS_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200210# include <sysexits.h>
211#endif
Barry Warsaw5676bd12003-01-07 20:57:09 +0000212
Anthony Baxter8a560de2004-10-13 15:30:56 +0000213#ifdef HAVE_SYS_LOADAVG_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200214# include <sys/loadavg.h>
Anthony Baxter8a560de2004-10-13 15:30:56 +0000215#endif
216
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000217#ifdef HAVE_SYS_SENDFILE_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200218# include <sys/sendfile.h>
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000219#endif
220
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200221#if defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200222# include <copyfile.h>
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200223#endif
224
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500225#ifdef HAVE_SCHED_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200226# include <sched.h>
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500227#endif
228
Pablo Galindoaac4d032019-05-31 19:39:47 +0100229#ifdef HAVE_COPY_FILE_RANGE
Victor Stinner5eca75d2020-04-15 15:07:31 +0200230# include <unistd.h>
Pablo Galindoaac4d032019-05-31 19:39:47 +0100231#endif
232
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500233#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200234# undef HAVE_SCHED_SETAFFINITY
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500235#endif
236
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200237#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200238# define USE_XATTRS
Benjamin Peterson9428d532011-09-14 11:45:52 -0400239#endif
240
241#ifdef USE_XATTRS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200242# include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400243#endif
244
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000245#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200246# ifdef HAVE_SYS_SOCKET_H
247# include <sys/socket.h>
248# endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000249#endif
250
Victor Stinner8b905bd2011-10-25 13:34:04 +0200251#ifdef HAVE_DLFCN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200252# include <dlfcn.h>
Victor Stinner8b905bd2011-10-25 13:34:04 +0200253#endif
254
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200255#ifdef __hpux
Victor Stinner5eca75d2020-04-15 15:07:31 +0200256# include <sys/mpctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200257#endif
258
259#if defined(__DragonFly__) || \
260 defined(__OpenBSD__) || \
261 defined(__FreeBSD__) || \
262 defined(__NetBSD__) || \
263 defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200264# include <sys/sysctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200265#endif
266
Victor Stinner9b1f4742016-09-06 16:18:52 -0700267#ifdef HAVE_LINUX_RANDOM_H
268# include <linux/random.h>
269#endif
270#ifdef HAVE_GETRANDOM_SYSCALL
271# include <sys/syscall.h>
272#endif
273
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100274#if defined(MS_WINDOWS)
275# define TERMSIZE_USE_CONIO
276#elif defined(HAVE_SYS_IOCTL_H)
277# include <sys/ioctl.h>
278# if defined(HAVE_TERMIOS_H)
279# include <termios.h>
280# endif
281# if defined(TIOCGWINSZ)
282# define TERMSIZE_USE_IOCTL
283# endif
284#endif /* MS_WINDOWS */
285
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000286/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000287/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000288#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200289# define HAVE_OPENDIR 1
290# define HAVE_SYSTEM 1
291# include <process.h>
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000292#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200293# ifdef _MSC_VER
294 /* Microsoft compiler */
295# define HAVE_GETPPID 1
296# define HAVE_GETLOGIN 1
297# define HAVE_SPAWNV 1
298# define HAVE_EXECV 1
299# define HAVE_WSPAWNV 1
300# define HAVE_WEXECV 1
301# define HAVE_PIPE 1
302# define HAVE_SYSTEM 1
303# define HAVE_CWAIT 1
304# define HAVE_FSYNC 1
305# define fsync _commit
306# else
307 /* Unix functions that the configure script doesn't check for */
308# ifndef __VXWORKS__
309# define HAVE_EXECV 1
310# define HAVE_FORK 1
311# if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
312# define HAVE_FORK1 1
313# endif
314# endif
315# define HAVE_GETEGID 1
316# define HAVE_GETEUID 1
317# define HAVE_GETGID 1
318# define HAVE_GETPPID 1
319# define HAVE_GETUID 1
320# define HAVE_KILL 1
321# define HAVE_OPENDIR 1
322# define HAVE_PIPE 1
323# define HAVE_SYSTEM 1
324# define HAVE_WAIT 1
325# define HAVE_TTYNAME 1
326# endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000327#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000328
Eddie Elizondob3966632019-11-05 07:16:14 -0800329_Py_IDENTIFIER(__fspath__);
Victor Stinnera2f7c002012-02-08 03:36:25 +0100330
Larry Hastings61272b72014-01-07 12:41:53 -0800331/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000332# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800333module os
Larry Hastings61272b72014-01-07 12:41:53 -0800334[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000335/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100336
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000337#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000338
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000339#if defined(__sgi)&&_COMPILER_VERSION>=700
340/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
341 (default) */
342extern char *ctermid_r(char *);
343#endif
344
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000345#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346
pxinwrf2d7ac72019-05-21 18:46:37 +0800347#if defined(__VXWORKS__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200348# include <vxCpuLib.h>
349# include <rtpLib.h>
350# include <wait.h>
351# include <taskLib.h>
352# ifndef _P_WAIT
353# define _P_WAIT 0
354# define _P_NOWAIT 1
355# define _P_NOWAITO 1
356# endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800357#endif /* __VXWORKS__ */
358
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000359#ifdef HAVE_POSIX_SPAWN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200360# include <spawn.h>
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000361#endif
362
Guido van Rossumb6775db1994-08-01 11:34:53 +0000363#ifdef HAVE_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200364# include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000365#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000366
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000367#ifdef HAVE_SYS_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200368# include <sys/utime.h>
369# define HAVE_UTIME_H /* pretend we do for the rest of this file */
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000370#endif /* HAVE_SYS_UTIME_H */
371
Guido van Rossumb6775db1994-08-01 11:34:53 +0000372#ifdef HAVE_SYS_TIMES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200373# include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000374#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000375
376#ifdef HAVE_SYS_PARAM_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200377# include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000378#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000379
380#ifdef HAVE_SYS_UTSNAME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200381# include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000382#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000383
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000384#ifdef HAVE_DIRENT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200385# include <dirent.h>
386# define NAMLEN(dirent) strlen((dirent)->d_name)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000387#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200388# if defined(__WATCOMC__) && !defined(__QNX__)
389# include <direct.h>
390# define NAMLEN(dirent) strlen((dirent)->d_name)
391# else
392# define dirent direct
393# define NAMLEN(dirent) (dirent)->d_namlen
394# endif
395# ifdef HAVE_SYS_NDIR_H
396# include <sys/ndir.h>
397# endif
398# ifdef HAVE_SYS_DIR_H
399# include <sys/dir.h>
400# endif
401# ifdef HAVE_NDIR_H
402# include <ndir.h>
403# endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000404#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000405
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000406#ifdef _MSC_VER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200407# ifdef HAVE_DIRECT_H
408# include <direct.h>
409# endif
410# ifdef HAVE_IO_H
411# include <io.h>
412# endif
413# ifdef HAVE_PROCESS_H
414# include <process.h>
415# endif
416# ifndef IO_REPARSE_TAG_SYMLINK
417# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
418# endif
419# ifndef IO_REPARSE_TAG_MOUNT_POINT
420# define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
421# endif
422# include "osdefs.h" // SEP
423# include <malloc.h>
424# include <windows.h>
425# include <shellapi.h> // ShellExecute()
426# include <lmcons.h> // UNLEN
427# define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000428#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000429
Tim Petersbc2e10e2002-03-03 23:17:02 +0000430#ifndef MAXPATHLEN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200431# if defined(PATH_MAX) && PATH_MAX > 1024
432# define MAXPATHLEN PATH_MAX
433# else
434# define MAXPATHLEN 1024
435# endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000436#endif /* MAXPATHLEN */
437
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000438#ifdef UNION_WAIT
Victor Stinner5eca75d2020-04-15 15:07:31 +0200439 /* Emulate some macros on systems that have a union instead of macros */
440# ifndef WIFEXITED
441# define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
442# endif
443# ifndef WEXITSTATUS
444# define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
445# endif
446# ifndef WTERMSIG
447# define WTERMSIG(u_wait) ((u_wait).w_termsig)
448# endif
449# define WAIT_TYPE union wait
450# define WAIT_STATUS_INT(s) (s.w_status)
451#else
452 /* !UNION_WAIT */
453# define WAIT_TYPE int
454# define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000455#endif /* UNION_WAIT */
456
Greg Wardb48bc172000-03-01 21:51:56 +0000457/* Don't use the "_r" form if we don't need it (also, won't have a
458 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200459#if defined(HAVE_CTERMID_R)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200460# define USE_CTERMID_R
Greg Wardb48bc172000-03-01 21:51:56 +0000461#endif
462
Fred Drake699f3522000-06-29 21:12:41 +0000463/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000464#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000465#undef FSTAT
466#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200467#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200468# define STAT win32_stat
469# define LSTAT win32_lstat
470# define FSTAT _Py_fstat_noraise
471# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000472#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200473# define STAT stat
474# define LSTAT lstat
475# define FSTAT fstat
476# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000477#endif
478
Tim Peters11b23062003-04-23 02:39:17 +0000479#if defined(MAJOR_IN_MKDEV)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200480# include <sys/mkdev.h>
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000481#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200482# if defined(MAJOR_IN_SYSMACROS)
483# include <sys/sysmacros.h>
484# endif
485# if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
486# include <sys/mkdev.h>
487# endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000488#endif
Fred Drake699f3522000-06-29 21:12:41 +0000489
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200490#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200491# define INITFUNC PyInit_nt
492# define MODNAME "nt"
Victor Stinner6036e442015-03-08 01:58:04 +0100493#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200494# define INITFUNC PyInit_posix
495# define MODNAME "posix"
Victor Stinner6036e442015-03-08 01:58:04 +0100496#endif
497
jcea6c51d512018-01-28 14:00:08 +0100498#if defined(__sun)
499/* Something to implement in autoconf, not present in autoconf 2.69 */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200500# define HAVE_STRUCT_STAT_ST_FSTYPE 1
jcea6c51d512018-01-28 14:00:08 +0100501#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200502
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600503/* memfd_create is either defined in sys/mman.h or sys/memfd.h
504 * linux/memfd.h defines additional flags
505 */
506#ifdef HAVE_SYS_MMAN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200507# include <sys/mman.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600508#endif
509#ifdef HAVE_SYS_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200510# include <sys/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600511#endif
512#ifdef HAVE_LINUX_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200513# include <linux/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600514#endif
515
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800516#ifdef _Py_MEMORY_SANITIZER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200517# include <sanitizer/msan_interface.h>
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800518#endif
519
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200520#ifdef HAVE_FORK
521static void
522run_at_forkers(PyObject *lst, int reverse)
523{
524 Py_ssize_t i;
525 PyObject *cpy;
526
527 if (lst != NULL) {
528 assert(PyList_CheckExact(lst));
529
530 /* Use a list copy in case register_at_fork() is called from
531 * one of the callbacks.
532 */
533 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
534 if (cpy == NULL)
535 PyErr_WriteUnraisable(lst);
536 else {
537 if (reverse)
538 PyList_Reverse(cpy);
539 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
540 PyObject *func, *res;
541 func = PyList_GET_ITEM(cpy, i);
Jeroen Demeyer7f41c8e2019-07-04 12:35:31 +0200542 res = _PyObject_CallNoArg(func);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200543 if (res == NULL)
544 PyErr_WriteUnraisable(func);
545 else
546 Py_DECREF(res);
547 }
548 Py_DECREF(cpy);
549 }
550 }
551}
552
553void
554PyOS_BeforeFork(void)
555{
Victor Stinner81a7be32020-04-14 15:14:01 +0200556 run_at_forkers(_PyInterpreterState_GET()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200557
558 _PyImport_AcquireLock();
559}
560
561void
562PyOS_AfterFork_Parent(void)
563{
564 if (_PyImport_ReleaseLock() <= 0)
565 Py_FatalError("failed releasing import lock after fork");
566
Victor Stinner81a7be32020-04-14 15:14:01 +0200567 run_at_forkers(_PyInterpreterState_GET()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200568}
569
570void
571PyOS_AfterFork_Child(void)
572{
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200573 _PyRuntimeState *runtime = &_PyRuntime;
574 _PyGILState_Reinit(runtime);
Victor Stinnerd5d9e812019-05-13 12:35:37 +0200575 _PyEval_ReInitThreads(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200576 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200577 _PySignal_AfterFork();
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200578 _PyRuntimeState_ReInitThreads(runtime);
Victor Stinnerb49858b2019-05-24 15:20:23 +0200579 _PyInterpreterState_DeleteExceptMain(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200580
Victor Stinner81a7be32020-04-14 15:14:01 +0200581 run_at_forkers(_PyInterpreterState_GET()->after_forkers_child, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200582}
583
584static int
585register_at_forker(PyObject **lst, PyObject *func)
586{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700587 if (func == NULL) /* nothing to register? do nothing. */
588 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200589 if (*lst == NULL) {
590 *lst = PyList_New(0);
591 if (*lst == NULL)
592 return -1;
593 }
594 return PyList_Append(*lst, func);
595}
Victor Stinner87255be2020-04-07 23:11:49 +0200596#endif /* HAVE_FORK */
597
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200598
599/* Legacy wrapper */
600void
601PyOS_AfterFork(void)
602{
603#ifdef HAVE_FORK
604 PyOS_AfterFork_Child();
605#endif
606}
607
608
Victor Stinner6036e442015-03-08 01:58:04 +0100609#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200610/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700611void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
612void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200613 ULONG, struct _Py_stat_struct *);
614#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700615
Larry Hastings9cf065c2012-06-22 16:30:09 -0700616
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200617#ifndef MS_WINDOWS
618PyObject *
619_PyLong_FromUid(uid_t uid)
620{
621 if (uid == (uid_t)-1)
622 return PyLong_FromLong(-1);
623 return PyLong_FromUnsignedLong(uid);
624}
625
626PyObject *
627_PyLong_FromGid(gid_t gid)
628{
629 if (gid == (gid_t)-1)
630 return PyLong_FromLong(-1);
631 return PyLong_FromUnsignedLong(gid);
632}
633
634int
635_Py_Uid_Converter(PyObject *obj, void *p)
636{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700637 uid_t uid;
638 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200639 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200640 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700641 unsigned long uresult;
642
643 index = PyNumber_Index(obj);
644 if (index == NULL) {
645 PyErr_Format(PyExc_TypeError,
646 "uid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800647 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200648 return 0;
649 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700650
651 /*
652 * Handling uid_t is complicated for two reasons:
653 * * Although uid_t is (always?) unsigned, it still
654 * accepts -1.
655 * * We don't know its size in advance--it may be
656 * bigger than an int, or it may be smaller than
657 * a long.
658 *
659 * So a bit of defensive programming is in order.
660 * Start with interpreting the value passed
661 * in as a signed long and see if it works.
662 */
663
664 result = PyLong_AsLongAndOverflow(index, &overflow);
665
666 if (!overflow) {
667 uid = (uid_t)result;
668
669 if (result == -1) {
670 if (PyErr_Occurred())
671 goto fail;
672 /* It's a legitimate -1, we're done. */
673 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200674 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700675
676 /* Any other negative number is disallowed. */
677 if (result < 0)
678 goto underflow;
679
680 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200681 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700682 (long)uid != result)
683 goto underflow;
684 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200685 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700686
687 if (overflow < 0)
688 goto underflow;
689
690 /*
691 * Okay, the value overflowed a signed long. If it
692 * fits in an *unsigned* long, it may still be okay,
693 * as uid_t may be unsigned long on this platform.
694 */
695 uresult = PyLong_AsUnsignedLong(index);
696 if (PyErr_Occurred()) {
697 if (PyErr_ExceptionMatches(PyExc_OverflowError))
698 goto overflow;
699 goto fail;
700 }
701
702 uid = (uid_t)uresult;
703
704 /*
705 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
706 * but this value would get interpreted as (uid_t)-1 by chown
707 * and its siblings. That's not what the user meant! So we
708 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100709 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700710 */
711 if (uid == (uid_t)-1)
712 goto overflow;
713
714 /* Ensure the value wasn't truncated. */
715 if (sizeof(uid_t) < sizeof(long) &&
716 (unsigned long)uid != uresult)
717 goto overflow;
718 /* fallthrough */
719
720success:
721 Py_DECREF(index);
722 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200723 return 1;
724
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700725underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200726 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700727 "uid is less than minimum");
728 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200729
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700730overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200731 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700732 "uid is greater than maximum");
733 /* fallthrough */
734
735fail:
736 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200737 return 0;
738}
739
740int
741_Py_Gid_Converter(PyObject *obj, void *p)
742{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700743 gid_t gid;
744 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200745 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200746 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700747 unsigned long uresult;
748
749 index = PyNumber_Index(obj);
750 if (index == NULL) {
751 PyErr_Format(PyExc_TypeError,
752 "gid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800753 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200754 return 0;
755 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700756
757 /*
758 * Handling gid_t is complicated for two reasons:
759 * * Although gid_t is (always?) unsigned, it still
760 * accepts -1.
761 * * We don't know its size in advance--it may be
762 * bigger than an int, or it may be smaller than
763 * a long.
764 *
765 * So a bit of defensive programming is in order.
766 * Start with interpreting the value passed
767 * in as a signed long and see if it works.
768 */
769
770 result = PyLong_AsLongAndOverflow(index, &overflow);
771
772 if (!overflow) {
773 gid = (gid_t)result;
774
775 if (result == -1) {
776 if (PyErr_Occurred())
777 goto fail;
778 /* It's a legitimate -1, we're done. */
779 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200780 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700781
782 /* Any other negative number is disallowed. */
783 if (result < 0) {
784 goto underflow;
785 }
786
787 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200788 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700789 (long)gid != result)
790 goto underflow;
791 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200792 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700793
794 if (overflow < 0)
795 goto underflow;
796
797 /*
798 * Okay, the value overflowed a signed long. If it
799 * fits in an *unsigned* long, it may still be okay,
800 * as gid_t may be unsigned long on this platform.
801 */
802 uresult = PyLong_AsUnsignedLong(index);
803 if (PyErr_Occurred()) {
804 if (PyErr_ExceptionMatches(PyExc_OverflowError))
805 goto overflow;
806 goto fail;
807 }
808
809 gid = (gid_t)uresult;
810
811 /*
812 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
813 * but this value would get interpreted as (gid_t)-1 by chown
814 * and its siblings. That's not what the user meant! So we
815 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100816 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700817 */
818 if (gid == (gid_t)-1)
819 goto overflow;
820
821 /* Ensure the value wasn't truncated. */
822 if (sizeof(gid_t) < sizeof(long) &&
823 (unsigned long)gid != uresult)
824 goto overflow;
825 /* fallthrough */
826
827success:
828 Py_DECREF(index);
829 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200830 return 1;
831
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700832underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200833 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700834 "gid is less than minimum");
835 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200836
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700837overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200838 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700839 "gid is greater than maximum");
840 /* fallthrough */
841
842fail:
843 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200844 return 0;
845}
846#endif /* MS_WINDOWS */
847
848
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700849#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800850
851
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200852#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
853static int
854_Py_Dev_Converter(PyObject *obj, void *p)
855{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200856 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200857 if (PyErr_Occurred())
858 return 0;
859 return 1;
860}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800861#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200862
863
Larry Hastings9cf065c2012-06-22 16:30:09 -0700864#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400865/*
866 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
867 * without the int cast, the value gets interpreted as uint (4291925331),
868 * which doesn't play nicely with all the initializer lines in this file that
869 * look like this:
870 * int dir_fd = DEFAULT_DIR_FD;
871 */
872#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700873#else
874#define DEFAULT_DIR_FD (-100)
875#endif
876
877static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300878_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200879{
880 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700881 long long_value;
882
883 PyObject *index = PyNumber_Index(o);
884 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700885 return 0;
886 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700887
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300888 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700889 long_value = PyLong_AsLongAndOverflow(index, &overflow);
890 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300891 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200892 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700893 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700894 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700895 return 0;
896 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200897 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700898 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700899 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700900 return 0;
901 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700902
Larry Hastings9cf065c2012-06-22 16:30:09 -0700903 *p = (int)long_value;
904 return 1;
905}
906
907static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200908dir_fd_converter(PyObject *o, void *p)
909{
910 if (o == Py_None) {
911 *(int *)p = DEFAULT_DIR_FD;
912 return 1;
913 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300914 else if (PyIndex_Check(o)) {
915 return _fd_converter(o, (int *)p);
916 }
917 else {
918 PyErr_Format(PyExc_TypeError,
919 "argument should be integer or None, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800920 _PyType_Name(Py_TYPE(o)));
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300921 return 0;
922 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700923}
924
Eddie Elizondob3966632019-11-05 07:16:14 -0800925typedef struct {
926 PyObject *billion;
Eddie Elizondob3966632019-11-05 07:16:14 -0800927 PyObject *DirEntryType;
928 PyObject *ScandirIteratorType;
929#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
930 PyObject *SchedParamType;
931#endif
932 PyObject *StatResultType;
933 PyObject *StatVFSResultType;
934 PyObject *TerminalSizeType;
935 PyObject *TimesResultType;
936 PyObject *UnameResultType;
937#if defined(HAVE_WAITID) && !defined(__APPLE__)
938 PyObject *WaitidResultType;
939#endif
940#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
941 PyObject *struct_rusage;
942#endif
943 PyObject *st_mode;
944} _posixstate;
945
Eddie Elizondob3966632019-11-05 07:16:14 -0800946
Hai Shif707d942020-03-16 21:15:01 +0800947static inline _posixstate*
948get_posix_state(PyObject *module)
949{
950 void *state = PyModule_GetState(module);
951 assert(state != NULL);
952 return (_posixstate *)state;
953}
954
Larry Hastings9cf065c2012-06-22 16:30:09 -0700955/*
956 * A PyArg_ParseTuple "converter" function
957 * that handles filesystem paths in the manner
958 * preferred by the os module.
959 *
960 * path_converter accepts (Unicode) strings and their
961 * subclasses, and bytes and their subclasses. What
962 * it does with the argument depends on the platform:
963 *
964 * * On Windows, if we get a (Unicode) string we
965 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700966 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700967 *
968 * * On all other platforms, strings are encoded
969 * to bytes using PyUnicode_FSConverter, then we
970 * extract the char * from the bytes object and
971 * return that.
972 *
973 * path_converter also optionally accepts signed
974 * integers (representing open file descriptors) instead
975 * of path strings.
976 *
977 * Input fields:
978 * path.nullable
979 * If nonzero, the path is permitted to be None.
980 * path.allow_fd
981 * If nonzero, the path is permitted to be a file handle
982 * (a signed int) instead of a string.
983 * path.function_name
984 * If non-NULL, path_converter will use that as the name
985 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700986 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700987 * path.argument_name
988 * If non-NULL, path_converter will use that as the name
989 * of the parameter in error messages.
990 * (If path.argument_name is NULL it uses "path".)
991 *
992 * Output fields:
993 * path.wide
994 * Points to the path if it was expressed as Unicode
995 * and was not encoded. (Only used on Windows.)
996 * path.narrow
997 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700998 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000999 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -07001000 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001 * path.fd
1002 * Contains a file descriptor if path.accept_fd was true
1003 * and the caller provided a signed integer instead of any
1004 * sort of string.
1005 *
1006 * WARNING: if your "path" parameter is optional, and is
1007 * unspecified, path_converter will never get called.
1008 * So if you set allow_fd, you *MUST* initialize path.fd = -1
1009 * yourself!
1010 * path.length
1011 * The length of the path in characters, if specified as
1012 * a string.
1013 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +08001014 * The original object passed in (if get a PathLike object,
1015 * the result of PyOS_FSPath() is treated as the original object).
1016 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -07001017 * path.cleanup
1018 * For internal use only. May point to a temporary object.
1019 * (Pay no attention to the man behind the curtain.)
1020 *
1021 * At most one of path.wide or path.narrow will be non-NULL.
1022 * If path was None and path.nullable was set,
1023 * or if path was an integer and path.allow_fd was set,
1024 * both path.wide and path.narrow will be NULL
1025 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +02001026 *
Larry Hastings9cf065c2012-06-22 16:30:09 -07001027 * path_converter takes care to not write to the path_t
1028 * unless it's successful. However it must reset the
1029 * "cleanup" field each time it's called.
1030 *
1031 * Use as follows:
1032 * path_t path;
1033 * memset(&path, 0, sizeof(path));
1034 * PyArg_ParseTuple(args, "O&", path_converter, &path);
1035 * // ... use values from path ...
1036 * path_cleanup(&path);
1037 *
1038 * (Note that if PyArg_Parse fails you don't need to call
1039 * path_cleanup(). However it is safe to do so.)
1040 */
1041typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +01001042 const char *function_name;
1043 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001044 int nullable;
1045 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001046 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -07001047#ifdef MS_WINDOWS
1048 BOOL narrow;
1049#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001050 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001051#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052 int fd;
1053 Py_ssize_t length;
1054 PyObject *object;
1055 PyObject *cleanup;
1056} path_t;
1057
Steve Dowercc16be82016-09-08 10:35:16 -07001058#ifdef MS_WINDOWS
1059#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
1060 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
1061#else
Larry Hastings2f936352014-08-05 14:04:04 +10001062#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
1063 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -07001064#endif
Larry Hastings31826802013-10-19 00:09:25 -07001065
Larry Hastings9cf065c2012-06-22 16:30:09 -07001066static void
Xiang Zhang04316c42017-01-08 23:26:57 +08001067path_cleanup(path_t *path)
1068{
1069 Py_CLEAR(path->object);
1070 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001071}
1072
1073static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001074path_converter(PyObject *o, void *p)
1075{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001076 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +08001077 PyObject *bytes = NULL;
1078 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001079 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001080 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001081#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +08001082 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001083 const wchar_t *wide;
1084#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001085
1086#define FORMAT_EXCEPTION(exc, fmt) \
1087 PyErr_Format(exc, "%s%s" fmt, \
1088 path->function_name ? path->function_name : "", \
1089 path->function_name ? ": " : "", \
1090 path->argument_name ? path->argument_name : "path")
1091
1092 /* Py_CLEANUP_SUPPORTED support */
1093 if (o == NULL) {
1094 path_cleanup(path);
1095 return 1;
1096 }
1097
Brett Cannon3f9183b2016-08-26 14:44:48 -07001098 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +08001099 path->object = path->cleanup = NULL;
1100 /* path->object owns a reference to the original object */
1101 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001102
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001103 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001104 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001105#ifdef MS_WINDOWS
1106 path->narrow = FALSE;
1107#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001108 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001109#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001110 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001111 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001112 }
1113
Brett Cannon3f9183b2016-08-26 14:44:48 -07001114 /* Only call this here so that we don't treat the return value of
1115 os.fspath() as an fd or buffer. */
1116 is_index = path->allow_fd && PyIndex_Check(o);
1117 is_buffer = PyObject_CheckBuffer(o);
1118 is_bytes = PyBytes_Check(o);
1119 is_unicode = PyUnicode_Check(o);
1120
1121 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
1122 /* Inline PyOS_FSPath() for better error messages. */
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001123 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001124
1125 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1126 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001127 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001128 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001129 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001130 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001131 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001132 goto error_exit;
1133 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001134 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001135 is_unicode = 1;
1136 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001137 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001138 is_bytes = 1;
1139 }
1140 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001141 PyErr_Format(PyExc_TypeError,
1142 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -08001143 "not %.200s", _PyType_Name(Py_TYPE(o)),
1144 _PyType_Name(Py_TYPE(res)));
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001145 Py_DECREF(res);
1146 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001147 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001148
1149 /* still owns a reference to the original object */
1150 Py_DECREF(o);
1151 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001152 }
1153
1154 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001155#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001156 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001157 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001158 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001159 }
Victor Stinner59799a82013-11-13 14:17:30 +01001160 if (length > 32767) {
1161 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001162 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001163 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001164 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001165 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001166 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001167 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001168
1169 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001170 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001171 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001172 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001173#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001174 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001175 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001176 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001177#endif
1178 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001179 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001180 bytes = o;
1181 Py_INCREF(bytes);
1182 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001183 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001184 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001185 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001186 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1187 "%s%s%s should be %s, not %.200s",
1188 path->function_name ? path->function_name : "",
1189 path->function_name ? ": " : "",
1190 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001191 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1192 "integer or None" :
1193 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1194 path->nullable ? "string, bytes, os.PathLike or None" :
1195 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001196 _PyType_Name(Py_TYPE(o)))) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001197 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001198 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001199 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001200 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001201 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001202 }
1203 }
Steve Dowercc16be82016-09-08 10:35:16 -07001204 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001205 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001206 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001207 }
1208 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001209#ifdef MS_WINDOWS
1210 path->narrow = FALSE;
1211#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001212 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001213#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001214 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001215 }
1216 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001217 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001218 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1219 path->function_name ? path->function_name : "",
1220 path->function_name ? ": " : "",
1221 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001222 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1223 "integer or None" :
1224 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1225 path->nullable ? "string, bytes, os.PathLike or None" :
1226 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001227 _PyType_Name(Py_TYPE(o)));
Xiang Zhang04316c42017-01-08 23:26:57 +08001228 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001229 }
1230
Larry Hastings9cf065c2012-06-22 16:30:09 -07001231 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001232 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001233 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001234 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001235 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001236 }
1237
Steve Dowercc16be82016-09-08 10:35:16 -07001238#ifdef MS_WINDOWS
1239 wo = PyUnicode_DecodeFSDefaultAndSize(
1240 narrow,
1241 length
1242 );
1243 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001244 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001245 }
1246
Xiang Zhang04316c42017-01-08 23:26:57 +08001247 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001248 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001249 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001250 }
1251 if (length > 32767) {
1252 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001253 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001254 }
1255 if (wcslen(wide) != length) {
1256 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001257 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001258 }
1259 path->wide = wide;
1260 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001261 path->cleanup = wo;
1262 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001263#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001264 path->wide = NULL;
1265 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001266 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001267 /* Still a reference owned by path->object, don't have to
1268 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001269 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001270 }
1271 else {
1272 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001273 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001274#endif
1275 path->fd = -1;
1276
1277 success_exit:
1278 path->length = length;
1279 path->object = o;
1280 return Py_CLEANUP_SUPPORTED;
1281
1282 error_exit:
1283 Py_XDECREF(o);
1284 Py_XDECREF(bytes);
1285#ifdef MS_WINDOWS
1286 Py_XDECREF(wo);
1287#endif
1288 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001289}
1290
1291static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001292argument_unavailable_error(const char *function_name, const char *argument_name)
1293{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001294 PyErr_Format(PyExc_NotImplementedError,
1295 "%s%s%s unavailable on this platform",
1296 (function_name != NULL) ? function_name : "",
1297 (function_name != NULL) ? ": ": "",
1298 argument_name);
1299}
1300
1301static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001302dir_fd_unavailable(PyObject *o, void *p)
1303{
1304 int dir_fd;
1305 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001306 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001307 if (dir_fd != DEFAULT_DIR_FD) {
1308 argument_unavailable_error(NULL, "dir_fd");
1309 return 0;
1310 }
1311 *(int *)p = dir_fd;
1312 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001313}
1314
1315static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001316fd_specified(const char *function_name, int fd)
1317{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001318 if (fd == -1)
1319 return 0;
1320
1321 argument_unavailable_error(function_name, "fd");
1322 return 1;
1323}
1324
1325static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001326follow_symlinks_specified(const char *function_name, int follow_symlinks)
1327{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001328 if (follow_symlinks)
1329 return 0;
1330
1331 argument_unavailable_error(function_name, "follow_symlinks");
1332 return 1;
1333}
1334
1335static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001336path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1337{
Steve Dowercc16be82016-09-08 10:35:16 -07001338 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1339#ifndef MS_WINDOWS
1340 && !path->narrow
1341#endif
1342 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001343 PyErr_Format(PyExc_ValueError,
1344 "%s: can't specify dir_fd without matching path",
1345 function_name);
1346 return 1;
1347 }
1348 return 0;
1349}
1350
1351static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001352dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1353{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001354 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1355 PyErr_Format(PyExc_ValueError,
1356 "%s: can't specify both dir_fd and fd",
1357 function_name);
1358 return 1;
1359 }
1360 return 0;
1361}
1362
1363static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001364fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1365 int follow_symlinks)
1366{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001367 if ((fd > 0) && (!follow_symlinks)) {
1368 PyErr_Format(PyExc_ValueError,
1369 "%s: cannot use fd and follow_symlinks together",
1370 function_name);
1371 return 1;
1372 }
1373 return 0;
1374}
1375
1376static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001377dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1378 int follow_symlinks)
1379{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001380 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1381 PyErr_Format(PyExc_ValueError,
1382 "%s: cannot use dir_fd and follow_symlinks together",
1383 function_name);
1384 return 1;
1385 }
1386 return 0;
1387}
1388
Larry Hastings2f936352014-08-05 14:04:04 +10001389#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001390 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001391#else
Larry Hastings2f936352014-08-05 14:04:04 +10001392 typedef off_t Py_off_t;
1393#endif
1394
1395static int
1396Py_off_t_converter(PyObject *arg, void *addr)
1397{
1398#ifdef HAVE_LARGEFILE_SUPPORT
1399 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1400#else
1401 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001402#endif
1403 if (PyErr_Occurred())
1404 return 0;
1405 return 1;
1406}
Larry Hastings2f936352014-08-05 14:04:04 +10001407
1408static PyObject *
1409PyLong_FromPy_off_t(Py_off_t offset)
1410{
1411#ifdef HAVE_LARGEFILE_SUPPORT
1412 return PyLong_FromLongLong(offset);
1413#else
1414 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001415#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001416}
1417
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001418#ifdef HAVE_SIGSET_T
1419/* Convert an iterable of integers to a sigset.
1420 Return 1 on success, return 0 and raise an exception on error. */
1421int
1422_Py_Sigset_Converter(PyObject *obj, void *addr)
1423{
1424 sigset_t *mask = (sigset_t *)addr;
1425 PyObject *iterator, *item;
1426 long signum;
1427 int overflow;
1428
Rémi Lapeyref0900192019-05-04 01:30:53 +02001429 // The extra parens suppress the unreachable-code warning with clang on MacOS
1430 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001431 /* Probably only if mask == NULL. */
1432 PyErr_SetFromErrno(PyExc_OSError);
1433 return 0;
1434 }
1435
1436 iterator = PyObject_GetIter(obj);
1437 if (iterator == NULL) {
1438 return 0;
1439 }
1440
1441 while ((item = PyIter_Next(iterator)) != NULL) {
1442 signum = PyLong_AsLongAndOverflow(item, &overflow);
1443 Py_DECREF(item);
1444 if (signum <= 0 || signum >= NSIG) {
1445 if (overflow || signum != -1 || !PyErr_Occurred()) {
1446 PyErr_Format(PyExc_ValueError,
1447 "signal number %ld out of range", signum);
1448 }
1449 goto error;
1450 }
1451 if (sigaddset(mask, (int)signum)) {
1452 if (errno != EINVAL) {
1453 /* Probably impossible */
1454 PyErr_SetFromErrno(PyExc_OSError);
1455 goto error;
1456 }
1457 /* For backwards compatibility, allow idioms such as
1458 * `range(1, NSIG)` but warn about invalid signal numbers
1459 */
1460 const char msg[] =
1461 "invalid signal number %ld, please use valid_signals()";
1462 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1463 goto error;
1464 }
1465 }
1466 }
1467 if (!PyErr_Occurred()) {
1468 Py_DECREF(iterator);
1469 return 1;
1470 }
1471
1472error:
1473 Py_DECREF(iterator);
1474 return 0;
1475}
1476#endif /* HAVE_SIGSET_T */
1477
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001478#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001479
1480static int
Brian Curtind25aef52011-06-13 15:16:04 -05001481win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001482{
Martin Panter70214ad2016-08-04 02:38:59 +00001483 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1484 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001485 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001486
1487 if (0 == DeviceIoControl(
1488 reparse_point_handle,
1489 FSCTL_GET_REPARSE_POINT,
1490 NULL, 0, /* in buffer */
1491 target_buffer, sizeof(target_buffer),
1492 &n_bytes_returned,
1493 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001494 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001495
1496 if (reparse_tag)
1497 *reparse_tag = rdb->ReparseTag;
1498
Brian Curtind25aef52011-06-13 15:16:04 -05001499 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001500}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001501
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001502#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001503
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001504/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001505#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001506/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001507** environ directly, we must obtain it with _NSGetEnviron(). See also
1508** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001509*/
1510#include <crt_externs.h>
pxinwrf2d7ac72019-05-21 18:46:37 +08001511#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001512extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001513#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001514
Barry Warsaw53699e91996-12-10 23:23:01 +00001515static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001516convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001517{
Victor Stinner8c62be82010-05-06 00:08:46 +00001518 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001519#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001520 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001521#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001522 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001523#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001524
Victor Stinner8c62be82010-05-06 00:08:46 +00001525 d = PyDict_New();
1526 if (d == NULL)
1527 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001528#ifdef MS_WINDOWS
1529 /* _wenviron must be initialized in this way if the program is started
1530 through main() instead of wmain(). */
1531 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001532 e = _wenviron;
Benoit Hudson723f71a2019-12-06 14:15:03 -05001533#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1534 /* environ is not accessible as an extern in a shared object on OSX; use
1535 _NSGetEnviron to resolve it. The value changes if you add environment
1536 variables between calls to Py_Initialize, so don't cache the value. */
1537 e = *_NSGetEnviron();
Victor Stinner8c62be82010-05-06 00:08:46 +00001538#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001539 e = environ;
1540#endif
1541 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001542 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001543 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001544 PyObject *k;
1545 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001546#ifdef MS_WINDOWS
1547 const wchar_t *p = wcschr(*e, L'=');
1548#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001549 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001550#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001551 if (p == NULL)
1552 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001553#ifdef MS_WINDOWS
1554 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1555#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001556 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001557#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001558 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001559 Py_DECREF(d);
1560 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001561 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001562#ifdef MS_WINDOWS
1563 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1564#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001565 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001566#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001567 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001568 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001569 Py_DECREF(d);
1570 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001571 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001572 if (PyDict_GetItemWithError(d, k) == NULL) {
1573 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1574 Py_DECREF(v);
1575 Py_DECREF(k);
1576 Py_DECREF(d);
1577 return NULL;
1578 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001579 }
1580 Py_DECREF(k);
1581 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001582 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001583 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001584}
1585
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001586/* Set a POSIX-specific error from errno, and return NULL */
1587
Barry Warsawd58d7641998-07-23 16:14:40 +00001588static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001589posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001590{
Victor Stinner8c62be82010-05-06 00:08:46 +00001591 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001592}
Mark Hammondef8b6542001-05-13 08:04:26 +00001593
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001594#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001595static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001596win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001597{
Victor Stinner8c62be82010-05-06 00:08:46 +00001598 /* XXX We should pass the function name along in the future.
1599 (winreg.c also wants to pass the function name.)
1600 This would however require an additional param to the
1601 Windows error object, which is non-trivial.
1602 */
1603 errno = GetLastError();
1604 if (filename)
1605 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1606 else
1607 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001608}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001609
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001610static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001611win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001612{
1613 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001614 if (filename)
1615 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001616 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001617 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001618 filename);
1619 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001620 return PyErr_SetFromWindowsErr(err);
1621}
1622
1623static PyObject *
1624win32_error_object(const char* function, PyObject* filename)
1625{
1626 errno = GetLastError();
1627 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001628}
1629
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001630#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001631
Larry Hastings9cf065c2012-06-22 16:30:09 -07001632static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001633posix_path_object_error(PyObject *path)
1634{
1635 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1636}
1637
1638static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001639path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001640{
1641#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001642 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1643 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001644#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001645 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001646#endif
1647}
1648
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001649static PyObject *
1650path_object_error2(PyObject *path, PyObject *path2)
1651{
1652#ifdef MS_WINDOWS
1653 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1654 PyExc_OSError, 0, path, path2);
1655#else
1656 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1657#endif
1658}
1659
1660static PyObject *
1661path_error(path_t *path)
1662{
1663 return path_object_error(path->object);
1664}
Larry Hastings31826802013-10-19 00:09:25 -07001665
Larry Hastingsb0827312014-02-09 22:05:19 -08001666static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001667posix_path_error(path_t *path)
1668{
1669 return posix_path_object_error(path->object);
1670}
1671
1672static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001673path_error2(path_t *path, path_t *path2)
1674{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001675 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001676}
1677
1678
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001679/* POSIX generic methods */
1680
Larry Hastings2f936352014-08-05 14:04:04 +10001681static int
1682fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001683{
Victor Stinner8c62be82010-05-06 00:08:46 +00001684 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001685 int *pointer = (int *)p;
1686 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001687 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001688 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001689 *pointer = fd;
1690 return 1;
1691}
1692
1693static PyObject *
1694posix_fildes_fd(int fd, int (*func)(int))
1695{
1696 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001697 int async_err = 0;
1698
1699 do {
1700 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001701 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001702 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001703 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001704 Py_END_ALLOW_THREADS
1705 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1706 if (res != 0)
1707 return (!async_err) ? posix_error() : NULL;
1708 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001709}
Guido van Rossum21142a01999-01-08 21:05:37 +00001710
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001711
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001712#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001713/* This is a reimplementation of the C library's chdir function,
1714 but one that produces Win32 errors instead of DOS error codes.
1715 chdir is essentially a wrapper around SetCurrentDirectory; however,
1716 it also needs to set "magic" environment variables indicating
1717 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001718static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001719win32_wchdir(LPCWSTR path)
1720{
Victor Stinnered537822015-12-13 21:40:26 +01001721 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001722 int result;
1723 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001724
Victor Stinner8c62be82010-05-06 00:08:46 +00001725 if(!SetCurrentDirectoryW(path))
1726 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001727 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001728 if (!result)
1729 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001730 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001731 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001732 if (!new_path) {
1733 SetLastError(ERROR_OUTOFMEMORY);
1734 return FALSE;
1735 }
1736 result = GetCurrentDirectoryW(result, new_path);
1737 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001738 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001739 return FALSE;
1740 }
1741 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001742 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1743 wcsncmp(new_path, L"//", 2) == 0);
1744 if (!is_unc_like_path) {
1745 env[1] = new_path[0];
1746 result = SetEnvironmentVariableW(env, new_path);
1747 }
Victor Stinnered537822015-12-13 21:40:26 +01001748 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001749 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001750 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001751}
1752#endif
1753
Martin v. Löwis14694662006-02-03 12:54:16 +00001754#ifdef MS_WINDOWS
1755/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1756 - time stamps are restricted to second resolution
1757 - file modification times suffer from forth-and-back conversions between
1758 UTC and local time
1759 Therefore, we implement our own stat, based on the Win32 API directly.
1760*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001761#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001762#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001763#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001764
Victor Stinner6036e442015-03-08 01:58:04 +01001765static void
Steve Dowercc16be82016-09-08 10:35:16 -07001766find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1767 BY_HANDLE_FILE_INFORMATION *info,
1768 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001769{
1770 memset(info, 0, sizeof(*info));
1771 info->dwFileAttributes = pFileData->dwFileAttributes;
1772 info->ftCreationTime = pFileData->ftCreationTime;
1773 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1774 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1775 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1776 info->nFileSizeLow = pFileData->nFileSizeLow;
1777/* info->nNumberOfLinks = 1; */
1778 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1779 *reparse_tag = pFileData->dwReserved0;
1780 else
1781 *reparse_tag = 0;
1782}
1783
Guido van Rossumd8faa362007-04-27 19:54:29 +00001784static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001785attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001786{
Victor Stinner8c62be82010-05-06 00:08:46 +00001787 HANDLE hFindFile;
1788 WIN32_FIND_DATAW FileData;
1789 hFindFile = FindFirstFileW(pszFile, &FileData);
1790 if (hFindFile == INVALID_HANDLE_VALUE)
1791 return FALSE;
1792 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001793 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001794 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001795}
1796
Brian Curtind25aef52011-06-13 15:16:04 -05001797static int
Steve Dowercc16be82016-09-08 10:35:16 -07001798win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001799 BOOL traverse)
1800{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001801 HANDLE hFile;
1802 BY_HANDLE_FILE_INFORMATION fileInfo;
1803 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1804 DWORD fileType, error;
1805 BOOL isUnhandledTag = FALSE;
1806 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001807
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001808 DWORD access = FILE_READ_ATTRIBUTES;
1809 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1810 if (!traverse) {
1811 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1812 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001813
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001814 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001815 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001816 /* Either the path doesn't exist, or the caller lacks access. */
1817 error = GetLastError();
1818 switch (error) {
1819 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1820 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1821 /* Try reading the parent directory. */
1822 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1823 /* Cannot read the parent directory. */
1824 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001825 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001826 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001827 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1828 if (traverse ||
1829 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1830 /* The stat call has to traverse but cannot, so fail. */
1831 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001832 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001833 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001834 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001835 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001836
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001837 case ERROR_INVALID_PARAMETER:
1838 /* \\.\con requires read or write access. */
1839 hFile = CreateFileW(path, access | GENERIC_READ,
1840 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1841 OPEN_EXISTING, flags, NULL);
1842 if (hFile == INVALID_HANDLE_VALUE) {
1843 SetLastError(error);
1844 return -1;
1845 }
1846 break;
1847
1848 case ERROR_CANT_ACCESS_FILE:
1849 /* bpo37834: open unhandled reparse points if traverse fails. */
1850 if (traverse) {
1851 traverse = FALSE;
1852 isUnhandledTag = TRUE;
1853 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1854 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1855 }
1856 if (hFile == INVALID_HANDLE_VALUE) {
1857 SetLastError(error);
1858 return -1;
1859 }
1860 break;
1861
1862 default:
1863 return -1;
1864 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001865 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001866
1867 if (hFile != INVALID_HANDLE_VALUE) {
1868 /* Handle types other than files on disk. */
1869 fileType = GetFileType(hFile);
1870 if (fileType != FILE_TYPE_DISK) {
1871 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1872 retval = -1;
1873 goto cleanup;
1874 }
1875 DWORD fileAttributes = GetFileAttributesW(path);
1876 memset(result, 0, sizeof(*result));
1877 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1878 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1879 /* \\.\pipe\ or \\.\mailslot\ */
1880 result->st_mode = _S_IFDIR;
1881 } else if (fileType == FILE_TYPE_CHAR) {
1882 /* \\.\nul */
1883 result->st_mode = _S_IFCHR;
1884 } else if (fileType == FILE_TYPE_PIPE) {
1885 /* \\.\pipe\spam */
1886 result->st_mode = _S_IFIFO;
1887 }
1888 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1889 goto cleanup;
1890 }
1891
1892 /* Query the reparse tag, and traverse a non-link. */
1893 if (!traverse) {
1894 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1895 &tagInfo, sizeof(tagInfo))) {
1896 /* Allow devices that do not support FileAttributeTagInfo. */
1897 switch (GetLastError()) {
1898 case ERROR_INVALID_PARAMETER:
1899 case ERROR_INVALID_FUNCTION:
1900 case ERROR_NOT_SUPPORTED:
1901 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1902 tagInfo.ReparseTag = 0;
1903 break;
1904 default:
1905 retval = -1;
1906 goto cleanup;
1907 }
1908 } else if (tagInfo.FileAttributes &
1909 FILE_ATTRIBUTE_REPARSE_POINT) {
1910 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1911 if (isUnhandledTag) {
1912 /* Traversing previously failed for either this link
1913 or its target. */
1914 SetLastError(ERROR_CANT_ACCESS_FILE);
1915 retval = -1;
1916 goto cleanup;
1917 }
1918 /* Traverse a non-link, but not if traversing already failed
1919 for an unhandled tag. */
1920 } else if (!isUnhandledTag) {
1921 CloseHandle(hFile);
1922 return win32_xstat_impl(path, result, TRUE);
1923 }
1924 }
1925 }
1926
1927 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
1928 switch (GetLastError()) {
1929 case ERROR_INVALID_PARAMETER:
1930 case ERROR_INVALID_FUNCTION:
1931 case ERROR_NOT_SUPPORTED:
Steve Dower772ec0f2019-09-04 14:42:54 -07001932 /* Volumes and physical disks are block devices, e.g.
1933 \\.\C: and \\.\PhysicalDrive0. */
1934 memset(result, 0, sizeof(*result));
1935 result->st_mode = 0x6000; /* S_IFBLK */
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001936 goto cleanup;
1937 }
Steve Dower772ec0f2019-09-04 14:42:54 -07001938 retval = -1;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001939 goto cleanup;
1940 }
1941 }
1942
1943 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
1944
1945 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
1946 /* Fix the file execute permissions. This hack sets S_IEXEC if
1947 the filename has an extension that is commonly used by files
1948 that CreateProcessW can execute. A real implementation calls
1949 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
1950 AccessCheck to check for generic read, write, and execute
1951 access. */
1952 const wchar_t *fileExtension = wcsrchr(path, '.');
1953 if (fileExtension) {
1954 if (_wcsicmp(fileExtension, L".exe") == 0 ||
1955 _wcsicmp(fileExtension, L".bat") == 0 ||
1956 _wcsicmp(fileExtension, L".cmd") == 0 ||
1957 _wcsicmp(fileExtension, L".com") == 0) {
1958 result->st_mode |= 0111;
1959 }
1960 }
1961 }
1962
1963cleanup:
1964 if (hFile != INVALID_HANDLE_VALUE) {
Steve Dower772ec0f2019-09-04 14:42:54 -07001965 /* Preserve last error if we are failing */
1966 error = retval ? GetLastError() : 0;
1967 if (!CloseHandle(hFile)) {
1968 retval = -1;
1969 } else if (retval) {
1970 /* Restore last error */
1971 SetLastError(error);
1972 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001973 }
1974
1975 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001976}
1977
1978static int
Steve Dowercc16be82016-09-08 10:35:16 -07001979win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001980{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001981 /* Protocol violation: we explicitly clear errno, instead of
1982 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001983 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001984 errno = 0;
1985 return code;
1986}
Brian Curtind25aef52011-06-13 15:16:04 -05001987/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001988
1989 In Posix, stat automatically traverses symlinks and returns the stat
1990 structure for the target. In Windows, the equivalent GetFileAttributes by
1991 default does not traverse symlinks and instead returns attributes for
1992 the symlink.
1993
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001994 Instead, we will open the file (which *does* traverse symlinks by default)
1995 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00001996
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001997static int
Steve Dowercc16be82016-09-08 10:35:16 -07001998win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001999{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002000 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00002001}
2002
Victor Stinner8c62be82010-05-06 00:08:46 +00002003static int
Steve Dowercc16be82016-09-08 10:35:16 -07002004win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00002005{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002006 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00002007}
2008
Martin v. Löwis14694662006-02-03 12:54:16 +00002009#endif /* MS_WINDOWS */
2010
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002011PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002012"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002013This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002014 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002015or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
2016\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002017Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
2018or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002019\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002020See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002021
2022static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002023 {"st_mode", "protection bits"},
2024 {"st_ino", "inode"},
2025 {"st_dev", "device"},
2026 {"st_nlink", "number of hard links"},
2027 {"st_uid", "user ID of owner"},
2028 {"st_gid", "group ID of owner"},
2029 {"st_size", "total size, in bytes"},
2030 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
2031 {NULL, "integer time of last access"},
2032 {NULL, "integer time of last modification"},
2033 {NULL, "integer time of last change"},
2034 {"st_atime", "time of last access"},
2035 {"st_mtime", "time of last modification"},
2036 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07002037 {"st_atime_ns", "time of last access in nanoseconds"},
2038 {"st_mtime_ns", "time of last modification in nanoseconds"},
2039 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002040#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002042#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002043#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002044 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002045#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002046#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002047 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002048#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002049#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002051#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002052#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002054#endif
2055#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002056 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002057#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002058#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2059 {"st_file_attributes", "Windows file attribute bits"},
2060#endif
jcea6c51d512018-01-28 14:00:08 +01002061#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2062 {"st_fstype", "Type of filesystem"},
2063#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002064#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2065 {"st_reparse_tag", "Windows reparse tag"},
2066#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002067 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002068};
2069
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002070#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002071#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002072#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002073#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002074#endif
2075
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002076#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002077#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2078#else
2079#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2080#endif
2081
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002082#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002083#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2084#else
2085#define ST_RDEV_IDX ST_BLOCKS_IDX
2086#endif
2087
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002088#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2089#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2090#else
2091#define ST_FLAGS_IDX ST_RDEV_IDX
2092#endif
2093
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002094#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002095#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002096#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002097#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002098#endif
2099
2100#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2101#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2102#else
2103#define ST_BIRTHTIME_IDX ST_GEN_IDX
2104#endif
2105
Zachary Ware63f277b2014-06-19 09:46:37 -05002106#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2107#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
2108#else
2109#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2110#endif
2111
jcea6c51d512018-01-28 14:00:08 +01002112#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2113#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2114#else
2115#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2116#endif
2117
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002118#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2119#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2120#else
2121#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2122#endif
2123
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002124static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002125 "stat_result", /* name */
2126 stat_result__doc__, /* doc */
2127 stat_result_fields,
2128 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002129};
2130
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002131PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002132"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2133This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002134 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002135or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002136\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002137See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002138
2139static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 {"f_bsize", },
2141 {"f_frsize", },
2142 {"f_blocks", },
2143 {"f_bfree", },
2144 {"f_bavail", },
2145 {"f_files", },
2146 {"f_ffree", },
2147 {"f_favail", },
2148 {"f_flag", },
2149 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002150 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002151 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002152};
2153
2154static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002155 "statvfs_result", /* name */
2156 statvfs_result__doc__, /* doc */
2157 statvfs_result_fields,
2158 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002159};
2160
Ross Lagerwall7807c352011-03-17 20:20:30 +02002161#if defined(HAVE_WAITID) && !defined(__APPLE__)
2162PyDoc_STRVAR(waitid_result__doc__,
2163"waitid_result: Result from waitid.\n\n\
2164This object may be accessed either as a tuple of\n\
2165 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2166or via the attributes si_pid, si_uid, and so on.\n\
2167\n\
2168See os.waitid for more information.");
2169
2170static PyStructSequence_Field waitid_result_fields[] = {
2171 {"si_pid", },
2172 {"si_uid", },
2173 {"si_signo", },
2174 {"si_status", },
2175 {"si_code", },
2176 {0}
2177};
2178
2179static PyStructSequence_Desc waitid_result_desc = {
2180 "waitid_result", /* name */
2181 waitid_result__doc__, /* doc */
2182 waitid_result_fields,
2183 5
2184};
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002185#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002186static newfunc structseq_new;
2187
2188static PyObject *
2189statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2190{
Victor Stinner8c62be82010-05-06 00:08:46 +00002191 PyStructSequence *result;
2192 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002193
Victor Stinner8c62be82010-05-06 00:08:46 +00002194 result = (PyStructSequence*)structseq_new(type, args, kwds);
2195 if (!result)
2196 return NULL;
2197 /* If we have been initialized from a tuple,
2198 st_?time might be set to None. Initialize it
2199 from the int slots. */
2200 for (i = 7; i <= 9; i++) {
2201 if (result->ob_item[i+3] == Py_None) {
2202 Py_DECREF(Py_None);
2203 Py_INCREF(result->ob_item[i]);
2204 result->ob_item[i+3] = result->ob_item[i];
2205 }
2206 }
2207 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002208}
2209
Eddie Elizondob3966632019-11-05 07:16:14 -08002210static int
2211_posix_clear(PyObject *module)
2212{
Victor Stinner97f33c32020-05-14 18:05:58 +02002213 _posixstate *state = get_posix_state(module);
2214 Py_CLEAR(state->billion);
2215 Py_CLEAR(state->DirEntryType);
2216 Py_CLEAR(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002217#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002218 Py_CLEAR(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002219#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002220 Py_CLEAR(state->StatResultType);
2221 Py_CLEAR(state->StatVFSResultType);
2222 Py_CLEAR(state->TerminalSizeType);
2223 Py_CLEAR(state->TimesResultType);
2224 Py_CLEAR(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002225#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002226 Py_CLEAR(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002227#endif
2228#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002229 Py_CLEAR(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002230#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002231 Py_CLEAR(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002232 return 0;
2233}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002234
Eddie Elizondob3966632019-11-05 07:16:14 -08002235static int
2236_posix_traverse(PyObject *module, visitproc visit, void *arg)
2237{
Victor Stinner97f33c32020-05-14 18:05:58 +02002238 _posixstate *state = get_posix_state(module);
2239 Py_VISIT(state->billion);
2240 Py_VISIT(state->DirEntryType);
2241 Py_VISIT(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002242#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002243 Py_VISIT(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002244#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002245 Py_VISIT(state->StatResultType);
2246 Py_VISIT(state->StatVFSResultType);
2247 Py_VISIT(state->TerminalSizeType);
2248 Py_VISIT(state->TimesResultType);
2249 Py_VISIT(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002250#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002251 Py_VISIT(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002252#endif
2253#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002254 Py_VISIT(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002255#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002256 Py_VISIT(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002257 return 0;
2258}
2259
2260static void
2261_posix_free(void *module)
2262{
2263 _posix_clear((PyObject *)module);
2264}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002265
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002266static void
Victor Stinner1c2fa782020-05-10 11:05:29 +02002267fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002268{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002269 PyObject *s = _PyLong_FromTime_t(sec);
2270 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2271 PyObject *s_in_ns = NULL;
2272 PyObject *ns_total = NULL;
2273 PyObject *float_s = NULL;
2274
2275 if (!(s && ns_fractional))
2276 goto exit;
2277
Victor Stinner1c2fa782020-05-10 11:05:29 +02002278 s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002279 if (!s_in_ns)
2280 goto exit;
2281
2282 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2283 if (!ns_total)
2284 goto exit;
2285
Victor Stinner01b5aab2017-10-24 02:02:00 -07002286 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2287 if (!float_s) {
2288 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002289 }
2290
2291 PyStructSequence_SET_ITEM(v, index, s);
2292 PyStructSequence_SET_ITEM(v, index+3, float_s);
2293 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2294 s = NULL;
2295 float_s = NULL;
2296 ns_total = NULL;
2297exit:
2298 Py_XDECREF(s);
2299 Py_XDECREF(ns_fractional);
2300 Py_XDECREF(s_in_ns);
2301 Py_XDECREF(ns_total);
2302 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002303}
2304
Tim Peters5aa91602002-01-30 05:46:57 +00002305/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002306 (used by posix_stat() and posix_fstat()) */
2307static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +02002308_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002309{
Victor Stinner8c62be82010-05-06 00:08:46 +00002310 unsigned long ansec, mnsec, cnsec;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002311 PyObject *StatResultType = get_posix_state(module)->StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08002312 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002313 if (v == NULL)
2314 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002315
Victor Stinner8c62be82010-05-06 00:08:46 +00002316 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002317 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002318 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002319#ifdef MS_WINDOWS
2320 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002321#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002322 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002323#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002324 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002325#if defined(MS_WINDOWS)
2326 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2327 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2328#else
2329 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2330 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2331#endif
xdegaye50e86032017-05-22 11:15:08 +02002332 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2333 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002334
Martin v. Löwis14694662006-02-03 12:54:16 +00002335#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002336 ansec = st->st_atim.tv_nsec;
2337 mnsec = st->st_mtim.tv_nsec;
2338 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002339#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002340 ansec = st->st_atimespec.tv_nsec;
2341 mnsec = st->st_mtimespec.tv_nsec;
2342 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002343#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002344 ansec = st->st_atime_nsec;
2345 mnsec = st->st_mtime_nsec;
2346 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002347#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002348 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002349#endif
Victor Stinner1c2fa782020-05-10 11:05:29 +02002350 fill_time(module, v, 7, st->st_atime, ansec);
2351 fill_time(module, v, 8, st->st_mtime, mnsec);
2352 fill_time(module, v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002353
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002354#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002355 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2356 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002357#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002358#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002359 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2360 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002361#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002362#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002363 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2364 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002365#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002366#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002367 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2368 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002369#endif
2370#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002371 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002372 PyObject *val;
2373 unsigned long bsec,bnsec;
2374 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002375#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002376 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002377#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002378 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002379#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002380 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002381 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2382 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002383 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002384#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002385#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002386 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2387 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002388#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002389#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2390 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2391 PyLong_FromUnsignedLong(st->st_file_attributes));
2392#endif
jcea6c51d512018-01-28 14:00:08 +01002393#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2394 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2395 PyUnicode_FromString(st->st_fstype));
2396#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002397#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2398 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2399 PyLong_FromUnsignedLong(st->st_reparse_tag));
2400#endif
Fred Drake699f3522000-06-29 21:12:41 +00002401
Victor Stinner8c62be82010-05-06 00:08:46 +00002402 if (PyErr_Occurred()) {
2403 Py_DECREF(v);
2404 return NULL;
2405 }
Fred Drake699f3522000-06-29 21:12:41 +00002406
Victor Stinner8c62be82010-05-06 00:08:46 +00002407 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002408}
2409
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002410/* POSIX methods */
2411
Guido van Rossum94f6f721999-01-06 18:42:14 +00002412
2413static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02002414posix_do_stat(PyObject *module, const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002415 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002416{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002417 STRUCT_STAT st;
2418 int result;
2419
Ronald Oussorene8b1c032020-11-22 11:18:40 +01002420#ifdef HAVE_FSTATAT
2421 int fstatat_unavailable = 0;
2422#endif
2423
Larry Hastings9cf065c2012-06-22 16:30:09 -07002424#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2425 if (follow_symlinks_specified(function_name, follow_symlinks))
2426 return NULL;
2427#endif
2428
2429 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2430 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2431 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2432 return NULL;
2433
2434 Py_BEGIN_ALLOW_THREADS
2435 if (path->fd != -1)
2436 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002437#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002438 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002439 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002440 else
Steve Dowercc16be82016-09-08 10:35:16 -07002441 result = win32_lstat(path->wide, &st);
2442#else
2443 else
2444#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002445 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2446 result = LSTAT(path->narrow, &st);
2447 else
Steve Dowercc16be82016-09-08 10:35:16 -07002448#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002449#ifdef HAVE_FSTATAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +01002450 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2451 if (HAVE_FSTATAT_RUNTIME) {
2452 result = fstatat(dir_fd, path->narrow, &st,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002453 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussorene8b1c032020-11-22 11:18:40 +01002454
2455 } else {
2456 fstatat_unavailable = 1;
2457 }
2458 } else
Steve Dowercc16be82016-09-08 10:35:16 -07002459#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002460 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002461#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002462 Py_END_ALLOW_THREADS
2463
Ronald Oussorene8b1c032020-11-22 11:18:40 +01002464#ifdef HAVE_FSTATAT
2465 if (fstatat_unavailable) {
2466 argument_unavailable_error("stat", "dir_fd");
2467 return NULL;
2468 }
2469#endif
2470
Victor Stinner292c8352012-10-30 02:17:38 +01002471 if (result != 0) {
2472 return path_error(path);
2473 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002474
Victor Stinner1c2fa782020-05-10 11:05:29 +02002475 return _pystat_fromstructstat(module, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002476}
2477
Larry Hastings2f936352014-08-05 14:04:04 +10002478/*[python input]
2479
2480for s in """
2481
2482FACCESSAT
2483FCHMODAT
2484FCHOWNAT
2485FSTATAT
2486LINKAT
2487MKDIRAT
2488MKFIFOAT
2489MKNODAT
2490OPENAT
2491READLINKAT
2492SYMLINKAT
2493UNLINKAT
2494
2495""".strip().split():
2496 s = s.strip()
2497 print("""
2498#ifdef HAVE_{s}
2499 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002500#else
Larry Hastings2f936352014-08-05 14:04:04 +10002501 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002502#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002503""".rstrip().format(s=s))
2504
2505for s in """
2506
2507FCHDIR
2508FCHMOD
2509FCHOWN
2510FDOPENDIR
2511FEXECVE
2512FPATHCONF
2513FSTATVFS
2514FTRUNCATE
2515
2516""".strip().split():
2517 s = s.strip()
2518 print("""
2519#ifdef HAVE_{s}
2520 #define PATH_HAVE_{s} 1
2521#else
2522 #define PATH_HAVE_{s} 0
2523#endif
2524
2525""".rstrip().format(s=s))
2526[python start generated code]*/
2527
2528#ifdef HAVE_FACCESSAT
2529 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2530#else
2531 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2532#endif
2533
2534#ifdef HAVE_FCHMODAT
2535 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2536#else
2537 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2538#endif
2539
2540#ifdef HAVE_FCHOWNAT
2541 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2542#else
2543 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2544#endif
2545
2546#ifdef HAVE_FSTATAT
2547 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2548#else
2549 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2550#endif
2551
2552#ifdef HAVE_LINKAT
2553 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2554#else
2555 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2556#endif
2557
2558#ifdef HAVE_MKDIRAT
2559 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2560#else
2561 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2562#endif
2563
2564#ifdef HAVE_MKFIFOAT
2565 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2566#else
2567 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2568#endif
2569
2570#ifdef HAVE_MKNODAT
2571 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2572#else
2573 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2574#endif
2575
2576#ifdef HAVE_OPENAT
2577 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2578#else
2579 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2580#endif
2581
2582#ifdef HAVE_READLINKAT
2583 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2584#else
2585 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2586#endif
2587
2588#ifdef HAVE_SYMLINKAT
2589 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2590#else
2591 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2592#endif
2593
2594#ifdef HAVE_UNLINKAT
2595 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2596#else
2597 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2598#endif
2599
2600#ifdef HAVE_FCHDIR
2601 #define PATH_HAVE_FCHDIR 1
2602#else
2603 #define PATH_HAVE_FCHDIR 0
2604#endif
2605
2606#ifdef HAVE_FCHMOD
2607 #define PATH_HAVE_FCHMOD 1
2608#else
2609 #define PATH_HAVE_FCHMOD 0
2610#endif
2611
2612#ifdef HAVE_FCHOWN
2613 #define PATH_HAVE_FCHOWN 1
2614#else
2615 #define PATH_HAVE_FCHOWN 0
2616#endif
2617
2618#ifdef HAVE_FDOPENDIR
2619 #define PATH_HAVE_FDOPENDIR 1
2620#else
2621 #define PATH_HAVE_FDOPENDIR 0
2622#endif
2623
2624#ifdef HAVE_FEXECVE
2625 #define PATH_HAVE_FEXECVE 1
2626#else
2627 #define PATH_HAVE_FEXECVE 0
2628#endif
2629
2630#ifdef HAVE_FPATHCONF
2631 #define PATH_HAVE_FPATHCONF 1
2632#else
2633 #define PATH_HAVE_FPATHCONF 0
2634#endif
2635
2636#ifdef HAVE_FSTATVFS
2637 #define PATH_HAVE_FSTATVFS 1
2638#else
2639 #define PATH_HAVE_FSTATVFS 0
2640#endif
2641
2642#ifdef HAVE_FTRUNCATE
2643 #define PATH_HAVE_FTRUNCATE 1
2644#else
2645 #define PATH_HAVE_FTRUNCATE 0
2646#endif
2647/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002648
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002649#ifdef MS_WINDOWS
2650 #undef PATH_HAVE_FTRUNCATE
2651 #define PATH_HAVE_FTRUNCATE 1
2652#endif
Larry Hastings31826802013-10-19 00:09:25 -07002653
Larry Hastings61272b72014-01-07 12:41:53 -08002654/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002655
2656class path_t_converter(CConverter):
2657
2658 type = "path_t"
2659 impl_by_reference = True
2660 parse_by_reference = True
2661
2662 converter = 'path_converter'
2663
2664 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002665 # right now path_t doesn't support default values.
2666 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002667 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002668 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002669
Larry Hastings2f936352014-08-05 14:04:04 +10002670 if self.c_default not in (None, 'Py_None'):
2671 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002672
2673 self.nullable = nullable
2674 self.allow_fd = allow_fd
2675
Larry Hastings7726ac92014-01-31 22:03:12 -08002676 def pre_render(self):
2677 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002678 if isinstance(value, str):
2679 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002680 return str(int(bool(value)))
2681
2682 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002683 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002684 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002685 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002686 strify(self.nullable),
2687 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002688 )
2689
2690 def cleanup(self):
2691 return "path_cleanup(&" + self.name + ");\n"
2692
2693
2694class dir_fd_converter(CConverter):
2695 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002696
Larry Hastings2f936352014-08-05 14:04:04 +10002697 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002698 if self.default in (unspecified, None):
2699 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002700 if isinstance(requires, str):
2701 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2702 else:
2703 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002704
Larry Hastings2f936352014-08-05 14:04:04 +10002705class fildes_converter(CConverter):
2706 type = 'int'
2707 converter = 'fildes_converter'
2708
2709class uid_t_converter(CConverter):
2710 type = "uid_t"
2711 converter = '_Py_Uid_Converter'
2712
2713class gid_t_converter(CConverter):
2714 type = "gid_t"
2715 converter = '_Py_Gid_Converter'
2716
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002717class dev_t_converter(CConverter):
2718 type = 'dev_t'
2719 converter = '_Py_Dev_Converter'
2720
2721class dev_t_return_converter(unsigned_long_return_converter):
2722 type = 'dev_t'
2723 conversion_fn = '_PyLong_FromDev'
2724 unsigned_cast = '(dev_t)'
2725
Larry Hastings2f936352014-08-05 14:04:04 +10002726class FSConverter_converter(CConverter):
2727 type = 'PyObject *'
2728 converter = 'PyUnicode_FSConverter'
2729 def converter_init(self):
2730 if self.default is not unspecified:
2731 fail("FSConverter_converter does not support default values")
2732 self.c_default = 'NULL'
2733
2734 def cleanup(self):
2735 return "Py_XDECREF(" + self.name + ");\n"
2736
2737class pid_t_converter(CConverter):
2738 type = 'pid_t'
2739 format_unit = '" _Py_PARSE_PID "'
2740
2741class idtype_t_converter(int_converter):
2742 type = 'idtype_t'
2743
2744class id_t_converter(CConverter):
2745 type = 'id_t'
2746 format_unit = '" _Py_PARSE_PID "'
2747
Benjamin Petersonca470632016-09-06 13:47:26 -07002748class intptr_t_converter(CConverter):
2749 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002750 format_unit = '" _Py_PARSE_INTPTR "'
2751
2752class Py_off_t_converter(CConverter):
2753 type = 'Py_off_t'
2754 converter = 'Py_off_t_converter'
2755
2756class Py_off_t_return_converter(long_return_converter):
2757 type = 'Py_off_t'
2758 conversion_fn = 'PyLong_FromPy_off_t'
2759
2760class path_confname_converter(CConverter):
2761 type="int"
2762 converter="conv_path_confname"
2763
2764class confstr_confname_converter(path_confname_converter):
2765 converter='conv_confstr_confname'
2766
2767class sysconf_confname_converter(path_confname_converter):
2768 converter="conv_sysconf_confname"
2769
Larry Hastings61272b72014-01-07 12:41:53 -08002770[python start generated code]*/
Victor Stinner1c2fa782020-05-10 11:05:29 +02002771/*[python end generated code: output=da39a3ee5e6b4b0d input=f1c8ae8d744f6c8b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002772
Larry Hastings61272b72014-01-07 12:41:53 -08002773/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002774
Larry Hastings2a727912014-01-16 11:32:01 -08002775os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002776
2777 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002778 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002779 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002780
2781 *
2782
Larry Hastings2f936352014-08-05 14:04:04 +10002783 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002784 If not None, it should be a file descriptor open to a directory,
2785 and path should be a relative string; path will then be relative to
2786 that directory.
2787
2788 follow_symlinks: bool = True
2789 If False, and the last element of the path is a symbolic link,
2790 stat will examine the symbolic link itself instead of the file
2791 the link points to.
2792
2793Perform a stat system call on the given path.
2794
2795dir_fd and follow_symlinks may not be implemented
2796 on your platform. If they are unavailable, using them will raise a
2797 NotImplementedError.
2798
2799It's an error to use dir_fd or follow_symlinks when specifying path as
2800 an open file descriptor.
2801
Larry Hastings61272b72014-01-07 12:41:53 -08002802[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002803
Larry Hastings31826802013-10-19 00:09:25 -07002804static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002805os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002806/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002807{
Victor Stinner1c2fa782020-05-10 11:05:29 +02002808 return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002809}
2810
Larry Hastings2f936352014-08-05 14:04:04 +10002811
2812/*[clinic input]
2813os.lstat
2814
2815 path : path_t
2816
2817 *
2818
2819 dir_fd : dir_fd(requires='fstatat') = None
2820
2821Perform a stat system call on the given path, without following symbolic links.
2822
2823Like stat(), but do not follow symbolic links.
2824Equivalent to stat(path, follow_symlinks=False).
2825[clinic start generated code]*/
2826
Larry Hastings2f936352014-08-05 14:04:04 +10002827static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002828os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2829/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002830{
2831 int follow_symlinks = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002832 return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10002833}
Larry Hastings31826802013-10-19 00:09:25 -07002834
Larry Hastings2f936352014-08-05 14:04:04 +10002835
Larry Hastings61272b72014-01-07 12:41:53 -08002836/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002837os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002838
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002839 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002840 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002841
2842 mode: int
2843 Operating-system mode bitfield. Can be F_OK to test existence,
2844 or the inclusive-OR of R_OK, W_OK, and X_OK.
2845
2846 *
2847
Larry Hastings2f936352014-08-05 14:04:04 +10002848 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002849 If not None, it should be a file descriptor open to a directory,
2850 and path should be relative; path will then be relative to that
2851 directory.
2852
2853 effective_ids: bool = False
2854 If True, access will use the effective uid/gid instead of
2855 the real uid/gid.
2856
2857 follow_symlinks: bool = True
2858 If False, and the last element of the path is a symbolic link,
2859 access will examine the symbolic link itself instead of the file
2860 the link points to.
2861
2862Use the real uid/gid to test for access to a path.
2863
2864{parameters}
2865dir_fd, effective_ids, and follow_symlinks may not be implemented
2866 on your platform. If they are unavailable, using them will raise a
2867 NotImplementedError.
2868
2869Note that most operations will use the effective uid/gid, therefore this
2870 routine can be used in a suid/sgid environment to test if the invoking user
2871 has the specified access to the path.
2872
Larry Hastings61272b72014-01-07 12:41:53 -08002873[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002874
Larry Hastings2f936352014-08-05 14:04:04 +10002875static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002876os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002877 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002878/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002879{
Larry Hastings2f936352014-08-05 14:04:04 +10002880 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002881
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002882#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002883 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002884#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002885 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002886#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002887
Ronald Oussorene8b1c032020-11-22 11:18:40 +01002888#ifdef HAVE_FACCESSAT
2889 int faccessat_unavailable = 0;
2890#endif
2891
Larry Hastings9cf065c2012-06-22 16:30:09 -07002892#ifndef HAVE_FACCESSAT
2893 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002894 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002895
2896 if (effective_ids) {
2897 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002898 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002899 }
2900#endif
2901
2902#ifdef MS_WINDOWS
2903 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002904 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002905 Py_END_ALLOW_THREADS
2906
2907 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002908 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002909 * * we didn't get a -1, and
2910 * * write access wasn't requested,
2911 * * or the file isn't read-only,
2912 * * or it's a directory.
2913 * (Directories cannot be read-only on Windows.)
2914 */
Larry Hastings2f936352014-08-05 14:04:04 +10002915 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002916 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002917 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002918 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002919#else
2920
2921 Py_BEGIN_ALLOW_THREADS
2922#ifdef HAVE_FACCESSAT
2923 if ((dir_fd != DEFAULT_DIR_FD) ||
2924 effective_ids ||
2925 !follow_symlinks) {
Ronald Oussorene8b1c032020-11-22 11:18:40 +01002926
2927 if (HAVE_FACCESSAT_RUNTIME) {
2928 int flags = 0;
2929 if (!follow_symlinks)
2930 flags |= AT_SYMLINK_NOFOLLOW;
2931 if (effective_ids)
2932 flags |= AT_EACCESS;
2933 result = faccessat(dir_fd, path->narrow, mode, flags);
2934 } else {
2935 faccessat_unavailable = 1;
2936 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002937 }
2938 else
2939#endif
Larry Hastings31826802013-10-19 00:09:25 -07002940 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002941 Py_END_ALLOW_THREADS
Ronald Oussorene8b1c032020-11-22 11:18:40 +01002942
2943#ifdef HAVE_FACCESSAT
2944 if (faccessat_unavailable) {
2945 if (dir_fd != DEFAULT_DIR_FD) {
2946 argument_unavailable_error("access", "dir_fd");
2947 return -1;
2948 }
2949 if (follow_symlinks_specified("access", follow_symlinks))
2950 return -1;
2951
2952 if (effective_ids) {
2953 argument_unavailable_error("access", "effective_ids");
2954 return -1;
2955 }
2956 /* should be unreachable */
2957 return -1;
2958 }
2959#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002960 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002961#endif
2962
Larry Hastings9cf065c2012-06-22 16:30:09 -07002963 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002964}
2965
Guido van Rossumd371ff11999-01-25 16:12:23 +00002966#ifndef F_OK
2967#define F_OK 0
2968#endif
2969#ifndef R_OK
2970#define R_OK 4
2971#endif
2972#ifndef W_OK
2973#define W_OK 2
2974#endif
2975#ifndef X_OK
2976#define X_OK 1
2977#endif
2978
Larry Hastings31826802013-10-19 00:09:25 -07002979
Guido van Rossumd371ff11999-01-25 16:12:23 +00002980#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002981/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002982os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002983
2984 fd: int
2985 Integer file descriptor handle.
2986
2987 /
2988
2989Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002990[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002991
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002992static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002993os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002994/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002995{
Guido van Rossum94f6f721999-01-06 18:42:14 +00002996
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002997 long size = sysconf(_SC_TTY_NAME_MAX);
2998 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002999 return posix_error();
3000 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02003001 char *buffer = (char *)PyMem_RawMalloc(size);
3002 if (buffer == NULL) {
3003 return PyErr_NoMemory();
3004 }
3005 int ret = ttyname_r(fd, buffer, size);
3006 if (ret != 0) {
3007 PyMem_RawFree(buffer);
3008 errno = ret;
3009 return posix_error();
3010 }
3011 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
3012 PyMem_RawFree(buffer);
3013 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003014}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003015#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003016
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003017#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10003018/*[clinic input]
3019os.ctermid
3020
3021Return the name of the controlling terminal for this process.
3022[clinic start generated code]*/
3023
Larry Hastings2f936352014-08-05 14:04:04 +10003024static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003025os_ctermid_impl(PyObject *module)
3026/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003027{
Victor Stinner8c62be82010-05-06 00:08:46 +00003028 char *ret;
3029 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003030
Greg Wardb48bc172000-03-01 21:51:56 +00003031#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00003032 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003033#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003034 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003035#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003036 if (ret == NULL)
3037 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00003038 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003039}
Larry Hastings2f936352014-08-05 14:04:04 +10003040#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003041
Larry Hastings2f936352014-08-05 14:04:04 +10003042
3043/*[clinic input]
3044os.chdir
3045
3046 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
3047
3048Change the current working directory to the specified path.
3049
3050path may always be specified as a string.
3051On some platforms, path may also be specified as an open file descriptor.
3052 If this functionality is unavailable, using it raises an exception.
3053[clinic start generated code]*/
3054
Larry Hastings2f936352014-08-05 14:04:04 +10003055static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003056os_chdir_impl(PyObject *module, path_t *path)
3057/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003058{
3059 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003060
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003061 if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
3062 return NULL;
3063 }
3064
Larry Hastings9cf065c2012-06-22 16:30:09 -07003065 Py_BEGIN_ALLOW_THREADS
3066#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003067 /* on unix, success = 0, on windows, success = !0 */
3068 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003069#else
3070#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10003071 if (path->fd != -1)
3072 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003073 else
3074#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003075 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003076#endif
3077 Py_END_ALLOW_THREADS
3078
3079 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003080 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003081 }
3082
Larry Hastings2f936352014-08-05 14:04:04 +10003083 Py_RETURN_NONE;
3084}
3085
3086
3087#ifdef HAVE_FCHDIR
3088/*[clinic input]
3089os.fchdir
3090
3091 fd: fildes
3092
3093Change to the directory of the given file descriptor.
3094
3095fd must be opened on a directory, not a file.
3096Equivalent to os.chdir(fd).
3097
3098[clinic start generated code]*/
3099
Fred Drake4d1e64b2002-04-15 19:40:07 +00003100static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003101os_fchdir_impl(PyObject *module, int fd)
3102/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00003103{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003104 if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
3105 return NULL;
3106 }
Larry Hastings2f936352014-08-05 14:04:04 +10003107 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00003108}
3109#endif /* HAVE_FCHDIR */
3110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003111
Larry Hastings2f936352014-08-05 14:04:04 +10003112/*[clinic input]
3113os.chmod
3114
3115 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00003116 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10003117 On some platforms, path may also be specified as an open file descriptor.
3118 If this functionality is unavailable, using it raises an exception.
3119
3120 mode: int
3121 Operating-system mode bitfield.
3122
3123 *
3124
3125 dir_fd : dir_fd(requires='fchmodat') = None
3126 If not None, it should be a file descriptor open to a directory,
3127 and path should be relative; path will then be relative to that
3128 directory.
3129
3130 follow_symlinks: bool = True
3131 If False, and the last element of the path is a symbolic link,
3132 chmod will modify the symbolic link itself instead of the file
3133 the link points to.
3134
3135Change the access permissions of a file.
3136
3137It is an error to use dir_fd or follow_symlinks when specifying path as
3138 an open file descriptor.
3139dir_fd and follow_symlinks may not be implemented on your platform.
3140 If they are unavailable, using them will raise a NotImplementedError.
3141
3142[clinic start generated code]*/
3143
Larry Hastings2f936352014-08-05 14:04:04 +10003144static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003145os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003146 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003147/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003148{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003149 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003150
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003151#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003152 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003153#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003154
Larry Hastings9cf065c2012-06-22 16:30:09 -07003155#ifdef HAVE_FCHMODAT
3156 int fchmodat_nofollow_unsupported = 0;
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003157 int fchmodat_unsupported = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003158#endif
3159
Larry Hastings9cf065c2012-06-22 16:30:09 -07003160#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3161 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003162 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003163#endif
3164
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003165 if (PySys_Audit("os.chmod", "Oii", path->object, mode,
3166 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3167 return NULL;
3168 }
3169
Larry Hastings9cf065c2012-06-22 16:30:09 -07003170#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003172 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003173 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174 result = 0;
3175 else {
3176 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003177 attr &= ~FILE_ATTRIBUTE_READONLY;
3178 else
3179 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003180 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003181 }
3182 Py_END_ALLOW_THREADS
3183
3184 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003185 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003186 }
3187#else /* MS_WINDOWS */
3188 Py_BEGIN_ALLOW_THREADS
3189#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003190 if (path->fd != -1)
3191 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192 else
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003193#endif /* HAVE_CHMOD */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194#ifdef HAVE_LCHMOD
3195 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003196 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003197 else
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003198#endif /* HAVE_LCHMOD */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003199#ifdef HAVE_FCHMODAT
3200 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003201 if (HAVE_FCHMODAT_RUNTIME) {
3202 /*
3203 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3204 * The documentation specifically shows how to use it,
3205 * and then says it isn't implemented yet.
3206 * (true on linux with glibc 2.15, and openindiana 3.x)
3207 *
3208 * Once it is supported, os.chmod will automatically
3209 * support dir_fd and follow_symlinks=False. (Hopefully.)
3210 * Until then, we need to be careful what exception we raise.
3211 */
3212 result = fchmodat(dir_fd, path->narrow, mode,
3213 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3214 /*
3215 * But wait! We can't throw the exception without allowing threads,
3216 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3217 */
3218 fchmodat_nofollow_unsupported =
3219 result &&
3220 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3221 !follow_symlinks;
3222 } else {
3223 fchmodat_unsupported = 1;
3224 fchmodat_nofollow_unsupported = 1;
3225
3226 result = -1;
3227 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003228 }
3229 else
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003230#endif /* HAVE_FHCMODAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003231 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003232 Py_END_ALLOW_THREADS
3233
3234 if (result) {
3235#ifdef HAVE_FCHMODAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003236 if (fchmodat_unsupported) {
3237 if (dir_fd != DEFAULT_DIR_FD) {
3238 argument_unavailable_error("chmod", "dir_fd");
3239 return NULL;
3240 }
3241 }
3242
Larry Hastings9cf065c2012-06-22 16:30:09 -07003243 if (fchmodat_nofollow_unsupported) {
3244 if (dir_fd != DEFAULT_DIR_FD)
3245 dir_fd_and_follow_symlinks_invalid("chmod",
3246 dir_fd, follow_symlinks);
3247 else
3248 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003249 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250 }
3251 else
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003252#endif /* HAVE_FCHMODAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003253 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003254 }
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003255#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256
Larry Hastings2f936352014-08-05 14:04:04 +10003257 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003258}
3259
Larry Hastings9cf065c2012-06-22 16:30:09 -07003260
Christian Heimes4e30a842007-11-30 22:12:06 +00003261#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003262/*[clinic input]
3263os.fchmod
3264
3265 fd: int
3266 mode: int
3267
3268Change the access permissions of the file given by file descriptor fd.
3269
3270Equivalent to os.chmod(fd, mode).
3271[clinic start generated code]*/
3272
Larry Hastings2f936352014-08-05 14:04:04 +10003273static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003274os_fchmod_impl(PyObject *module, int fd, int mode)
3275/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003276{
3277 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003278 int async_err = 0;
3279
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003280 if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
3281 return NULL;
3282 }
3283
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003284 do {
3285 Py_BEGIN_ALLOW_THREADS
3286 res = fchmod(fd, mode);
3287 Py_END_ALLOW_THREADS
3288 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3289 if (res != 0)
3290 return (!async_err) ? posix_error() : NULL;
3291
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003293}
3294#endif /* HAVE_FCHMOD */
3295
Larry Hastings2f936352014-08-05 14:04:04 +10003296
Christian Heimes4e30a842007-11-30 22:12:06 +00003297#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003298/*[clinic input]
3299os.lchmod
3300
3301 path: path_t
3302 mode: int
3303
3304Change the access permissions of a file, without following symbolic links.
3305
3306If path is a symlink, this affects the link itself rather than the target.
3307Equivalent to chmod(path, mode, follow_symlinks=False)."
3308[clinic start generated code]*/
3309
Larry Hastings2f936352014-08-05 14:04:04 +10003310static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003311os_lchmod_impl(PyObject *module, path_t *path, int mode)
3312/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003313{
Victor Stinner8c62be82010-05-06 00:08:46 +00003314 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003315 if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3316 return NULL;
3317 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003318 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003319 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003320 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003321 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003322 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003323 return NULL;
3324 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003325 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003326}
3327#endif /* HAVE_LCHMOD */
3328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003329
Thomas Wouterscf297e42007-02-23 15:07:44 +00003330#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003331/*[clinic input]
3332os.chflags
3333
3334 path: path_t
3335 flags: unsigned_long(bitwise=True)
3336 follow_symlinks: bool=True
3337
3338Set file flags.
3339
3340If follow_symlinks is False, and the last element of the path is a symbolic
3341 link, chflags will change flags on the symbolic link itself instead of the
3342 file the link points to.
3343follow_symlinks may not be implemented on your platform. If it is
3344unavailable, using it will raise a NotImplementedError.
3345
3346[clinic start generated code]*/
3347
Larry Hastings2f936352014-08-05 14:04:04 +10003348static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003349os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003350 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003351/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003352{
3353 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003354
3355#ifndef HAVE_LCHFLAGS
3356 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003357 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003358#endif
3359
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003360 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3361 return NULL;
3362 }
3363
Victor Stinner8c62be82010-05-06 00:08:46 +00003364 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003365#ifdef HAVE_LCHFLAGS
3366 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003367 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368 else
3369#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003370 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003371 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003372
Larry Hastings2f936352014-08-05 14:04:04 +10003373 if (result)
3374 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003375
Larry Hastings2f936352014-08-05 14:04:04 +10003376 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003377}
3378#endif /* HAVE_CHFLAGS */
3379
Larry Hastings2f936352014-08-05 14:04:04 +10003380
Thomas Wouterscf297e42007-02-23 15:07:44 +00003381#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003382/*[clinic input]
3383os.lchflags
3384
3385 path: path_t
3386 flags: unsigned_long(bitwise=True)
3387
3388Set file flags.
3389
3390This function will not follow symbolic links.
3391Equivalent to chflags(path, flags, follow_symlinks=False).
3392[clinic start generated code]*/
3393
Larry Hastings2f936352014-08-05 14:04:04 +10003394static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003395os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3396/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003397{
Victor Stinner8c62be82010-05-06 00:08:46 +00003398 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003399 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3400 return NULL;
3401 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003402 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003403 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003404 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003405 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003406 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003407 }
Victor Stinner292c8352012-10-30 02:17:38 +01003408 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003409}
3410#endif /* HAVE_LCHFLAGS */
3411
Larry Hastings2f936352014-08-05 14:04:04 +10003412
Martin v. Löwis244edc82001-10-04 22:44:26 +00003413#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003414/*[clinic input]
3415os.chroot
3416 path: path_t
3417
3418Change root directory to path.
3419
3420[clinic start generated code]*/
3421
Larry Hastings2f936352014-08-05 14:04:04 +10003422static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003423os_chroot_impl(PyObject *module, path_t *path)
3424/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003425{
3426 int res;
3427 Py_BEGIN_ALLOW_THREADS
3428 res = chroot(path->narrow);
3429 Py_END_ALLOW_THREADS
3430 if (res < 0)
3431 return path_error(path);
3432 Py_RETURN_NONE;
3433}
3434#endif /* HAVE_CHROOT */
3435
Martin v. Löwis244edc82001-10-04 22:44:26 +00003436
Guido van Rossum21142a01999-01-08 21:05:37 +00003437#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003438/*[clinic input]
3439os.fsync
3440
3441 fd: fildes
3442
3443Force write of fd to disk.
3444[clinic start generated code]*/
3445
Larry Hastings2f936352014-08-05 14:04:04 +10003446static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003447os_fsync_impl(PyObject *module, int fd)
3448/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003449{
3450 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003451}
3452#endif /* HAVE_FSYNC */
3453
Larry Hastings2f936352014-08-05 14:04:04 +10003454
Ross Lagerwall7807c352011-03-17 20:20:30 +02003455#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003456/*[clinic input]
3457os.sync
3458
3459Force write of everything to disk.
3460[clinic start generated code]*/
3461
Larry Hastings2f936352014-08-05 14:04:04 +10003462static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003463os_sync_impl(PyObject *module)
3464/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003465{
3466 Py_BEGIN_ALLOW_THREADS
3467 sync();
3468 Py_END_ALLOW_THREADS
3469 Py_RETURN_NONE;
3470}
Larry Hastings2f936352014-08-05 14:04:04 +10003471#endif /* HAVE_SYNC */
3472
Ross Lagerwall7807c352011-03-17 20:20:30 +02003473
Guido van Rossum21142a01999-01-08 21:05:37 +00003474#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003475#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003476extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3477#endif
3478
Larry Hastings2f936352014-08-05 14:04:04 +10003479/*[clinic input]
3480os.fdatasync
3481
3482 fd: fildes
3483
3484Force write of fd to disk without forcing update of metadata.
3485[clinic start generated code]*/
3486
Larry Hastings2f936352014-08-05 14:04:04 +10003487static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003488os_fdatasync_impl(PyObject *module, int fd)
3489/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003490{
3491 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003492}
3493#endif /* HAVE_FDATASYNC */
3494
3495
Fredrik Lundh10723342000-07-10 16:38:09 +00003496#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003497/*[clinic input]
3498os.chown
3499
3500 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003501 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003502
3503 uid: uid_t
3504
3505 gid: gid_t
3506
3507 *
3508
3509 dir_fd : dir_fd(requires='fchownat') = None
3510 If not None, it should be a file descriptor open to a directory,
3511 and path should be relative; path will then be relative to that
3512 directory.
3513
3514 follow_symlinks: bool = True
3515 If False, and the last element of the path is a symbolic link,
3516 stat will examine the symbolic link itself instead of the file
3517 the link points to.
3518
3519Change the owner and group id of path to the numeric uid and gid.\
3520
3521path may always be specified as a string.
3522On some platforms, path may also be specified as an open file descriptor.
3523 If this functionality is unavailable, using it raises an exception.
3524If dir_fd is not None, it should be a file descriptor open to a directory,
3525 and path should be relative; path will then be relative to that directory.
3526If follow_symlinks is False, and the last element of the path is a symbolic
3527 link, chown will modify the symbolic link itself instead of the file the
3528 link points to.
3529It is an error to use dir_fd or follow_symlinks when specifying path as
3530 an open file descriptor.
3531dir_fd and follow_symlinks may not be implemented on your platform.
3532 If they are unavailable, using them will raise a NotImplementedError.
3533
3534[clinic start generated code]*/
3535
Larry Hastings2f936352014-08-05 14:04:04 +10003536static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003537os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003538 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003539/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003540{
3541 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003542
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003543#if defined(HAVE_FCHOWNAT)
3544 int fchownat_unsupported = 0;
3545#endif
3546
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3548 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003549 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003551 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3552 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3553 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003555 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
3556 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3557 return NULL;
3558 }
3559
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003562 if (path->fd != -1)
3563 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564 else
3565#endif
3566#ifdef HAVE_LCHOWN
3567 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003568 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003569 else
3570#endif
3571#ifdef HAVE_FCHOWNAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003572 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
3573 if (HAVE_FCHOWNAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10003574 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003576 } else {
3577 fchownat_unsupported = 1;
3578 }
3579 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003581 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003582 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003583
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003584#ifdef HAVE_FCHOWNAT
3585 if (fchownat_unsupported) {
3586 /* This would be incorrect if the current platform
3587 * doesn't support lchown.
3588 */
3589 argument_unavailable_error(NULL, "dir_fd");
3590 return NULL;
3591 }
3592#endif
3593
Larry Hastings2f936352014-08-05 14:04:04 +10003594 if (result)
3595 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003596
Larry Hastings2f936352014-08-05 14:04:04 +10003597 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003598}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003599#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003600
Larry Hastings2f936352014-08-05 14:04:04 +10003601
Christian Heimes4e30a842007-11-30 22:12:06 +00003602#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003603/*[clinic input]
3604os.fchown
3605
3606 fd: int
3607 uid: uid_t
3608 gid: gid_t
3609
3610Change the owner and group id of the file specified by file descriptor.
3611
3612Equivalent to os.chown(fd, uid, gid).
3613
3614[clinic start generated code]*/
3615
Larry Hastings2f936352014-08-05 14:04:04 +10003616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003617os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3618/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003619{
Victor Stinner8c62be82010-05-06 00:08:46 +00003620 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003621 int async_err = 0;
3622
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003623 if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
3624 return NULL;
3625 }
3626
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003627 do {
3628 Py_BEGIN_ALLOW_THREADS
3629 res = fchown(fd, uid, gid);
3630 Py_END_ALLOW_THREADS
3631 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3632 if (res != 0)
3633 return (!async_err) ? posix_error() : NULL;
3634
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003636}
3637#endif /* HAVE_FCHOWN */
3638
Larry Hastings2f936352014-08-05 14:04:04 +10003639
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003640#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003641/*[clinic input]
3642os.lchown
3643
3644 path : path_t
3645 uid: uid_t
3646 gid: gid_t
3647
3648Change the owner and group id of path to the numeric uid and gid.
3649
3650This function will not follow symbolic links.
3651Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3652[clinic start generated code]*/
3653
Larry Hastings2f936352014-08-05 14:04:04 +10003654static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003655os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3656/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003657{
Victor Stinner8c62be82010-05-06 00:08:46 +00003658 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003659 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
3660 return NULL;
3661 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003662 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003663 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003664 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003665 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003666 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003667 }
Larry Hastings2f936352014-08-05 14:04:04 +10003668 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003669}
3670#endif /* HAVE_LCHOWN */
3671
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003672
Barry Warsaw53699e91996-12-10 23:23:01 +00003673static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003674posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003675{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003676#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003677 wchar_t wbuf[MAXPATHLEN];
3678 wchar_t *wbuf2 = wbuf;
3679 DWORD len;
3680
3681 Py_BEGIN_ALLOW_THREADS
3682 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3683 /* If the buffer is large enough, len does not include the
3684 terminating \0. If the buffer is too small, len includes
3685 the space needed for the terminator. */
3686 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003687 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003688 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003689 }
Victor Stinner689830e2019-06-26 17:31:12 +02003690 else {
3691 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003692 }
Victor Stinner689830e2019-06-26 17:31:12 +02003693 if (wbuf2) {
3694 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 }
Victor Stinner689830e2019-06-26 17:31:12 +02003696 }
3697 Py_END_ALLOW_THREADS
3698
3699 if (!wbuf2) {
3700 PyErr_NoMemory();
3701 return NULL;
3702 }
3703 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003704 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003705 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003706 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003707 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003708
Victor Stinner689830e2019-06-26 17:31:12 +02003709 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3710 if (wbuf2 != wbuf) {
3711 PyMem_RawFree(wbuf2);
3712 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003713
Victor Stinner689830e2019-06-26 17:31:12 +02003714 if (use_bytes) {
3715 if (resobj == NULL) {
3716 return NULL;
3717 }
3718 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3719 }
3720
3721 return resobj;
3722#else
3723 const size_t chunk = 1024;
3724
3725 char *buf = NULL;
3726 char *cwd = NULL;
3727 size_t buflen = 0;
3728
Victor Stinner8c62be82010-05-06 00:08:46 +00003729 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003730 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003731 char *newbuf;
3732 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3733 buflen += chunk;
3734 newbuf = PyMem_RawRealloc(buf, buflen);
3735 }
3736 else {
3737 newbuf = NULL;
3738 }
3739 if (newbuf == NULL) {
3740 PyMem_RawFree(buf);
3741 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003742 break;
3743 }
Victor Stinner689830e2019-06-26 17:31:12 +02003744 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003745
Victor Stinner4403d7d2015-04-25 00:16:10 +02003746 cwd = getcwd(buf, buflen);
3747 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003748 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003749
Victor Stinner689830e2019-06-26 17:31:12 +02003750 if (buf == NULL) {
3751 return PyErr_NoMemory();
3752 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003753 if (cwd == NULL) {
3754 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003755 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003756 }
3757
Victor Stinner689830e2019-06-26 17:31:12 +02003758 PyObject *obj;
3759 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003760 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003761 }
3762 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003763 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003764 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003765 PyMem_RawFree(buf);
3766
3767 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003768#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003769}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003770
Larry Hastings2f936352014-08-05 14:04:04 +10003771
3772/*[clinic input]
3773os.getcwd
3774
3775Return a unicode string representing the current working directory.
3776[clinic start generated code]*/
3777
Larry Hastings2f936352014-08-05 14:04:04 +10003778static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003779os_getcwd_impl(PyObject *module)
3780/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003781{
3782 return posix_getcwd(0);
3783}
3784
Larry Hastings2f936352014-08-05 14:04:04 +10003785
3786/*[clinic input]
3787os.getcwdb
3788
3789Return a bytes string representing the current working directory.
3790[clinic start generated code]*/
3791
Larry Hastings2f936352014-08-05 14:04:04 +10003792static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003793os_getcwdb_impl(PyObject *module)
3794/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003795{
3796 return posix_getcwd(1);
3797}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003798
Larry Hastings2f936352014-08-05 14:04:04 +10003799
Larry Hastings9cf065c2012-06-22 16:30:09 -07003800#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3801#define HAVE_LINK 1
3802#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003803
Guido van Rossumb6775db1994-08-01 11:34:53 +00003804#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003805/*[clinic input]
3806
3807os.link
3808
3809 src : path_t
3810 dst : path_t
3811 *
3812 src_dir_fd : dir_fd = None
3813 dst_dir_fd : dir_fd = None
3814 follow_symlinks: bool = True
3815
3816Create a hard link to a file.
3817
3818If either src_dir_fd or dst_dir_fd is not None, it should be a file
3819 descriptor open to a directory, and the respective path string (src or dst)
3820 should be relative; the path will then be relative to that directory.
3821If follow_symlinks is False, and the last element of src is a symbolic
3822 link, link will create a link to the symbolic link itself instead of the
3823 file the link points to.
3824src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3825 platform. If they are unavailable, using them will raise a
3826 NotImplementedError.
3827[clinic start generated code]*/
3828
Larry Hastings2f936352014-08-05 14:04:04 +10003829static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003830os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003831 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003832/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003833{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003834#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003835 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003836#else
3837 int result;
3838#endif
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003839#if defined(HAVE_LINKAT)
3840 int linkat_unavailable = 0;
3841#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003842
Larry Hastings9cf065c2012-06-22 16:30:09 -07003843#ifndef HAVE_LINKAT
3844 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3845 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003846 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003847 }
3848#endif
3849
Steve Dowercc16be82016-09-08 10:35:16 -07003850#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003851 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003852 PyErr_SetString(PyExc_NotImplementedError,
3853 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003854 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003855 }
Steve Dowercc16be82016-09-08 10:35:16 -07003856#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003857
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003858 if (PySys_Audit("os.link", "OOii", src->object, dst->object,
3859 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
3860 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
3861 return NULL;
3862 }
3863
Brian Curtin1b9df392010-11-24 20:24:31 +00003864#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003865 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003866 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003867 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003868
Larry Hastings2f936352014-08-05 14:04:04 +10003869 if (!result)
3870 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003871#else
3872 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003873#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003874 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3875 (dst_dir_fd != DEFAULT_DIR_FD) ||
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003876 (!follow_symlinks)) {
3877
3878 if (HAVE_LINKAT_RUNTIME) {
3879
3880 result = linkat(src_dir_fd, src->narrow,
3881 dst_dir_fd, dst->narrow,
3882 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3883
3884 }
3885#ifdef __APPLE__
3886 else {
3887 if (src_dir_fd == DEFAULT_DIR_FD && dst_dir_fd == DEFAULT_DIR_FD) {
3888 /* See issue 41355: This matches the behaviour of !HAVE_LINKAT */
3889 result = link(src->narrow, dst->narrow);
3890 } else {
3891 linkat_unavailable = 1;
3892 }
3893 }
3894#endif
3895 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003896 else
Steve Dowercc16be82016-09-08 10:35:16 -07003897#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003898 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003899 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003900
Ronald Oussorene8b1c032020-11-22 11:18:40 +01003901#ifdef HAVE_LINKAT
3902 if (linkat_unavailable) {
3903 /* Either or both dir_fd arguments were specified */
3904 if (src_dir_fd != DEFAULT_DIR_FD) {
3905 argument_unavailable_error("link", "src_dir_fd");
3906 } else {
3907 argument_unavailable_error("link", "dst_dir_fd");
3908 }
3909 return NULL;
3910 }
3911#endif
3912
Larry Hastings2f936352014-08-05 14:04:04 +10003913 if (result)
3914 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003915#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003916
Larry Hastings2f936352014-08-05 14:04:04 +10003917 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003918}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003919#endif
3920
Brian Curtin1b9df392010-11-24 20:24:31 +00003921
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003922#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003923static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003924_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003925{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003926 PyObject *v;
3927 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3928 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003929 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003930 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003931 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003932 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003933
Steve Dowercc16be82016-09-08 10:35:16 -07003934 WIN32_FIND_DATAW wFileData;
3935 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003936
Steve Dowercc16be82016-09-08 10:35:16 -07003937 if (!path->wide) { /* Default arg: "." */
3938 po_wchars = L".";
3939 len = 1;
3940 } else {
3941 po_wchars = path->wide;
3942 len = wcslen(path->wide);
3943 }
3944 /* The +5 is so we can append "\\*.*\0" */
3945 wnamebuf = PyMem_New(wchar_t, len + 5);
3946 if (!wnamebuf) {
3947 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003948 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003949 }
Steve Dowercc16be82016-09-08 10:35:16 -07003950 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003951 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003952 wchar_t wch = wnamebuf[len-1];
3953 if (wch != SEP && wch != ALTSEP && wch != L':')
3954 wnamebuf[len++] = SEP;
3955 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003956 }
Steve Dowercc16be82016-09-08 10:35:16 -07003957 if ((list = PyList_New(0)) == NULL) {
3958 goto exit;
3959 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003960 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003961 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003962 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003963 if (hFindFile == INVALID_HANDLE_VALUE) {
3964 int error = GetLastError();
3965 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003966 goto exit;
3967 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003968 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003969 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003970 }
3971 do {
3972 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003973 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3974 wcscmp(wFileData.cFileName, L"..") != 0) {
3975 v = PyUnicode_FromWideChar(wFileData.cFileName,
3976 wcslen(wFileData.cFileName));
3977 if (path->narrow && v) {
3978 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3979 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003980 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003981 Py_DECREF(list);
3982 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003983 break;
3984 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003985 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003986 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003987 Py_DECREF(list);
3988 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003989 break;
3990 }
3991 Py_DECREF(v);
3992 }
3993 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003994 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003995 Py_END_ALLOW_THREADS
3996 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3997 it got to the end of the directory. */
3998 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004000 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004001 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004002 }
4003 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004004
Larry Hastings9cf065c2012-06-22 16:30:09 -07004005exit:
4006 if (hFindFile != INVALID_HANDLE_VALUE) {
4007 if (FindClose(hFindFile) == FALSE) {
4008 if (list != NULL) {
4009 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004010 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004011 }
4012 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004013 }
Victor Stinnerb6404912013-07-07 16:21:41 +02004014 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004015
Larry Hastings9cf065c2012-06-22 16:30:09 -07004016 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004017} /* end of _listdir_windows_no_opendir */
4018
4019#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
4020
4021static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07004022_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004023{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004024 PyObject *v;
4025 DIR *dirp = NULL;
4026 struct dirent *ep;
4027 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004028#ifdef HAVE_FDOPENDIR
4029 int fd = -1;
4030#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004031
Victor Stinner8c62be82010-05-06 00:08:46 +00004032 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004033#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07004034 if (path->fd != -1) {
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004035 if (HAVE_FDOPENDIR_RUNTIME) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004036 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02004037 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01004038 if (fd == -1)
4039 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004040
Larry Hastingsfdaea062012-06-25 04:42:23 -07004041 return_str = 1;
4042
Larry Hastings9cf065c2012-06-22 16:30:09 -07004043 Py_BEGIN_ALLOW_THREADS
4044 dirp = fdopendir(fd);
4045 Py_END_ALLOW_THREADS
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004046 } else {
4047 PyErr_SetString(PyExc_TypeError,
4048 "listdir: path should be string, bytes, os.PathLike or None, not int");
4049 return NULL;
4050 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004051 }
4052 else
4053#endif
4054 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004055 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07004056 if (path->narrow) {
4057 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03004058 /* only return bytes if they specified a bytes-like object */
4059 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07004060 }
4061 else {
4062 name = ".";
4063 return_str = 1;
4064 }
4065
Larry Hastings9cf065c2012-06-22 16:30:09 -07004066 Py_BEGIN_ALLOW_THREADS
4067 dirp = opendir(name);
4068 Py_END_ALLOW_THREADS
4069 }
4070
4071 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07004072 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004073#ifdef HAVE_FDOPENDIR
4074 if (fd != -1) {
4075 Py_BEGIN_ALLOW_THREADS
4076 close(fd);
4077 Py_END_ALLOW_THREADS
4078 }
4079#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004080 goto exit;
4081 }
4082 if ((list = PyList_New(0)) == NULL) {
4083 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004084 }
4085 for (;;) {
4086 errno = 0;
4087 Py_BEGIN_ALLOW_THREADS
4088 ep = readdir(dirp);
4089 Py_END_ALLOW_THREADS
4090 if (ep == NULL) {
4091 if (errno == 0) {
4092 break;
4093 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004094 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004095 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004096 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004097 }
4098 }
4099 if (ep->d_name[0] == '.' &&
4100 (NAMLEN(ep) == 1 ||
4101 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
4102 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07004103 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00004104 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
4105 else
4106 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00004107 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004108 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004109 break;
4110 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004111 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004112 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004114 break;
4115 }
4116 Py_DECREF(v);
4117 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00004118
Larry Hastings9cf065c2012-06-22 16:30:09 -07004119exit:
4120 if (dirp != NULL) {
4121 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004122#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07004123 if (fd > -1)
4124 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004125#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004126 closedir(dirp);
4127 Py_END_ALLOW_THREADS
4128 }
4129
Larry Hastings9cf065c2012-06-22 16:30:09 -07004130 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004131} /* end of _posix_listdir */
4132#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004133
Larry Hastings2f936352014-08-05 14:04:04 +10004134
4135/*[clinic input]
4136os.listdir
4137
4138 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
4139
4140Return a list containing the names of the files in the directory.
4141
BNMetricsb9427072018-11-02 15:20:19 +00004142path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10004143 the filenames returned will also be bytes; in all other circumstances
4144 the filenames returned will be str.
4145If path is None, uses the path='.'.
4146On some platforms, path may also be specified as an open file descriptor;\
4147 the file descriptor must refer to a directory.
4148 If this functionality is unavailable, using it raises NotImplementedError.
4149
4150The list is in arbitrary order. It does not include the special
4151entries '.' and '..' even if they are present in the directory.
4152
4153
4154[clinic start generated code]*/
4155
Larry Hastings2f936352014-08-05 14:04:04 +10004156static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004157os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00004158/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004159{
Steve Dower60419a72019-06-24 08:42:54 -07004160 if (PySys_Audit("os.listdir", "O",
4161 path->object ? path->object : Py_None) < 0) {
4162 return NULL;
4163 }
Larry Hastings2f936352014-08-05 14:04:04 +10004164#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4165 return _listdir_windows_no_opendir(path, NULL);
4166#else
4167 return _posix_listdir(path, NULL);
4168#endif
4169}
4170
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004171#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00004172/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004173/*[clinic input]
4174os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02004175
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004176 path: path_t
4177 /
4178
4179[clinic start generated code]*/
4180
4181static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004182os__getfullpathname_impl(PyObject *module, path_t *path)
4183/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004184{
Victor Stinner3939c322019-06-25 15:02:43 +02004185 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004186
Victor Stinner3939c322019-06-25 15:02:43 +02004187 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
4188 if (_Py_abspath(path->wide, &abspath) < 0) {
4189 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00004190 }
Victor Stinner3939c322019-06-25 15:02:43 +02004191 if (abspath == NULL) {
4192 return PyErr_NoMemory();
4193 }
4194
4195 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
4196 PyMem_RawFree(abspath);
4197 if (str == NULL) {
4198 return NULL;
4199 }
4200 if (path->narrow) {
4201 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
4202 }
4203 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10004204}
Brian Curtind40e6f72010-07-08 21:39:08 +00004205
Brian Curtind25aef52011-06-13 15:16:04 -05004206
Larry Hastings2f936352014-08-05 14:04:04 +10004207/*[clinic input]
4208os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004209
Steve Dower23ad6d02018-02-22 10:39:10 -08004210 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004211 /
4212
4213A helper function for samepath on windows.
4214[clinic start generated code]*/
4215
Larry Hastings2f936352014-08-05 14:04:04 +10004216static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004217os__getfinalpathname_impl(PyObject *module, path_t *path)
4218/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004219{
4220 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004221 wchar_t buf[MAXPATHLEN], *target_path = buf;
4222 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00004223 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004224 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004225
Steve Dower23ad6d02018-02-22 10:39:10 -08004226 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004227 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08004228 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004229 0, /* desired access */
4230 0, /* share mode */
4231 NULL, /* security attributes */
4232 OPEN_EXISTING,
4233 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4234 FILE_FLAG_BACKUP_SEMANTICS,
4235 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004236 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004237
Steve Dower23ad6d02018-02-22 10:39:10 -08004238 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004239 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004240 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004241
4242 /* We have a good handle to the target, use it to determine the
4243 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004244 while (1) {
4245 Py_BEGIN_ALLOW_THREADS
4246 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4247 buf_size, VOLUME_NAME_DOS);
4248 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004249
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004250 if (!result_length) {
4251 result = win32_error_object("GetFinalPathNameByHandleW",
4252 path->object);
4253 goto cleanup;
4254 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004255
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004256 if (result_length < buf_size) {
4257 break;
4258 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004259
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004260 wchar_t *tmp;
4261 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4262 result_length * sizeof(*tmp));
4263 if (!tmp) {
4264 result = PyErr_NoMemory();
4265 goto cleanup;
4266 }
4267
4268 buf_size = result_length;
4269 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004270 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004271
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004272 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004273 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004274 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004275 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004276
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004277cleanup:
4278 if (target_path != buf) {
4279 PyMem_Free(target_path);
4280 }
4281 CloseHandle(hFile);
4282 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004283}
Brian Curtin62857742010-09-06 17:07:27 +00004284
Tim Golden6b528062013-08-01 12:44:00 +01004285
Larry Hastings2f936352014-08-05 14:04:04 +10004286/*[clinic input]
4287os._getvolumepathname
4288
Steve Dower23ad6d02018-02-22 10:39:10 -08004289 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004290
4291A helper function for ismount on Win32.
4292[clinic start generated code]*/
4293
Larry Hastings2f936352014-08-05 14:04:04 +10004294static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004295os__getvolumepathname_impl(PyObject *module, path_t *path)
4296/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004297{
4298 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004299 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004300 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004301 BOOL ret;
4302
Tim Golden6b528062013-08-01 12:44:00 +01004303 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004304 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004305
Victor Stinner850a18e2017-10-24 16:53:32 -07004306 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004307 PyErr_SetString(PyExc_OverflowError, "path too long");
4308 return NULL;
4309 }
4310
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004311 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004312 if (mountpath == NULL)
4313 return PyErr_NoMemory();
4314
4315 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004316 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004317 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004318 Py_END_ALLOW_THREADS
4319
4320 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004321 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004322 goto exit;
4323 }
4324 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004325 if (path->narrow)
4326 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004327
4328exit:
4329 PyMem_Free(mountpath);
4330 return result;
4331}
Tim Golden6b528062013-08-01 12:44:00 +01004332
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004333#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004334
Larry Hastings2f936352014-08-05 14:04:04 +10004335
4336/*[clinic input]
4337os.mkdir
4338
4339 path : path_t
4340
4341 mode: int = 0o777
4342
4343 *
4344
4345 dir_fd : dir_fd(requires='mkdirat') = None
4346
4347# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4348
4349Create a directory.
4350
4351If dir_fd is not None, it should be a file descriptor open to a directory,
4352 and path should be relative; path will then be relative to that directory.
4353dir_fd may not be implemented on your platform.
4354 If it is unavailable, using it will raise a NotImplementedError.
4355
4356The mode argument is ignored on Windows.
4357[clinic start generated code]*/
4358
Larry Hastings2f936352014-08-05 14:04:04 +10004359static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004360os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4361/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004362{
4363 int result;
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004364#ifdef HAVE_MKDIRAT
4365 int mkdirat_unavailable = 0;
4366#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004367
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004368 if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
4369 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4370 return NULL;
4371 }
4372
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004373#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004374 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004375 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004376 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004377
Larry Hastings2f936352014-08-05 14:04:04 +10004378 if (!result)
4379 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004380#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004381 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004382#if HAVE_MKDIRAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004383 if (dir_fd != DEFAULT_DIR_FD) {
4384 if (HAVE_MKDIRAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10004385 result = mkdirat(dir_fd, path->narrow, mode);
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004386
4387 } else {
4388 mkdirat_unavailable = 1;
4389 }
4390 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004391#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004392#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004393 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004394#else
Larry Hastings2f936352014-08-05 14:04:04 +10004395 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004396#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004397 Py_END_ALLOW_THREADS
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004398
4399#if HAVE_MKDIRAT
4400 if (mkdirat_unavailable) {
4401 argument_unavailable_error(NULL, "dir_fd");
4402 return NULL;
4403 }
4404#endif
4405
Larry Hastings2f936352014-08-05 14:04:04 +10004406 if (result < 0)
4407 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004408#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004409 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004410}
4411
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004412
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004413/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4414#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004415#include <sys/resource.h>
4416#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004417
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004418
4419#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004420/*[clinic input]
4421os.nice
4422
4423 increment: int
4424 /
4425
4426Add increment to the priority of process and return the new priority.
4427[clinic start generated code]*/
4428
Larry Hastings2f936352014-08-05 14:04:04 +10004429static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004430os_nice_impl(PyObject *module, int increment)
4431/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004432{
4433 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004434
Victor Stinner8c62be82010-05-06 00:08:46 +00004435 /* There are two flavours of 'nice': one that returns the new
4436 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004437 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004438 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004439
Victor Stinner8c62be82010-05-06 00:08:46 +00004440 If we are of the nice family that returns the new priority, we
4441 need to clear errno before the call, and check if errno is filled
4442 before calling posix_error() on a returnvalue of -1, because the
4443 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004444
Victor Stinner8c62be82010-05-06 00:08:46 +00004445 errno = 0;
4446 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004447#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004448 if (value == 0)
4449 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004450#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004451 if (value == -1 && errno != 0)
4452 /* either nice() or getpriority() returned an error */
4453 return posix_error();
4454 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004455}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004456#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004457
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004458
4459#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004460/*[clinic input]
4461os.getpriority
4462
4463 which: int
4464 who: int
4465
4466Return program scheduling priority.
4467[clinic start generated code]*/
4468
Larry Hastings2f936352014-08-05 14:04:04 +10004469static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004470os_getpriority_impl(PyObject *module, int which, int who)
4471/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004472{
4473 int retval;
4474
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004475 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004476 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004477 if (errno != 0)
4478 return posix_error();
4479 return PyLong_FromLong((long)retval);
4480}
4481#endif /* HAVE_GETPRIORITY */
4482
4483
4484#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004485/*[clinic input]
4486os.setpriority
4487
4488 which: int
4489 who: int
4490 priority: int
4491
4492Set program scheduling priority.
4493[clinic start generated code]*/
4494
Larry Hastings2f936352014-08-05 14:04:04 +10004495static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004496os_setpriority_impl(PyObject *module, int which, int who, int priority)
4497/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004498{
4499 int retval;
4500
4501 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004502 if (retval == -1)
4503 return posix_error();
4504 Py_RETURN_NONE;
4505}
4506#endif /* HAVE_SETPRIORITY */
4507
4508
Barry Warsaw53699e91996-12-10 23:23:01 +00004509static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004510internal_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 +00004511{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004512 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004513 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004514
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004515#ifdef HAVE_RENAMEAT
4516 int renameat_unavailable = 0;
4517#endif
4518
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004519#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004520 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004521 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004522#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004523 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004524#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004525
Larry Hastings9cf065c2012-06-22 16:30:09 -07004526 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4527 (dst_dir_fd != DEFAULT_DIR_FD);
4528#ifndef HAVE_RENAMEAT
4529 if (dir_fd_specified) {
4530 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004531 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004532 }
4533#endif
4534
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004535 if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
4536 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
4537 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
4538 return NULL;
4539 }
4540
Larry Hastings9cf065c2012-06-22 16:30:09 -07004541#ifdef MS_WINDOWS
4542 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004543 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004544 Py_END_ALLOW_THREADS
4545
Larry Hastings2f936352014-08-05 14:04:04 +10004546 if (!result)
4547 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004548
4549#else
Steve Dowercc16be82016-09-08 10:35:16 -07004550 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4551 PyErr_Format(PyExc_ValueError,
4552 "%s: src and dst must be the same type", function_name);
4553 return NULL;
4554 }
4555
Larry Hastings9cf065c2012-06-22 16:30:09 -07004556 Py_BEGIN_ALLOW_THREADS
4557#ifdef HAVE_RENAMEAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004558 if (dir_fd_specified) {
4559 if (HAVE_RENAMEAT_RUNTIME) {
4560 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
4561 } else {
4562 renameat_unavailable = 1;
4563 }
4564 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004565#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004566 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004567 Py_END_ALLOW_THREADS
4568
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004569
4570#ifdef HAVE_RENAMEAT
4571 if (renameat_unavailable) {
4572 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4573 return NULL;
4574 }
4575#endif
4576
Larry Hastings2f936352014-08-05 14:04:04 +10004577 if (result)
4578 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004579#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004580 Py_RETURN_NONE;
4581}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582
Larry Hastings2f936352014-08-05 14:04:04 +10004583
4584/*[clinic input]
4585os.rename
4586
4587 src : path_t
4588 dst : path_t
4589 *
4590 src_dir_fd : dir_fd = None
4591 dst_dir_fd : dir_fd = None
4592
4593Rename a file or directory.
4594
4595If either src_dir_fd or dst_dir_fd is not None, it should be a file
4596 descriptor open to a directory, and the respective path string (src or dst)
4597 should be relative; the path will then be relative to that directory.
4598src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4599 If they are unavailable, using them will raise a NotImplementedError.
4600[clinic start generated code]*/
4601
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004602static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004603os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004604 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004605/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004606{
Larry Hastings2f936352014-08-05 14:04:04 +10004607 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004608}
4609
Larry Hastings2f936352014-08-05 14:04:04 +10004610
4611/*[clinic input]
4612os.replace = os.rename
4613
4614Rename a file or directory, overwriting the destination.
4615
4616If either src_dir_fd or dst_dir_fd is not None, it should be a file
4617 descriptor open to a directory, and the respective path string (src or dst)
4618 should be relative; the path will then be relative to that directory.
4619src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004620 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004621[clinic start generated code]*/
4622
Larry Hastings2f936352014-08-05 14:04:04 +10004623static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004624os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4625 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004626/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004627{
4628 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4629}
4630
4631
4632/*[clinic input]
4633os.rmdir
4634
4635 path: path_t
4636 *
4637 dir_fd: dir_fd(requires='unlinkat') = None
4638
4639Remove a directory.
4640
4641If dir_fd is not None, it should be a file descriptor open to a directory,
4642 and path should be relative; path will then be relative to that directory.
4643dir_fd may not be implemented on your platform.
4644 If it is unavailable, using it will raise a NotImplementedError.
4645[clinic start generated code]*/
4646
Larry Hastings2f936352014-08-05 14:04:04 +10004647static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004648os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4649/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004650{
4651 int result;
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004652#ifdef HAVE_UNLINKAT
4653 int unlinkat_unavailable = 0;
4654#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004655
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004656 if (PySys_Audit("os.rmdir", "Oi", path->object,
4657 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4658 return NULL;
4659 }
4660
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004661 Py_BEGIN_ALLOW_THREADS
4662#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004663 /* Windows, success=1, UNIX, success=0 */
4664 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004665#else
4666#ifdef HAVE_UNLINKAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004667 if (dir_fd != DEFAULT_DIR_FD) {
4668 if (HAVE_UNLINKAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10004669 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004670 } else {
4671 unlinkat_unavailable = 1;
4672 result = -1;
4673 }
4674 } else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004675#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004676 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004677#endif
4678 Py_END_ALLOW_THREADS
4679
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004680#ifdef HAVE_UNLINKAT
4681 if (unlinkat_unavailable) {
4682 argument_unavailable_error("rmdir", "dir_fd");
4683 return NULL;
4684 }
4685#endif
4686
Larry Hastings2f936352014-08-05 14:04:04 +10004687 if (result)
4688 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004689
Larry Hastings2f936352014-08-05 14:04:04 +10004690 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004691}
4692
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004693
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004694#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004695#ifdef MS_WINDOWS
4696/*[clinic input]
4697os.system -> long
4698
4699 command: Py_UNICODE
4700
4701Execute the command in a subshell.
4702[clinic start generated code]*/
4703
Larry Hastings2f936352014-08-05 14:04:04 +10004704static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004705os_system_impl(PyObject *module, const Py_UNICODE *command)
4706/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004707{
4708 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004709
Steve Dowerfbe3c762019-10-18 00:52:15 -07004710 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004711 return -1;
4712 }
4713
Victor Stinner8c62be82010-05-06 00:08:46 +00004714 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004715 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004716 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004717 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004718 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004719 return result;
4720}
4721#else /* MS_WINDOWS */
4722/*[clinic input]
4723os.system -> long
4724
4725 command: FSConverter
4726
4727Execute the command in a subshell.
4728[clinic start generated code]*/
4729
Larry Hastings2f936352014-08-05 14:04:04 +10004730static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004731os_system_impl(PyObject *module, PyObject *command)
4732/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004733{
4734 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004735 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004736
Steve Dowerfbe3c762019-10-18 00:52:15 -07004737 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004738 return -1;
4739 }
4740
Larry Hastings2f936352014-08-05 14:04:04 +10004741 Py_BEGIN_ALLOW_THREADS
4742 result = system(bytes);
4743 Py_END_ALLOW_THREADS
4744 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004745}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004746#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004747#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004749
Larry Hastings2f936352014-08-05 14:04:04 +10004750/*[clinic input]
4751os.umask
4752
4753 mask: int
4754 /
4755
4756Set the current numeric umask and return the previous umask.
4757[clinic start generated code]*/
4758
Larry Hastings2f936352014-08-05 14:04:04 +10004759static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004760os_umask_impl(PyObject *module, int mask)
4761/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004762{
4763 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004764 if (i < 0)
4765 return posix_error();
4766 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004767}
4768
Brian Curtind40e6f72010-07-08 21:39:08 +00004769#ifdef MS_WINDOWS
4770
4771/* override the default DeleteFileW behavior so that directory
4772symlinks can be removed with this function, the same as with
4773Unix symlinks */
4774BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4775{
4776 WIN32_FILE_ATTRIBUTE_DATA info;
4777 WIN32_FIND_DATAW find_data;
4778 HANDLE find_data_handle;
4779 int is_directory = 0;
4780 int is_link = 0;
4781
4782 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4783 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004784
Brian Curtind40e6f72010-07-08 21:39:08 +00004785 /* Get WIN32_FIND_DATA structure for the path to determine if
4786 it is a symlink */
4787 if(is_directory &&
4788 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4789 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4790
4791 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004792 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4793 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4794 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4795 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004796 FindClose(find_data_handle);
4797 }
4798 }
4799 }
4800
4801 if (is_directory && is_link)
4802 return RemoveDirectoryW(lpFileName);
4803
4804 return DeleteFileW(lpFileName);
4805}
4806#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004808
Larry Hastings2f936352014-08-05 14:04:04 +10004809/*[clinic input]
4810os.unlink
4811
4812 path: path_t
4813 *
4814 dir_fd: dir_fd(requires='unlinkat')=None
4815
4816Remove a file (same as remove()).
4817
4818If dir_fd is not None, it should be a file descriptor open to a directory,
4819 and path should be relative; path will then be relative to that directory.
4820dir_fd may not be implemented on your platform.
4821 If it is unavailable, using it will raise a NotImplementedError.
4822
4823[clinic start generated code]*/
4824
Larry Hastings2f936352014-08-05 14:04:04 +10004825static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004826os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4827/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004828{
4829 int result;
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004830#ifdef HAVE_UNLINKAT
4831 int unlinkat_unavailable = 0;
4832#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004833
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004834 if (PySys_Audit("os.remove", "Oi", path->object,
4835 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4836 return NULL;
4837 }
4838
Larry Hastings9cf065c2012-06-22 16:30:09 -07004839 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004840 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004841#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004842 /* Windows, success=1, UNIX, success=0 */
4843 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004844#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004845#ifdef HAVE_UNLINKAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004846 if (dir_fd != DEFAULT_DIR_FD) {
4847 if (HAVE_UNLINKAT_RUNTIME) {
4848
Larry Hastings2f936352014-08-05 14:04:04 +10004849 result = unlinkat(dir_fd, path->narrow, 0);
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004850 } else {
4851 unlinkat_unavailable = 1;
4852 }
4853 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004854#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004855 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004856#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004857 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004858 Py_END_ALLOW_THREADS
4859
Ronald Oussorene8b1c032020-11-22 11:18:40 +01004860#ifdef HAVE_UNLINKAT
4861 if (unlinkat_unavailable) {
4862 argument_unavailable_error(NULL, "dir_fd");
4863 return NULL;
4864 }
4865#endif
4866
Larry Hastings2f936352014-08-05 14:04:04 +10004867 if (result)
4868 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004869
Larry Hastings2f936352014-08-05 14:04:04 +10004870 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004871}
4872
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004873
Larry Hastings2f936352014-08-05 14:04:04 +10004874/*[clinic input]
4875os.remove = os.unlink
4876
4877Remove a file (same as unlink()).
4878
4879If dir_fd is not None, it should be a file descriptor open to a directory,
4880 and path should be relative; path will then be relative to that directory.
4881dir_fd may not be implemented on your platform.
4882 If it is unavailable, using it will raise a NotImplementedError.
4883[clinic start generated code]*/
4884
Larry Hastings2f936352014-08-05 14:04:04 +10004885static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004886os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4887/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004888{
4889 return os_unlink_impl(module, path, dir_fd);
4890}
4891
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004892
Larry Hastings605a62d2012-06-24 04:33:36 -07004893static PyStructSequence_Field uname_result_fields[] = {
4894 {"sysname", "operating system name"},
4895 {"nodename", "name of machine on network (implementation-defined)"},
4896 {"release", "operating system release"},
4897 {"version", "operating system version"},
4898 {"machine", "hardware identifier"},
4899 {NULL}
4900};
4901
4902PyDoc_STRVAR(uname_result__doc__,
4903"uname_result: Result from os.uname().\n\n\
4904This object may be accessed either as a tuple of\n\
4905 (sysname, nodename, release, version, machine),\n\
4906or via the attributes sysname, nodename, release, version, and machine.\n\
4907\n\
4908See os.uname for more information.");
4909
4910static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08004911 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07004912 uname_result__doc__, /* doc */
4913 uname_result_fields,
4914 5
4915};
4916
Larry Hastings605a62d2012-06-24 04:33:36 -07004917#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004918/*[clinic input]
4919os.uname
4920
4921Return an object identifying the current operating system.
4922
4923The object behaves like a named tuple with the following fields:
4924 (sysname, nodename, release, version, machine)
4925
4926[clinic start generated code]*/
4927
Larry Hastings2f936352014-08-05 14:04:04 +10004928static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004929os_uname_impl(PyObject *module)
4930/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004931{
Victor Stinner8c62be82010-05-06 00:08:46 +00004932 struct utsname u;
4933 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004934 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004935
Victor Stinner8c62be82010-05-06 00:08:46 +00004936 Py_BEGIN_ALLOW_THREADS
4937 res = uname(&u);
4938 Py_END_ALLOW_THREADS
4939 if (res < 0)
4940 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004941
Hai Shif707d942020-03-16 21:15:01 +08004942 PyObject *UnameResultType = get_posix_state(module)->UnameResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08004943 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004944 if (value == NULL)
4945 return NULL;
4946
4947#define SET(i, field) \
4948 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004949 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004950 if (!o) { \
4951 Py_DECREF(value); \
4952 return NULL; \
4953 } \
4954 PyStructSequence_SET_ITEM(value, i, o); \
4955 } \
4956
4957 SET(0, u.sysname);
4958 SET(1, u.nodename);
4959 SET(2, u.release);
4960 SET(3, u.version);
4961 SET(4, u.machine);
4962
4963#undef SET
4964
4965 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004966}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004967#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004968
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004969
Larry Hastings9cf065c2012-06-22 16:30:09 -07004970
4971typedef struct {
4972 int now;
4973 time_t atime_s;
4974 long atime_ns;
4975 time_t mtime_s;
4976 long mtime_ns;
4977} utime_t;
4978
4979/*
Victor Stinner484df002014-10-09 13:52:31 +02004980 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004981 * they also intentionally leak the declaration of a pointer named "time"
4982 */
4983#define UTIME_TO_TIMESPEC \
4984 struct timespec ts[2]; \
4985 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004986 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004987 time = NULL; \
4988 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004989 ts[0].tv_sec = ut->atime_s; \
4990 ts[0].tv_nsec = ut->atime_ns; \
4991 ts[1].tv_sec = ut->mtime_s; \
4992 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004993 time = ts; \
4994 } \
4995
4996#define UTIME_TO_TIMEVAL \
4997 struct timeval tv[2]; \
4998 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004999 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005000 time = NULL; \
5001 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005002 tv[0].tv_sec = ut->atime_s; \
5003 tv[0].tv_usec = ut->atime_ns / 1000; \
5004 tv[1].tv_sec = ut->mtime_s; \
5005 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005006 time = tv; \
5007 } \
5008
5009#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005010 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005011 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005012 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005013 time = NULL; \
5014 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005015 u.actime = ut->atime_s; \
5016 u.modtime = ut->mtime_s; \
5017 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005018 }
5019
5020#define UTIME_TO_TIME_T \
5021 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005022 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005023 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005024 time = NULL; \
5025 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005026 timet[0] = ut->atime_s; \
5027 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005028 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005029 } \
5030
5031
Victor Stinner528a9ab2015-09-03 21:30:26 +02005032#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005033
5034static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005035utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005036{
Ronald Oussorene8b1c032020-11-22 11:18:40 +01005037#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5038 if (HAVE_UTIMENSAT_RUNTIME) {
5039 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5040 UTIME_TO_TIMESPEC;
5041 return utimensat(dir_fd, path, time, flags);
5042 } else {
5043 errno = ENOSYS;
5044 return -1;
5045 }
5046#elif defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005047 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5048 UTIME_TO_TIMESPEC;
5049 return utimensat(dir_fd, path, time, flags);
5050#elif defined(HAVE_FUTIMESAT)
5051 UTIME_TO_TIMEVAL;
5052 /*
5053 * follow_symlinks will never be false here;
5054 * we only allow !follow_symlinks and dir_fd together
5055 * if we have utimensat()
5056 */
5057 assert(follow_symlinks);
5058 return futimesat(dir_fd, path, time);
5059#endif
5060}
5061
Larry Hastings2f936352014-08-05 14:04:04 +10005062 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
5063#else
5064 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07005065#endif
5066
Victor Stinner528a9ab2015-09-03 21:30:26 +02005067#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005068
5069static int
Victor Stinner484df002014-10-09 13:52:31 +02005070utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005071{
5072#ifdef HAVE_FUTIMENS
Ronald Oussorene8b1c032020-11-22 11:18:40 +01005073
5074 if (HAVE_FUTIMENS_RUNTIME) {
5075
Larry Hastings9cf065c2012-06-22 16:30:09 -07005076 UTIME_TO_TIMESPEC;
5077 return futimens(fd, time);
Ronald Oussorene8b1c032020-11-22 11:18:40 +01005078
5079 } else
5080#ifndef HAVE_FUTIMES
5081 {
5082 /* Not sure if this can happen */
5083 PyErr_SetString(
5084 PyExc_RuntimeError,
5085 "neither futimens nor futimes are supported"
5086 " on this system");
5087 return -1;
5088 }
5089#endif
5090
5091#endif
5092#ifdef HAVE_FUTIMES
5093 {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005094 UTIME_TO_TIMEVAL;
5095 return futimes(fd, time);
Ronald Oussorene8b1c032020-11-22 11:18:40 +01005096 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005097#endif
5098}
5099
Larry Hastings2f936352014-08-05 14:04:04 +10005100 #define PATH_UTIME_HAVE_FD 1
5101#else
5102 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07005103#endif
5104
Victor Stinner5ebae872015-09-22 01:29:33 +02005105#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
5106# define UTIME_HAVE_NOFOLLOW_SYMLINKS
5107#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005108
Victor Stinner4552ced2015-09-21 22:37:15 +02005109#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005110
5111static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005112utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005113{
5114#ifdef HAVE_UTIMENSAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +01005115 if (HAVE_UTIMENSAT_RUNTIME) {
5116 UTIME_TO_TIMESPEC;
5117 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
5118 } else
5119#ifndef HAVE_LUTIMES
5120 {
5121 /* Not sure if this can happen */
5122 PyErr_SetString(
5123 PyExc_RuntimeError,
5124 "neither utimensat nor lutimes are supported"
5125 " on this system");
5126 return -1;
5127 }
5128#endif
5129#endif
5130
5131#ifdef HAVE_LUTIMES
5132 {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005133 UTIME_TO_TIMEVAL;
5134 return lutimes(path, time);
Ronald Oussorene8b1c032020-11-22 11:18:40 +01005135 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005136#endif
5137}
5138
5139#endif
5140
5141#ifndef MS_WINDOWS
5142
5143static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005144utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005145{
Ronald Oussorene8b1c032020-11-22 11:18:40 +01005146#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5147 if (HAVE_UTIMENSAT_RUNTIME) {
5148 UTIME_TO_TIMESPEC;
5149 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5150 } else {
5151 UTIME_TO_TIMEVAL;
5152 return utimes(path, time);
5153 }
5154#elif defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005155 UTIME_TO_TIMESPEC;
5156 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5157#elif defined(HAVE_UTIMES)
5158 UTIME_TO_TIMEVAL;
5159 return utimes(path, time);
5160#elif defined(HAVE_UTIME_H)
5161 UTIME_TO_UTIMBUF;
5162 return utime(path, time);
5163#else
5164 UTIME_TO_TIME_T;
5165 return utime(path, time);
5166#endif
5167}
5168
5169#endif
5170
Larry Hastings76ad59b2012-05-03 00:30:07 -07005171static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005172split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns)
Larry Hastings76ad59b2012-05-03 00:30:07 -07005173{
5174 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04005175 PyObject *divmod;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005176 divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07005177 if (!divmod)
5178 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03005179 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
5180 PyErr_Format(PyExc_TypeError,
5181 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08005182 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03005183 goto exit;
5184 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005185 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
5186 if ((*s == -1) && PyErr_Occurred())
5187 goto exit;
5188 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04005189 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07005190 goto exit;
5191
5192 result = 1;
5193exit:
5194 Py_XDECREF(divmod);
5195 return result;
5196}
5197
Larry Hastings2f936352014-08-05 14:04:04 +10005198
5199/*[clinic input]
5200os.utime
5201
5202 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005203 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10005204 *
5205 ns: object = NULL
5206 dir_fd: dir_fd(requires='futimensat') = None
5207 follow_symlinks: bool=True
5208
Martin Panter0ff89092015-09-09 01:56:53 +00005209# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10005210
5211Set the access and modified time of path.
5212
5213path may always be specified as a string.
5214On some platforms, path may also be specified as an open file descriptor.
5215 If this functionality is unavailable, using it raises an exception.
5216
5217If times is not None, it must be a tuple (atime, mtime);
5218 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00005219If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10005220 atime_ns and mtime_ns should be expressed as integer nanoseconds
5221 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00005222If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10005223Specifying tuples for both times and ns is an error.
5224
5225If dir_fd is not None, it should be a file descriptor open to a directory,
5226 and path should be relative; path will then be relative to that directory.
5227If follow_symlinks is False, and the last element of the path is a symbolic
5228 link, utime will modify the symbolic link itself instead of the file the
5229 link points to.
5230It is an error to use dir_fd or follow_symlinks when specifying path
5231 as an open file descriptor.
5232dir_fd and follow_symlinks may not be available on your platform.
5233 If they are unavailable, using them will raise a NotImplementedError.
5234
5235[clinic start generated code]*/
5236
Larry Hastings2f936352014-08-05 14:04:04 +10005237static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005238os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
5239 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005240/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005241{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005242#ifdef MS_WINDOWS
5243 HANDLE hFile;
5244 FILETIME atime, mtime;
5245#else
5246 int result;
5247#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005248
Larry Hastings2f936352014-08-05 14:04:04 +10005249 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005250
Christian Heimesb3c87242013-08-01 00:08:16 +02005251 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07005252
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005253 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005254 PyErr_SetString(PyExc_ValueError,
5255 "utime: you may specify either 'times'"
5256 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005257 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005258 }
5259
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005260 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005261 time_t a_sec, m_sec;
5262 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005263 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005264 PyErr_SetString(PyExc_TypeError,
5265 "utime: 'times' must be either"
5266 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005267 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005268 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005269 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005270 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02005271 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005272 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02005273 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005274 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005275 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005276 utime.atime_s = a_sec;
5277 utime.atime_ns = a_nsec;
5278 utime.mtime_s = m_sec;
5279 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005280 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005281 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07005282 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005283 PyErr_SetString(PyExc_TypeError,
5284 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005285 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005286 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005287 utime.now = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005288 if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005289 &utime.atime_s, &utime.atime_ns) ||
Victor Stinner1c2fa782020-05-10 11:05:29 +02005290 !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005291 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005292 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005293 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005294 }
5295 else {
5296 /* times and ns are both None/unspecified. use "now". */
5297 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005298 }
5299
Victor Stinner4552ced2015-09-21 22:37:15 +02005300#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005301 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005302 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005303#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005304
Larry Hastings2f936352014-08-05 14:04:04 +10005305 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
5306 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
5307 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005308 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005309
Larry Hastings9cf065c2012-06-22 16:30:09 -07005310#if !defined(HAVE_UTIMENSAT)
5311 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02005312 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005313 "utime: cannot use dir_fd and follow_symlinks "
5314 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005315 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005316 }
5317#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005318
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005319 if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
5320 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
5321 return NULL;
5322 }
5323
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005324#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005325 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005326 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5327 NULL, OPEN_EXISTING,
5328 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005329 Py_END_ALLOW_THREADS
5330 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10005331 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005332 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005333 }
5334
Larry Hastings9cf065c2012-06-22 16:30:09 -07005335 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005336 GetSystemTimeAsFileTime(&mtime);
5337 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005338 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005339 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08005340 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5341 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005342 }
5343 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5344 /* Avoid putting the file name into the error here,
5345 as that may confuse the user into believing that
5346 something is wrong with the file, when it also
5347 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005348 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005349 CloseHandle(hFile);
5350 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005351 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005352 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005353#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005354 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005355
Victor Stinner4552ced2015-09-21 22:37:15 +02005356#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005357 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10005358 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005359 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005360#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005361
Victor Stinner528a9ab2015-09-03 21:30:26 +02005362#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Ronald Oussorene8b1c032020-11-22 11:18:40 +01005363 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
Larry Hastings2f936352014-08-05 14:04:04 +10005364 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Ronald Oussorene8b1c032020-11-22 11:18:40 +01005365
5366 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07005367#endif
5368
Victor Stinner528a9ab2015-09-03 21:30:26 +02005369#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005370 if (path->fd != -1)
5371 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005372 else
5373#endif
5374
Larry Hastings2f936352014-08-05 14:04:04 +10005375 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005376
5377 Py_END_ALLOW_THREADS
5378
Ronald Oussorene8b1c032020-11-22 11:18:40 +01005379#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5380 /* See utime_dir_fd implementation */
5381 if (result == -1 && errno == ENOSYS) {
5382 argument_unavailable_error(NULL, "dir_fd");
5383 return NULL;
5384 }
5385#endif
5386
Larry Hastings9cf065c2012-06-22 16:30:09 -07005387 if (result < 0) {
5388 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005389 posix_error();
5390 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005391 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005392
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005393#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005394
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005395 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005396}
5397
Guido van Rossum3b066191991-06-04 19:40:25 +00005398/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005399
Larry Hastings2f936352014-08-05 14:04:04 +10005400
5401/*[clinic input]
5402os._exit
5403
5404 status: int
5405
5406Exit to the system with specified status, without normal exit processing.
5407[clinic start generated code]*/
5408
Larry Hastings2f936352014-08-05 14:04:04 +10005409static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005410os__exit_impl(PyObject *module, int status)
5411/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005412{
5413 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005414 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005415}
5416
Steve Dowercc16be82016-09-08 10:35:16 -07005417#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5418#define EXECV_CHAR wchar_t
5419#else
5420#define EXECV_CHAR char
5421#endif
5422
pxinwrf2d7ac72019-05-21 18:46:37 +08005423#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005424static void
Steve Dowercc16be82016-09-08 10:35:16 -07005425free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005426{
Victor Stinner8c62be82010-05-06 00:08:46 +00005427 Py_ssize_t i;
5428 for (i = 0; i < count; i++)
5429 PyMem_Free(array[i]);
5430 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005431}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005432
Berker Peksag81816462016-09-15 20:19:47 +03005433static int
5434fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005435{
Victor Stinner8c62be82010-05-06 00:08:46 +00005436 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005437 PyObject *ub;
5438 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005439#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005440 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005441 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005442 *out = PyUnicode_AsWideCharString(ub, &size);
5443 if (*out)
5444 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005445#else
Berker Peksag81816462016-09-15 20:19:47 +03005446 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005447 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005448 size = PyBytes_GET_SIZE(ub);
5449 *out = PyMem_Malloc(size + 1);
5450 if (*out) {
5451 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5452 result = 1;
5453 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005454 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005455#endif
Berker Peksag81816462016-09-15 20:19:47 +03005456 Py_DECREF(ub);
5457 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005458}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005459#endif
5460
pxinwrf2d7ac72019-05-21 18:46:37 +08005461#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005462static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005463parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5464{
Victor Stinner8c62be82010-05-06 00:08:46 +00005465 Py_ssize_t i, pos, envc;
5466 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005467 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005468 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005469
Victor Stinner8c62be82010-05-06 00:08:46 +00005470 i = PyMapping_Size(env);
5471 if (i < 0)
5472 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005473 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005474 if (envlist == NULL) {
5475 PyErr_NoMemory();
5476 return NULL;
5477 }
5478 envc = 0;
5479 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005480 if (!keys)
5481 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005482 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005483 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005484 goto error;
5485 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5486 PyErr_Format(PyExc_TypeError,
5487 "env.keys() or env.values() is not a list");
5488 goto error;
5489 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005490
Victor Stinner8c62be82010-05-06 00:08:46 +00005491 for (pos = 0; pos < i; pos++) {
5492 key = PyList_GetItem(keys, pos);
5493 val = PyList_GetItem(vals, pos);
5494 if (!key || !val)
5495 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005496
Berker Peksag81816462016-09-15 20:19:47 +03005497#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5498 if (!PyUnicode_FSDecoder(key, &key2))
5499 goto error;
5500 if (!PyUnicode_FSDecoder(val, &val2)) {
5501 Py_DECREF(key2);
5502 goto error;
5503 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005504 /* Search from index 1 because on Windows starting '=' is allowed for
5505 defining hidden environment variables. */
5506 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5507 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5508 {
5509 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005510 Py_DECREF(key2);
5511 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005512 goto error;
5513 }
Berker Peksag81816462016-09-15 20:19:47 +03005514 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5515#else
5516 if (!PyUnicode_FSConverter(key, &key2))
5517 goto error;
5518 if (!PyUnicode_FSConverter(val, &val2)) {
5519 Py_DECREF(key2);
5520 goto error;
5521 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005522 if (PyBytes_GET_SIZE(key2) == 0 ||
5523 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5524 {
5525 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005526 Py_DECREF(key2);
5527 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005528 goto error;
5529 }
Berker Peksag81816462016-09-15 20:19:47 +03005530 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5531 PyBytes_AS_STRING(val2));
5532#endif
5533 Py_DECREF(key2);
5534 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005535 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005536 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005537
5538 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5539 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005540 goto error;
5541 }
Berker Peksag81816462016-09-15 20:19:47 +03005542
Steve Dowercc16be82016-09-08 10:35:16 -07005543 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005544 }
5545 Py_DECREF(vals);
5546 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005547
Victor Stinner8c62be82010-05-06 00:08:46 +00005548 envlist[envc] = 0;
5549 *envc_ptr = envc;
5550 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005551
5552error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005553 Py_XDECREF(keys);
5554 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005555 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005556 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005557}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005558
Steve Dowercc16be82016-09-08 10:35:16 -07005559static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005560parse_arglist(PyObject* argv, Py_ssize_t *argc)
5561{
5562 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005563 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005564 if (argvlist == NULL) {
5565 PyErr_NoMemory();
5566 return NULL;
5567 }
5568 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005569 PyObject* item = PySequence_ITEM(argv, i);
5570 if (item == NULL)
5571 goto fail;
5572 if (!fsconvert_strdup(item, &argvlist[i])) {
5573 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005574 goto fail;
5575 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005576 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005577 }
5578 argvlist[*argc] = NULL;
5579 return argvlist;
5580fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005581 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005582 free_string_array(argvlist, *argc);
5583 return NULL;
5584}
Steve Dowercc16be82016-09-08 10:35:16 -07005585
Ross Lagerwall7807c352011-03-17 20:20:30 +02005586#endif
5587
Larry Hastings2f936352014-08-05 14:04:04 +10005588
Ross Lagerwall7807c352011-03-17 20:20:30 +02005589#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005590/*[clinic input]
5591os.execv
5592
Steve Dowercc16be82016-09-08 10:35:16 -07005593 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005594 Path of executable file.
5595 argv: object
5596 Tuple or list of strings.
5597 /
5598
5599Execute an executable path with arguments, replacing current process.
5600[clinic start generated code]*/
5601
Larry Hastings2f936352014-08-05 14:04:04 +10005602static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005603os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5604/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005605{
Steve Dowercc16be82016-09-08 10:35:16 -07005606 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005607 Py_ssize_t argc;
5608
5609 /* execv has two arguments: (path, argv), where
5610 argv is a list or tuple of strings. */
5611
Ross Lagerwall7807c352011-03-17 20:20:30 +02005612 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5613 PyErr_SetString(PyExc_TypeError,
5614 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005615 return NULL;
5616 }
5617 argc = PySequence_Size(argv);
5618 if (argc < 1) {
5619 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005620 return NULL;
5621 }
5622
5623 argvlist = parse_arglist(argv, &argc);
5624 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005625 return NULL;
5626 }
Steve Dowerbce26262016-11-19 19:17:26 -08005627 if (!argvlist[0][0]) {
5628 PyErr_SetString(PyExc_ValueError,
5629 "execv() arg 2 first element cannot be empty");
5630 free_string_array(argvlist, argc);
5631 return NULL;
5632 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005633
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005634 if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005635 free_string_array(argvlist, argc);
5636 return NULL;
5637 }
5638
Steve Dowerbce26262016-11-19 19:17:26 -08005639 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005640#ifdef HAVE_WEXECV
5641 _wexecv(path->wide, argvlist);
5642#else
5643 execv(path->narrow, argvlist);
5644#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005645 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005646
5647 /* If we get here it's definitely an error */
5648
5649 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005650 return posix_error();
5651}
5652
Larry Hastings2f936352014-08-05 14:04:04 +10005653
5654/*[clinic input]
5655os.execve
5656
5657 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5658 Path of executable file.
5659 argv: object
5660 Tuple or list of strings.
5661 env: object
5662 Dictionary of strings mapping to strings.
5663
5664Execute an executable path with arguments, replacing current process.
5665[clinic start generated code]*/
5666
Larry Hastings2f936352014-08-05 14:04:04 +10005667static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005668os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5669/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005670{
Steve Dowercc16be82016-09-08 10:35:16 -07005671 EXECV_CHAR **argvlist = NULL;
5672 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005673 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005674
Victor Stinner8c62be82010-05-06 00:08:46 +00005675 /* execve has three arguments: (path, argv, env), where
5676 argv is a list or tuple of strings and env is a dictionary
5677 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005678
Ross Lagerwall7807c352011-03-17 20:20:30 +02005679 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005680 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005681 "execve: argv must be a tuple or list");
Saiyang Gou95f60012020-02-04 16:15:00 -08005682 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005683 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005684 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005685 if (argc < 1) {
5686 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5687 return NULL;
5688 }
5689
Victor Stinner8c62be82010-05-06 00:08:46 +00005690 if (!PyMapping_Check(env)) {
5691 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005692 "execve: environment must be a mapping object");
Saiyang Gou95f60012020-02-04 16:15:00 -08005693 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005694 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005695
Ross Lagerwall7807c352011-03-17 20:20:30 +02005696 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005697 if (argvlist == NULL) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005698 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005699 }
Steve Dowerbce26262016-11-19 19:17:26 -08005700 if (!argvlist[0][0]) {
5701 PyErr_SetString(PyExc_ValueError,
5702 "execve: argv first element cannot be empty");
Saiyang Gou95f60012020-02-04 16:15:00 -08005703 goto fail_0;
Steve Dowerbce26262016-11-19 19:17:26 -08005704 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005705
Victor Stinner8c62be82010-05-06 00:08:46 +00005706 envlist = parse_envlist(env, &envc);
5707 if (envlist == NULL)
Saiyang Gou95f60012020-02-04 16:15:00 -08005708 goto fail_0;
5709
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005710 if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005711 goto fail_1;
5712 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005713
Steve Dowerbce26262016-11-19 19:17:26 -08005714 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005715#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005716 if (path->fd > -1)
5717 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005718 else
5719#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005720#ifdef HAVE_WEXECV
5721 _wexecve(path->wide, argvlist, envlist);
5722#else
Larry Hastings2f936352014-08-05 14:04:04 +10005723 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005724#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005725 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005726
5727 /* If we get here it's definitely an error */
5728
Alexey Izbyshev83460312018-10-20 03:28:22 +03005729 posix_path_error(path);
Saiyang Gou95f60012020-02-04 16:15:00 -08005730 fail_1:
Steve Dowercc16be82016-09-08 10:35:16 -07005731 free_string_array(envlist, envc);
Saiyang Gou95f60012020-02-04 16:15:00 -08005732 fail_0:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005733 if (argvlist)
5734 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005735 return NULL;
5736}
Steve Dowercc16be82016-09-08 10:35:16 -07005737
Larry Hastings9cf065c2012-06-22 16:30:09 -07005738#endif /* HAVE_EXECV */
5739
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005740#ifdef HAVE_POSIX_SPAWN
5741
5742enum posix_spawn_file_actions_identifier {
5743 POSIX_SPAWN_OPEN,
5744 POSIX_SPAWN_CLOSE,
5745 POSIX_SPAWN_DUP2
5746};
5747
William Orr81574b82018-10-01 22:19:56 -07005748#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005749static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005750convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005751#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005752
5753static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005754parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005755 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005756 PyObject *setsigdef, PyObject *scheduler,
5757 posix_spawnattr_t *attrp)
5758{
5759 long all_flags = 0;
5760
5761 errno = posix_spawnattr_init(attrp);
5762 if (errno) {
5763 posix_error();
5764 return -1;
5765 }
5766
5767 if (setpgroup) {
5768 pid_t pgid = PyLong_AsPid(setpgroup);
5769 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5770 goto fail;
5771 }
5772 errno = posix_spawnattr_setpgroup(attrp, pgid);
5773 if (errno) {
5774 posix_error();
5775 goto fail;
5776 }
5777 all_flags |= POSIX_SPAWN_SETPGROUP;
5778 }
5779
5780 if (resetids) {
5781 all_flags |= POSIX_SPAWN_RESETIDS;
5782 }
5783
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005784 if (setsid) {
Ronald Oussorene8b1c032020-11-22 11:18:40 +01005785#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5786 if (HAVE_POSIX_SPAWN_SETSID_RUNTIME) {
5787#endif
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005788#ifdef POSIX_SPAWN_SETSID
5789 all_flags |= POSIX_SPAWN_SETSID;
5790#elif defined(POSIX_SPAWN_SETSID_NP)
5791 all_flags |= POSIX_SPAWN_SETSID_NP;
5792#else
5793 argument_unavailable_error(func_name, "setsid");
5794 return -1;
5795#endif
Ronald Oussorene8b1c032020-11-22 11:18:40 +01005796
5797#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5798 } else {
5799 argument_unavailable_error(func_name, "setsid");
5800 return -1;
5801 }
5802#endif /* HAVE_POSIX_SPAWN_SETSID_RUNTIME */
5803
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005804 }
5805
Pablo Galindo254a4662018-09-07 16:44:24 +01005806 if (setsigmask) {
5807 sigset_t set;
5808 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5809 goto fail;
5810 }
5811 errno = posix_spawnattr_setsigmask(attrp, &set);
5812 if (errno) {
5813 posix_error();
5814 goto fail;
5815 }
5816 all_flags |= POSIX_SPAWN_SETSIGMASK;
5817 }
5818
5819 if (setsigdef) {
5820 sigset_t set;
5821 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5822 goto fail;
5823 }
5824 errno = posix_spawnattr_setsigdefault(attrp, &set);
5825 if (errno) {
5826 posix_error();
5827 goto fail;
5828 }
5829 all_flags |= POSIX_SPAWN_SETSIGDEF;
5830 }
5831
5832 if (scheduler) {
5833#ifdef POSIX_SPAWN_SETSCHEDULER
5834 PyObject *py_schedpolicy;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005835 PyObject *schedparam_obj;
Pablo Galindo254a4662018-09-07 16:44:24 +01005836 struct sched_param schedparam;
5837
Victor Stinner1c2fa782020-05-10 11:05:29 +02005838 if (!PyArg_ParseTuple(scheduler, "OO"
Pablo Galindo254a4662018-09-07 16:44:24 +01005839 ";A scheduler tuple must have two elements",
Victor Stinner1c2fa782020-05-10 11:05:29 +02005840 &py_schedpolicy, &schedparam_obj)) {
5841 goto fail;
5842 }
5843 if (!convert_sched_param(module, schedparam_obj, &schedparam)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005844 goto fail;
5845 }
5846 if (py_schedpolicy != Py_None) {
5847 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5848
5849 if (schedpolicy == -1 && PyErr_Occurred()) {
5850 goto fail;
5851 }
5852 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5853 if (errno) {
5854 posix_error();
5855 goto fail;
5856 }
5857 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5858 }
5859 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5860 if (errno) {
5861 posix_error();
5862 goto fail;
5863 }
5864 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5865#else
5866 PyErr_SetString(PyExc_NotImplementedError,
5867 "The scheduler option is not supported in this system.");
5868 goto fail;
5869#endif
5870 }
5871
5872 errno = posix_spawnattr_setflags(attrp, all_flags);
5873 if (errno) {
5874 posix_error();
5875 goto fail;
5876 }
5877
5878 return 0;
5879
5880fail:
5881 (void)posix_spawnattr_destroy(attrp);
5882 return -1;
5883}
5884
5885static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005886parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005887 posix_spawn_file_actions_t *file_actionsp,
5888 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005889{
5890 PyObject *seq;
5891 PyObject *file_action = NULL;
5892 PyObject *tag_obj;
5893
5894 seq = PySequence_Fast(file_actions,
5895 "file_actions must be a sequence or None");
5896 if (seq == NULL) {
5897 return -1;
5898 }
5899
5900 errno = posix_spawn_file_actions_init(file_actionsp);
5901 if (errno) {
5902 posix_error();
5903 Py_DECREF(seq);
5904 return -1;
5905 }
5906
Zackery Spytzd52a83a2019-06-26 14:54:20 -06005907 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03005908 file_action = PySequence_Fast_GET_ITEM(seq, i);
5909 Py_INCREF(file_action);
5910 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5911 PyErr_SetString(PyExc_TypeError,
5912 "Each file_actions element must be a non-empty tuple");
5913 goto fail;
5914 }
5915 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5916 if (tag == -1 && PyErr_Occurred()) {
5917 goto fail;
5918 }
5919
5920 /* Populate the file_actions object */
5921 switch (tag) {
5922 case POSIX_SPAWN_OPEN: {
5923 int fd, oflag;
5924 PyObject *path;
5925 unsigned long mode;
5926 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5927 ";A open file_action tuple must have 5 elements",
5928 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5929 &oflag, &mode))
5930 {
5931 goto fail;
5932 }
Pablo Galindocb970732018-06-19 09:19:50 +01005933 if (PyList_Append(temp_buffer, path)) {
5934 Py_DECREF(path);
5935 goto fail;
5936 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005937 errno = posix_spawn_file_actions_addopen(file_actionsp,
5938 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005939 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005940 if (errno) {
5941 posix_error();
5942 goto fail;
5943 }
5944 break;
5945 }
5946 case POSIX_SPAWN_CLOSE: {
5947 int fd;
5948 if (!PyArg_ParseTuple(file_action, "Oi"
5949 ";A close file_action tuple must have 2 elements",
5950 &tag_obj, &fd))
5951 {
5952 goto fail;
5953 }
5954 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5955 if (errno) {
5956 posix_error();
5957 goto fail;
5958 }
5959 break;
5960 }
5961 case POSIX_SPAWN_DUP2: {
5962 int fd1, fd2;
5963 if (!PyArg_ParseTuple(file_action, "Oii"
5964 ";A dup2 file_action tuple must have 3 elements",
5965 &tag_obj, &fd1, &fd2))
5966 {
5967 goto fail;
5968 }
5969 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5970 fd1, fd2);
5971 if (errno) {
5972 posix_error();
5973 goto fail;
5974 }
5975 break;
5976 }
5977 default: {
5978 PyErr_SetString(PyExc_TypeError,
5979 "Unknown file_actions identifier");
5980 goto fail;
5981 }
5982 }
5983 Py_DECREF(file_action);
5984 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005985
Serhiy Storchakaef347532018-05-01 16:45:04 +03005986 Py_DECREF(seq);
5987 return 0;
5988
5989fail:
5990 Py_DECREF(seq);
5991 Py_DECREF(file_action);
5992 (void)posix_spawn_file_actions_destroy(file_actionsp);
5993 return -1;
5994}
5995
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005996
5997static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005998py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5999 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006000 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006001 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006002{
Victor Stinner325e4ba2019-02-01 15:47:24 +01006003 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006004 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006005 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006006 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006007 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01006008 posix_spawnattr_t attr;
6009 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006010 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006011 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01006012 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006013 pid_t pid;
6014 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006015
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006016 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03006017 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006018 like posix.environ. */
6019
Serhiy Storchakaef347532018-05-01 16:45:04 +03006020 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006021 PyErr_Format(PyExc_TypeError,
6022 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006023 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006024 }
6025 argc = PySequence_Size(argv);
6026 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006027 PyErr_Format(PyExc_ValueError,
6028 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006029 return NULL;
6030 }
6031
6032 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006033 PyErr_Format(PyExc_TypeError,
6034 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006035 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006036 }
6037
6038 argvlist = parse_arglist(argv, &argc);
6039 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006040 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006041 }
6042 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006043 PyErr_Format(PyExc_ValueError,
6044 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006045 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006046 }
6047
6048 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006049 if (envlist == NULL) {
6050 goto exit;
6051 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006052
Anthony Shaw948ed8c2019-05-10 12:00:06 +10006053 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01006054 /* There is a bug in old versions of glibc that makes some of the
6055 * helper functions for manipulating file actions not copy the provided
6056 * buffers. The problem is that posix_spawn_file_actions_addopen does not
6057 * copy the value of path for some old versions of glibc (<2.20).
6058 * The use of temp_buffer here is a workaround that keeps the
6059 * python objects that own the buffers alive until posix_spawn gets called.
6060 * Check https://bugs.python.org/issue33630 and
6061 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
6062 temp_buffer = PyList_New(0);
6063 if (!temp_buffer) {
6064 goto exit;
6065 }
6066 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006067 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006068 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03006069 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006070 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006071
Victor Stinner1c2fa782020-05-10 11:05:29 +02006072 if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid,
Victor Stinner325e4ba2019-02-01 15:47:24 +01006073 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01006074 goto exit;
6075 }
6076 attrp = &attr;
6077
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006078 if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006079 goto exit;
6080 }
6081
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006082 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006083#ifdef HAVE_POSIX_SPAWNP
6084 if (use_posix_spawnp) {
6085 err_code = posix_spawnp(&pid, path->narrow,
6086 file_actionsp, attrp, argvlist, envlist);
6087 }
6088 else
6089#endif /* HAVE_POSIX_SPAWNP */
6090 {
6091 err_code = posix_spawn(&pid, path->narrow,
6092 file_actionsp, attrp, argvlist, envlist);
6093 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006094 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006095
Serhiy Storchakaef347532018-05-01 16:45:04 +03006096 if (err_code) {
6097 errno = err_code;
6098 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006099 goto exit;
6100 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006101#ifdef _Py_MEMORY_SANITIZER
6102 __msan_unpoison(&pid, sizeof(pid));
6103#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006104 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006105
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006106exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03006107 if (file_actionsp) {
6108 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006109 }
Pablo Galindo254a4662018-09-07 16:44:24 +01006110 if (attrp) {
6111 (void)posix_spawnattr_destroy(attrp);
6112 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006113 if (envlist) {
6114 free_string_array(envlist, envc);
6115 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006116 if (argvlist) {
6117 free_string_array(argvlist, argc);
6118 }
Pablo Galindocb970732018-06-19 09:19:50 +01006119 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006120 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006121}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006122
6123
6124/*[clinic input]
6125
6126os.posix_spawn
6127 path: path_t
6128 Path of executable file.
6129 argv: object
6130 Tuple or list of strings.
6131 env: object
6132 Dictionary of strings mapping to strings.
6133 /
6134 *
6135 file_actions: object(c_default='NULL') = ()
6136 A sequence of file action tuples.
6137 setpgroup: object = NULL
6138 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6139 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006140 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
6141 setsid: bool(accept={int}) = False
6142 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006143 setsigmask: object(c_default='NULL') = ()
6144 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6145 setsigdef: object(c_default='NULL') = ()
6146 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6147 scheduler: object = NULL
6148 A tuple with the scheduler policy (optional) and parameters.
6149
6150Execute the program specified by path in a new process.
6151[clinic start generated code]*/
6152
6153static PyObject *
6154os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
6155 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006156 PyObject *setpgroup, int resetids, int setsid,
6157 PyObject *setsigmask, PyObject *setsigdef,
6158 PyObject *scheduler)
6159/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006160{
6161 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006162 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006163 scheduler);
6164}
6165 #endif /* HAVE_POSIX_SPAWN */
6166
6167
6168
6169#ifdef HAVE_POSIX_SPAWNP
6170/*[clinic input]
6171
6172os.posix_spawnp
6173 path: path_t
6174 Path of executable file.
6175 argv: object
6176 Tuple or list of strings.
6177 env: object
6178 Dictionary of strings mapping to strings.
6179 /
6180 *
6181 file_actions: object(c_default='NULL') = ()
6182 A sequence of file action tuples.
6183 setpgroup: object = NULL
6184 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6185 resetids: bool(accept={int}) = False
6186 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006187 setsid: bool(accept={int}) = False
6188 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006189 setsigmask: object(c_default='NULL') = ()
6190 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6191 setsigdef: object(c_default='NULL') = ()
6192 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6193 scheduler: object = NULL
6194 A tuple with the scheduler policy (optional) and parameters.
6195
6196Execute the program specified by path in a new process.
6197[clinic start generated code]*/
6198
6199static PyObject *
6200os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
6201 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006202 PyObject *setpgroup, int resetids, int setsid,
6203 PyObject *setsigmask, PyObject *setsigdef,
6204 PyObject *scheduler)
6205/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006206{
6207 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006208 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006209 scheduler);
6210}
6211#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006212
pxinwrf2d7ac72019-05-21 18:46:37 +08006213#ifdef HAVE_RTPSPAWN
6214static intptr_t
6215_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
6216 const char *envp[])
6217{
6218 RTP_ID rtpid;
6219 int status;
6220 pid_t res;
6221 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006222
pxinwrf2d7ac72019-05-21 18:46:37 +08006223 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
6224 uStackSize=0 cannot be used, the default stack size is too small for
6225 Python. */
6226 if (envp) {
6227 rtpid = rtpSpawn(rtpFileName, argv, envp,
6228 100, 0x1000000, 0, VX_FP_TASK);
6229 }
6230 else {
6231 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
6232 100, 0x1000000, 0, VX_FP_TASK);
6233 }
6234 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
6235 do {
6236 res = waitpid((pid_t)rtpid, &status, 0);
6237 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6238
6239 if (res < 0)
6240 return RTP_ID_ERROR;
6241 return ((intptr_t)status);
6242 }
6243 return ((intptr_t)rtpid);
6244}
6245#endif
6246
6247#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10006248/*[clinic input]
6249os.spawnv
6250
6251 mode: int
6252 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006253 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006254 Path of executable file.
6255 argv: object
6256 Tuple or list of strings.
6257 /
6258
6259Execute the program specified by path in a new process.
6260[clinic start generated code]*/
6261
Larry Hastings2f936352014-08-05 14:04:04 +10006262static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006263os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
6264/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006265{
Steve Dowercc16be82016-09-08 10:35:16 -07006266 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10006267 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00006268 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006269 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006270 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00006271
Victor Stinner8c62be82010-05-06 00:08:46 +00006272 /* spawnv has three arguments: (mode, path, argv), where
6273 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006274
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 if (PyList_Check(argv)) {
6276 argc = PyList_Size(argv);
6277 getitem = PyList_GetItem;
6278 }
6279 else if (PyTuple_Check(argv)) {
6280 argc = PyTuple_Size(argv);
6281 getitem = PyTuple_GetItem;
6282 }
6283 else {
6284 PyErr_SetString(PyExc_TypeError,
6285 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00006286 return NULL;
6287 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006288 if (argc == 0) {
6289 PyErr_SetString(PyExc_ValueError,
6290 "spawnv() arg 2 cannot be empty");
6291 return NULL;
6292 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006293
Steve Dowercc16be82016-09-08 10:35:16 -07006294 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006295 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 return PyErr_NoMemory();
6297 }
6298 for (i = 0; i < argc; i++) {
6299 if (!fsconvert_strdup((*getitem)(argv, i),
6300 &argvlist[i])) {
6301 free_string_array(argvlist, i);
6302 PyErr_SetString(
6303 PyExc_TypeError,
6304 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00006305 return NULL;
6306 }
Steve Dower93ff8722016-11-19 19:03:54 -08006307 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02006308 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08006309 PyErr_SetString(
6310 PyExc_ValueError,
6311 "spawnv() arg 2 first element cannot be empty");
6312 return NULL;
6313 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006314 }
6315 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006316
pxinwrf2d7ac72019-05-21 18:46:37 +08006317#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006318 if (mode == _OLD_P_OVERLAY)
6319 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006320#endif
Tim Peters5aa91602002-01-30 05:46:57 +00006321
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006322 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
Saiyang Gou95f60012020-02-04 16:15:00 -08006323 Py_None) < 0) {
6324 free_string_array(argvlist, argc);
6325 return NULL;
6326 }
6327
Victor Stinner8c62be82010-05-06 00:08:46 +00006328 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006329 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006330#ifdef HAVE_WSPAWNV
6331 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006332#elif defined(HAVE_RTPSPAWN)
6333 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07006334#else
6335 spawnval = _spawnv(mode, path->narrow, argvlist);
6336#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006337 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00006339
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00006341
Victor Stinner8c62be82010-05-06 00:08:46 +00006342 if (spawnval == -1)
6343 return posix_error();
6344 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006345 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006346}
6347
Larry Hastings2f936352014-08-05 14:04:04 +10006348/*[clinic input]
6349os.spawnve
6350
6351 mode: int
6352 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006353 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006354 Path of executable file.
6355 argv: object
6356 Tuple or list of strings.
6357 env: object
6358 Dictionary of strings mapping to strings.
6359 /
6360
6361Execute the program specified by path in a new process.
6362[clinic start generated code]*/
6363
Larry Hastings2f936352014-08-05 14:04:04 +10006364static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006365os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006366 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07006367/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006368{
Steve Dowercc16be82016-09-08 10:35:16 -07006369 EXECV_CHAR **argvlist;
6370 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006372 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006373 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006374 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006375 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006376
Victor Stinner8c62be82010-05-06 00:08:46 +00006377 /* spawnve has four arguments: (mode, path, argv, env), where
6378 argv is a list or tuple of strings and env is a dictionary
6379 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006380
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 if (PyList_Check(argv)) {
6382 argc = PyList_Size(argv);
6383 getitem = PyList_GetItem;
6384 }
6385 else if (PyTuple_Check(argv)) {
6386 argc = PyTuple_Size(argv);
6387 getitem = PyTuple_GetItem;
6388 }
6389 else {
6390 PyErr_SetString(PyExc_TypeError,
6391 "spawnve() arg 2 must be a tuple or list");
6392 goto fail_0;
6393 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006394 if (argc == 0) {
6395 PyErr_SetString(PyExc_ValueError,
6396 "spawnve() arg 2 cannot be empty");
6397 goto fail_0;
6398 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 if (!PyMapping_Check(env)) {
6400 PyErr_SetString(PyExc_TypeError,
6401 "spawnve() arg 3 must be a mapping object");
6402 goto fail_0;
6403 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006404
Steve Dowercc16be82016-09-08 10:35:16 -07006405 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006406 if (argvlist == NULL) {
6407 PyErr_NoMemory();
6408 goto fail_0;
6409 }
6410 for (i = 0; i < argc; i++) {
6411 if (!fsconvert_strdup((*getitem)(argv, i),
6412 &argvlist[i]))
6413 {
6414 lastarg = i;
6415 goto fail_1;
6416 }
Steve Dowerbce26262016-11-19 19:17:26 -08006417 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006418 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006419 PyErr_SetString(
6420 PyExc_ValueError,
6421 "spawnv() arg 2 first element cannot be empty");
6422 goto fail_1;
6423 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006424 }
6425 lastarg = argc;
6426 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006427
Victor Stinner8c62be82010-05-06 00:08:46 +00006428 envlist = parse_envlist(env, &envc);
6429 if (envlist == NULL)
6430 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006431
pxinwrf2d7ac72019-05-21 18:46:37 +08006432#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006433 if (mode == _OLD_P_OVERLAY)
6434 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006435#endif
Tim Peters25059d32001-12-07 20:35:43 +00006436
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006437 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006438 goto fail_2;
6439 }
6440
Victor Stinner8c62be82010-05-06 00:08:46 +00006441 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006442 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006443#ifdef HAVE_WSPAWNV
6444 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006445#elif defined(HAVE_RTPSPAWN)
6446 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6447 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006448#else
6449 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6450#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006451 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006453
Victor Stinner8c62be82010-05-06 00:08:46 +00006454 if (spawnval == -1)
6455 (void) posix_error();
6456 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006457 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006458
Saiyang Gou95f60012020-02-04 16:15:00 -08006459 fail_2:
Victor Stinner8c62be82010-05-06 00:08:46 +00006460 while (--envc >= 0)
6461 PyMem_DEL(envlist[envc]);
6462 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006463 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006464 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006465 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006466 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006467}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006468
Guido van Rossuma1065681999-01-25 23:20:23 +00006469#endif /* HAVE_SPAWNV */
6470
6471
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006472#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006473
6474/* Helper function to validate arguments.
6475 Returns 0 on success. non-zero on failure with a TypeError raised.
6476 If obj is non-NULL it must be callable. */
6477static int
6478check_null_or_callable(PyObject *obj, const char* obj_name)
6479{
6480 if (obj && !PyCallable_Check(obj)) {
6481 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006482 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006483 return -1;
6484 }
6485 return 0;
6486}
6487
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006488/*[clinic input]
6489os.register_at_fork
6490
Gregory P. Smith163468a2017-05-29 10:03:41 -07006491 *
6492 before: object=NULL
6493 A callable to be called in the parent before the fork() syscall.
6494 after_in_child: object=NULL
6495 A callable to be called in the child after fork().
6496 after_in_parent: object=NULL
6497 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006498
Gregory P. Smith163468a2017-05-29 10:03:41 -07006499Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006500
Gregory P. Smith163468a2017-05-29 10:03:41 -07006501'before' callbacks are called in reverse order.
6502'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006503
6504[clinic start generated code]*/
6505
6506static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006507os_register_at_fork_impl(PyObject *module, PyObject *before,
6508 PyObject *after_in_child, PyObject *after_in_parent)
6509/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006510{
6511 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006512
Gregory P. Smith163468a2017-05-29 10:03:41 -07006513 if (!before && !after_in_child && !after_in_parent) {
6514 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6515 return NULL;
6516 }
6517 if (check_null_or_callable(before, "before") ||
6518 check_null_or_callable(after_in_child, "after_in_child") ||
6519 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006520 return NULL;
6521 }
Victor Stinner81a7be32020-04-14 15:14:01 +02006522 interp = _PyInterpreterState_GET();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006523
Gregory P. Smith163468a2017-05-29 10:03:41 -07006524 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006525 return NULL;
6526 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006527 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006528 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006529 }
6530 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6531 return NULL;
6532 }
6533 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006534}
6535#endif /* HAVE_FORK */
6536
6537
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006538#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006539/*[clinic input]
6540os.fork1
6541
6542Fork a child process with a single multiplexed (i.e., not bound) thread.
6543
6544Return 0 to child process and PID of child to parent process.
6545[clinic start generated code]*/
6546
Larry Hastings2f936352014-08-05 14:04:04 +10006547static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006548os_fork1_impl(PyObject *module)
6549/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006550{
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006552
Victor Stinner81a7be32020-04-14 15:14:01 +02006553 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006554 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6555 return NULL;
6556 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006557 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006558 pid = fork1();
6559 if (pid == 0) {
6560 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006561 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 } else {
6563 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006564 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 }
6566 if (pid == -1)
6567 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006568 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006569}
Larry Hastings2f936352014-08-05 14:04:04 +10006570#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006571
6572
Guido van Rossumad0ee831995-03-01 10:34:45 +00006573#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006574/*[clinic input]
6575os.fork
6576
6577Fork a child process.
6578
6579Return 0 to child process and PID of child to parent process.
6580[clinic start generated code]*/
6581
Larry Hastings2f936352014-08-05 14:04:04 +10006582static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006583os_fork_impl(PyObject *module)
6584/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006585{
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 pid_t pid;
Victor Stinner252346a2020-05-01 11:33:44 +02006587 PyInterpreterState *interp = _PyInterpreterState_GET();
6588 if (interp->config._isolated_interpreter) {
6589 PyErr_SetString(PyExc_RuntimeError,
6590 "fork not supported for isolated subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -07006591 return NULL;
6592 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006593 if (PySys_Audit("os.fork", NULL) < 0) {
6594 return NULL;
6595 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006596 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006597 pid = fork();
6598 if (pid == 0) {
6599 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006600 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 } else {
6602 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006603 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 }
6605 if (pid == -1)
6606 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006608}
Larry Hastings2f936352014-08-05 14:04:04 +10006609#endif /* HAVE_FORK */
6610
Guido van Rossum85e3b011991-06-03 12:42:10 +00006611
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006612#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006613#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006614/*[clinic input]
6615os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006616
Larry Hastings2f936352014-08-05 14:04:04 +10006617 policy: int
6618
6619Get the maximum scheduling priority for policy.
6620[clinic start generated code]*/
6621
Larry Hastings2f936352014-08-05 14:04:04 +10006622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006623os_sched_get_priority_max_impl(PyObject *module, int policy)
6624/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006625{
6626 int max;
6627
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006628 max = sched_get_priority_max(policy);
6629 if (max < 0)
6630 return posix_error();
6631 return PyLong_FromLong(max);
6632}
6633
Larry Hastings2f936352014-08-05 14:04:04 +10006634
6635/*[clinic input]
6636os.sched_get_priority_min
6637
6638 policy: int
6639
6640Get the minimum scheduling priority for policy.
6641[clinic start generated code]*/
6642
Larry Hastings2f936352014-08-05 14:04:04 +10006643static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006644os_sched_get_priority_min_impl(PyObject *module, int policy)
6645/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006646{
6647 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006648 if (min < 0)
6649 return posix_error();
6650 return PyLong_FromLong(min);
6651}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006652#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6653
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006654
Larry Hastings2f936352014-08-05 14:04:04 +10006655#ifdef HAVE_SCHED_SETSCHEDULER
6656/*[clinic input]
6657os.sched_getscheduler
6658 pid: pid_t
6659 /
6660
Min ho Kimc4cacc82019-07-31 08:16:13 +10006661Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006662
6663Passing 0 for pid returns the scheduling policy for the calling process.
6664[clinic start generated code]*/
6665
Larry Hastings2f936352014-08-05 14:04:04 +10006666static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006667os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006668/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006669{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006670 int policy;
6671
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006672 policy = sched_getscheduler(pid);
6673 if (policy < 0)
6674 return posix_error();
6675 return PyLong_FromLong(policy);
6676}
Larry Hastings2f936352014-08-05 14:04:04 +10006677#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006678
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006679
William Orr81574b82018-10-01 22:19:56 -07006680#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006681/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006682class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006683
6684@classmethod
6685os.sched_param.__new__
6686
6687 sched_priority: object
6688 A scheduling parameter.
6689
Eddie Elizondob3966632019-11-05 07:16:14 -08006690Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006691[clinic start generated code]*/
6692
Larry Hastings2f936352014-08-05 14:04:04 +10006693static PyObject *
6694os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006695/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006696{
6697 PyObject *res;
6698
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006699 res = PyStructSequence_New(type);
6700 if (!res)
6701 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006702 Py_INCREF(sched_priority);
6703 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006704 return res;
6705}
6706
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006707PyDoc_VAR(os_sched_param__doc__);
6708
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006709static PyStructSequence_Field sched_param_fields[] = {
6710 {"sched_priority", "the scheduling priority"},
6711 {0}
6712};
6713
6714static PyStructSequence_Desc sched_param_desc = {
6715 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006716 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006717 sched_param_fields,
6718 1
6719};
6720
6721static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006722convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006723{
6724 long priority;
6725
Victor Stinner1c2fa782020-05-10 11:05:29 +02006726 if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006727 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6728 return 0;
6729 }
6730 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6731 if (priority == -1 && PyErr_Occurred())
6732 return 0;
6733 if (priority > INT_MAX || priority < INT_MIN) {
6734 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6735 return 0;
6736 }
6737 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6738 return 1;
6739}
William Orr81574b82018-10-01 22:19:56 -07006740#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006741
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006742
6743#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006744/*[clinic input]
6745os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006746
Larry Hastings2f936352014-08-05 14:04:04 +10006747 pid: pid_t
6748 policy: int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006749 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006750 /
6751
6752Set the scheduling policy for the process identified by pid.
6753
6754If pid is 0, the calling process is changed.
6755param is an instance of sched_param.
6756[clinic start generated code]*/
6757
Larry Hastings2f936352014-08-05 14:04:04 +10006758static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006759os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Victor Stinner1c2fa782020-05-10 11:05:29 +02006760 PyObject *param_obj)
6761/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006762{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006763 struct sched_param param;
6764 if (!convert_sched_param(module, param_obj, &param)) {
6765 return NULL;
6766 }
6767
Jesus Cea9c822272011-09-10 01:40:52 +02006768 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006769 ** sched_setscheduler() returns 0 in Linux, but the previous
6770 ** scheduling policy under Solaris/Illumos, and others.
6771 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006772 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02006773 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006774 return posix_error();
6775 Py_RETURN_NONE;
6776}
Larry Hastings2f936352014-08-05 14:04:04 +10006777#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006778
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006779
6780#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006781/*[clinic input]
6782os.sched_getparam
6783 pid: pid_t
6784 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006785
Larry Hastings2f936352014-08-05 14:04:04 +10006786Returns scheduling parameters for the process identified by pid.
6787
6788If pid is 0, returns parameters for the calling process.
6789Return value is an instance of sched_param.
6790[clinic start generated code]*/
6791
Larry Hastings2f936352014-08-05 14:04:04 +10006792static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006793os_sched_getparam_impl(PyObject *module, pid_t pid)
6794/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006795{
6796 struct sched_param param;
6797 PyObject *result;
6798 PyObject *priority;
6799
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006800 if (sched_getparam(pid, &param))
6801 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02006802 PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -08006803 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006804 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006805 return NULL;
6806 priority = PyLong_FromLong(param.sched_priority);
6807 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006808 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006809 return NULL;
6810 }
Larry Hastings2f936352014-08-05 14:04:04 +10006811 PyStructSequence_SET_ITEM(result, 0, priority);
6812 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006813}
6814
Larry Hastings2f936352014-08-05 14:04:04 +10006815
6816/*[clinic input]
6817os.sched_setparam
6818 pid: pid_t
Victor Stinner1c2fa782020-05-10 11:05:29 +02006819 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006820 /
6821
6822Set scheduling parameters for the process identified by pid.
6823
6824If pid is 0, sets parameters for the calling process.
6825param should be an instance of sched_param.
6826[clinic start generated code]*/
6827
Larry Hastings2f936352014-08-05 14:04:04 +10006828static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02006829os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
6830/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006831{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006832 struct sched_param param;
6833 if (!convert_sched_param(module, param_obj, &param)) {
6834 return NULL;
6835 }
6836
6837 if (sched_setparam(pid, &param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006838 return posix_error();
6839 Py_RETURN_NONE;
6840}
Larry Hastings2f936352014-08-05 14:04:04 +10006841#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006842
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006843
6844#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006845/*[clinic input]
6846os.sched_rr_get_interval -> double
6847 pid: pid_t
6848 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006849
Larry Hastings2f936352014-08-05 14:04:04 +10006850Return the round-robin quantum for the process identified by pid, in seconds.
6851
6852Value returned is a float.
6853[clinic start generated code]*/
6854
Larry Hastings2f936352014-08-05 14:04:04 +10006855static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006856os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6857/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006858{
6859 struct timespec interval;
6860 if (sched_rr_get_interval(pid, &interval)) {
6861 posix_error();
6862 return -1.0;
6863 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006864#ifdef _Py_MEMORY_SANITIZER
6865 __msan_unpoison(&interval, sizeof(interval));
6866#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006867 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6868}
6869#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006870
Larry Hastings2f936352014-08-05 14:04:04 +10006871
6872/*[clinic input]
6873os.sched_yield
6874
6875Voluntarily relinquish the CPU.
6876[clinic start generated code]*/
6877
Larry Hastings2f936352014-08-05 14:04:04 +10006878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006879os_sched_yield_impl(PyObject *module)
6880/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006881{
6882 if (sched_yield())
6883 return posix_error();
6884 Py_RETURN_NONE;
6885}
6886
Benjamin Peterson2740af82011-08-02 17:41:34 -05006887#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006888/* The minimum number of CPUs allocated in a cpu_set_t */
6889static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006890
Larry Hastings2f936352014-08-05 14:04:04 +10006891/*[clinic input]
6892os.sched_setaffinity
6893 pid: pid_t
6894 mask : object
6895 /
6896
6897Set the CPU affinity of the process identified by pid to mask.
6898
6899mask should be an iterable of integers identifying CPUs.
6900[clinic start generated code]*/
6901
Larry Hastings2f936352014-08-05 14:04:04 +10006902static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006903os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6904/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006905{
Antoine Pitrou84869872012-08-04 16:16:35 +02006906 int ncpus;
6907 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006908 cpu_set_t *cpu_set = NULL;
6909 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006910
Larry Hastings2f936352014-08-05 14:04:04 +10006911 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006912 if (iterator == NULL)
6913 return NULL;
6914
6915 ncpus = NCPUS_START;
6916 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006917 cpu_set = CPU_ALLOC(ncpus);
6918 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006919 PyErr_NoMemory();
6920 goto error;
6921 }
Larry Hastings2f936352014-08-05 14:04:04 +10006922 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006923
6924 while ((item = PyIter_Next(iterator))) {
6925 long cpu;
6926 if (!PyLong_Check(item)) {
6927 PyErr_Format(PyExc_TypeError,
6928 "expected an iterator of ints, "
6929 "but iterator yielded %R",
6930 Py_TYPE(item));
6931 Py_DECREF(item);
6932 goto error;
6933 }
6934 cpu = PyLong_AsLong(item);
6935 Py_DECREF(item);
6936 if (cpu < 0) {
6937 if (!PyErr_Occurred())
6938 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6939 goto error;
6940 }
6941 if (cpu > INT_MAX - 1) {
6942 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6943 goto error;
6944 }
6945 if (cpu >= ncpus) {
6946 /* Grow CPU mask to fit the CPU number */
6947 int newncpus = ncpus;
6948 cpu_set_t *newmask;
6949 size_t newsetsize;
6950 while (newncpus <= cpu) {
6951 if (newncpus > INT_MAX / 2)
6952 newncpus = cpu + 1;
6953 else
6954 newncpus = newncpus * 2;
6955 }
6956 newmask = CPU_ALLOC(newncpus);
6957 if (newmask == NULL) {
6958 PyErr_NoMemory();
6959 goto error;
6960 }
6961 newsetsize = CPU_ALLOC_SIZE(newncpus);
6962 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006963 memcpy(newmask, cpu_set, setsize);
6964 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006965 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006966 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006967 ncpus = newncpus;
6968 }
Larry Hastings2f936352014-08-05 14:04:04 +10006969 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006970 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07006971 if (PyErr_Occurred()) {
6972 goto error;
6973 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006974 Py_CLEAR(iterator);
6975
Larry Hastings2f936352014-08-05 14:04:04 +10006976 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006977 posix_error();
6978 goto error;
6979 }
Larry Hastings2f936352014-08-05 14:04:04 +10006980 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006981 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006982
6983error:
Larry Hastings2f936352014-08-05 14:04:04 +10006984 if (cpu_set)
6985 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006986 Py_XDECREF(iterator);
6987 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006988}
6989
Larry Hastings2f936352014-08-05 14:04:04 +10006990
6991/*[clinic input]
6992os.sched_getaffinity
6993 pid: pid_t
6994 /
6995
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006996Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006997
6998The affinity is returned as a set of CPU identifiers.
6999[clinic start generated code]*/
7000
Larry Hastings2f936352014-08-05 14:04:04 +10007001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007002os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03007003/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007004{
Antoine Pitrou84869872012-08-04 16:16:35 +02007005 int cpu, ncpus, count;
7006 size_t setsize;
7007 cpu_set_t *mask = NULL;
7008 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007009
Antoine Pitrou84869872012-08-04 16:16:35 +02007010 ncpus = NCPUS_START;
7011 while (1) {
7012 setsize = CPU_ALLOC_SIZE(ncpus);
7013 mask = CPU_ALLOC(ncpus);
7014 if (mask == NULL)
7015 return PyErr_NoMemory();
7016 if (sched_getaffinity(pid, setsize, mask) == 0)
7017 break;
7018 CPU_FREE(mask);
7019 if (errno != EINVAL)
7020 return posix_error();
7021 if (ncpus > INT_MAX / 2) {
7022 PyErr_SetString(PyExc_OverflowError, "could not allocate "
7023 "a large enough CPU set");
7024 return NULL;
7025 }
7026 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007027 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007028
7029 res = PySet_New(NULL);
7030 if (res == NULL)
7031 goto error;
7032 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
7033 if (CPU_ISSET_S(cpu, setsize, mask)) {
7034 PyObject *cpu_num = PyLong_FromLong(cpu);
7035 --count;
7036 if (cpu_num == NULL)
7037 goto error;
7038 if (PySet_Add(res, cpu_num)) {
7039 Py_DECREF(cpu_num);
7040 goto error;
7041 }
7042 Py_DECREF(cpu_num);
7043 }
7044 }
7045 CPU_FREE(mask);
7046 return res;
7047
7048error:
7049 if (mask)
7050 CPU_FREE(mask);
7051 Py_XDECREF(res);
7052 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007053}
7054
Benjamin Peterson2740af82011-08-02 17:41:34 -05007055#endif /* HAVE_SCHED_SETAFFINITY */
7056
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007057#endif /* HAVE_SCHED_H */
7058
Larry Hastings2f936352014-08-05 14:04:04 +10007059
Neal Norwitzb59798b2003-03-21 01:43:31 +00007060/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00007061/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
7062#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00007063#define DEV_PTY_FILE "/dev/ptc"
7064#define HAVE_DEV_PTMX
7065#else
7066#define DEV_PTY_FILE "/dev/ptmx"
7067#endif
7068
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007069#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00007070#ifdef HAVE_PTY_H
7071#include <pty.h>
7072#else
7073#ifdef HAVE_LIBUTIL_H
7074#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00007075#else
7076#ifdef HAVE_UTIL_H
7077#include <util.h>
7078#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007079#endif /* HAVE_LIBUTIL_H */
7080#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00007081#ifdef HAVE_STROPTS_H
7082#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007083#endif
ngie-eign7745ec42018-02-14 11:54:28 -08007084#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007085
Larry Hastings2f936352014-08-05 14:04:04 +10007086
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007087#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10007088/*[clinic input]
7089os.openpty
7090
7091Open a pseudo-terminal.
7092
7093Return a tuple of (master_fd, slave_fd) containing open file descriptors
7094for both the master and slave ends.
7095[clinic start generated code]*/
7096
Larry Hastings2f936352014-08-05 14:04:04 +10007097static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007098os_openpty_impl(PyObject *module)
7099/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007100{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007101 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007102#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007103 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007104#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007105#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007106 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01007107#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007109#endif
7110#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00007111
Thomas Wouters70c21a12000-07-14 14:28:33 +00007112#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007113 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007114 goto posix_error;
7115
7116 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7117 goto error;
7118 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
7119 goto error;
7120
Neal Norwitzb59798b2003-03-21 01:43:31 +00007121#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007122 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
7123 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007124 goto posix_error;
7125 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7126 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007127
Victor Stinnerdaf45552013-08-28 00:53:59 +02007128 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01007130 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007131
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007132#else
Victor Stinner000de532013-11-25 23:19:58 +01007133 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00007134 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007135 goto posix_error;
7136
Victor Stinner8c62be82010-05-06 00:08:46 +00007137 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007138
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 /* change permission of slave */
7140 if (grantpt(master_fd) < 0) {
7141 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007142 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007143 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007144
Victor Stinner8c62be82010-05-06 00:08:46 +00007145 /* unlock slave */
7146 if (unlockpt(master_fd) < 0) {
7147 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007148 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007149 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007150
Victor Stinner8c62be82010-05-06 00:08:46 +00007151 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007152
Victor Stinner8c62be82010-05-06 00:08:46 +00007153 slave_name = ptsname(master_fd); /* get name of slave */
7154 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007155 goto posix_error;
7156
7157 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01007158 if (slave_fd == -1)
7159 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01007160
7161 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7162 goto posix_error;
7163
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02007164#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
7166 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00007167#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00007168 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00007169#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007170#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00007171#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00007172
Victor Stinner8c62be82010-05-06 00:08:46 +00007173 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00007174
Victor Stinnerdaf45552013-08-28 00:53:59 +02007175posix_error:
7176 posix_error();
7177error:
7178 if (master_fd != -1)
7179 close(master_fd);
7180 if (slave_fd != -1)
7181 close(slave_fd);
7182 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00007183}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007184#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007185
Larry Hastings2f936352014-08-05 14:04:04 +10007186
Fred Drake8cef4cf2000-06-28 16:40:38 +00007187#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10007188/*[clinic input]
7189os.forkpty
7190
7191Fork a new process with a new pseudo-terminal as controlling tty.
7192
7193Returns a tuple of (pid, master_fd).
7194Like fork(), return pid of 0 to the child process,
7195and pid of child to the parent process.
7196To both, return fd of newly opened pseudo-terminal.
7197[clinic start generated code]*/
7198
Larry Hastings2f936352014-08-05 14:04:04 +10007199static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007200os_forkpty_impl(PyObject *module)
7201/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007202{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007203 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00007205
Victor Stinner81a7be32020-04-14 15:14:01 +02007206 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07007207 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
7208 return NULL;
7209 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007210 if (PySys_Audit("os.forkpty", NULL) < 0) {
7211 return NULL;
7212 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007213 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00007214 pid = forkpty(&master_fd, NULL, NULL, NULL);
7215 if (pid == 0) {
7216 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007217 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00007218 } else {
7219 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007220 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00007221 }
7222 if (pid == -1)
7223 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007224 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00007225}
Larry Hastings2f936352014-08-05 14:04:04 +10007226#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007227
Ross Lagerwall7807c352011-03-17 20:20:30 +02007228
Guido van Rossumad0ee831995-03-01 10:34:45 +00007229#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007230/*[clinic input]
7231os.getegid
7232
7233Return the current process's effective group id.
7234[clinic start generated code]*/
7235
Larry Hastings2f936352014-08-05 14:04:04 +10007236static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007237os_getegid_impl(PyObject *module)
7238/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007239{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007240 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007241}
Larry Hastings2f936352014-08-05 14:04:04 +10007242#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007243
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007244
Guido van Rossumad0ee831995-03-01 10:34:45 +00007245#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007246/*[clinic input]
7247os.geteuid
7248
7249Return the current process's effective user id.
7250[clinic start generated code]*/
7251
Larry Hastings2f936352014-08-05 14:04:04 +10007252static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007253os_geteuid_impl(PyObject *module)
7254/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007255{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007256 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007257}
Larry Hastings2f936352014-08-05 14:04:04 +10007258#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007259
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007260
Guido van Rossumad0ee831995-03-01 10:34:45 +00007261#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007262/*[clinic input]
7263os.getgid
7264
7265Return the current process's group id.
7266[clinic start generated code]*/
7267
Larry Hastings2f936352014-08-05 14:04:04 +10007268static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007269os_getgid_impl(PyObject *module)
7270/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007271{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007272 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007273}
Larry Hastings2f936352014-08-05 14:04:04 +10007274#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007276
Berker Peksag39404992016-09-15 20:45:16 +03007277#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10007278/*[clinic input]
7279os.getpid
7280
7281Return the current process id.
7282[clinic start generated code]*/
7283
Larry Hastings2f936352014-08-05 14:04:04 +10007284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007285os_getpid_impl(PyObject *module)
7286/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007287{
Victor Stinner8c62be82010-05-06 00:08:46 +00007288 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00007289}
Berker Peksag39404992016-09-15 20:45:16 +03007290#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007291
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007292#ifdef NGROUPS_MAX
7293#define MAX_GROUPS NGROUPS_MAX
7294#else
7295 /* defined to be 16 on Solaris7, so this should be a small number */
7296#define MAX_GROUPS 64
7297#endif
7298
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007299#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10007300
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007301#ifdef __APPLE__
7302/*[clinic input]
7303os.getgrouplist
7304
7305 user: str
7306 username to lookup
7307 group as basegid: int
7308 base group id of the user
7309 /
7310
7311Returns a list of groups to which a user belongs.
7312[clinic start generated code]*/
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007313
7314static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007315os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
7316/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
7317#else
7318/*[clinic input]
7319os.getgrouplist
7320
7321 user: str
7322 username to lookup
7323 group as basegid: gid_t
7324 base group id of the user
7325 /
7326
7327Returns a list of groups to which a user belongs.
7328[clinic start generated code]*/
7329
7330static PyObject *
7331os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
7332/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
7333#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007334{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007335 int i, ngroups;
7336 PyObject *list;
7337#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007338 int *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007339#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007340 gid_t *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007341#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007342
7343 /*
7344 * NGROUPS_MAX is defined by POSIX.1 as the maximum
7345 * number of supplimental groups a users can belong to.
7346 * We have to increment it by one because
7347 * getgrouplist() returns both the supplemental groups
7348 * and the primary group, i.e. all of the groups the
7349 * user belongs to.
7350 */
7351 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007352
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007353 while (1) {
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007354#ifdef __APPLE__
Victor Stinner8ec73702020-03-23 20:00:57 +01007355 groups = PyMem_New(int, ngroups);
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007356#else
7357 groups = PyMem_New(gid_t, ngroups);
7358#endif
Victor Stinner8ec73702020-03-23 20:00:57 +01007359 if (groups == NULL) {
7360 return PyErr_NoMemory();
7361 }
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007362
7363 int old_ngroups = ngroups;
7364 if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
7365 /* Success */
7366 break;
7367 }
7368
7369 /* getgrouplist() fails if the group list is too small */
7370 PyMem_Free(groups);
7371
7372 if (ngroups > old_ngroups) {
7373 /* If the group list is too small, the glibc implementation of
7374 getgrouplist() sets ngroups to the total number of groups and
7375 returns -1. */
7376 }
7377 else {
7378 /* Double the group list size */
7379 if (ngroups > INT_MAX / 2) {
7380 return PyErr_NoMemory();
7381 }
7382 ngroups *= 2;
7383 }
7384
7385 /* Retry getgrouplist() with a larger group list */
Victor Stinner8ec73702020-03-23 20:00:57 +01007386 }
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007387
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007388#ifdef _Py_MEMORY_SANITIZER
7389 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7390 __msan_unpoison(&ngroups, sizeof(ngroups));
7391 __msan_unpoison(groups, ngroups*sizeof(*groups));
7392#endif
7393
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007394 list = PyList_New(ngroups);
7395 if (list == NULL) {
7396 PyMem_Del(groups);
7397 return NULL;
7398 }
7399
7400 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007401#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007402 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007403#else
7404 PyObject *o = _PyLong_FromGid(groups[i]);
7405#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007406 if (o == NULL) {
7407 Py_DECREF(list);
7408 PyMem_Del(groups);
7409 return NULL;
7410 }
7411 PyList_SET_ITEM(list, i, o);
7412 }
7413
7414 PyMem_Del(groups);
7415
7416 return list;
7417}
Larry Hastings2f936352014-08-05 14:04:04 +10007418#endif /* HAVE_GETGROUPLIST */
7419
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007420
Fred Drakec9680921999-12-13 16:37:25 +00007421#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007422/*[clinic input]
7423os.getgroups
7424
7425Return list of supplemental group IDs for the process.
7426[clinic start generated code]*/
7427
Larry Hastings2f936352014-08-05 14:04:04 +10007428static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007429os_getgroups_impl(PyObject *module)
7430/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007431{
7432 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007433 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007434
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007435 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007436 * This is a helper variable to store the intermediate result when
7437 * that happens.
7438 *
7439 * To keep the code readable the OSX behaviour is unconditional,
7440 * according to the POSIX spec this should be safe on all unix-y
7441 * systems.
7442 */
7443 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007444 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007445
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007446#ifdef __APPLE__
7447 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7448 * there are more groups than can fit in grouplist. Therefore, on OS X
7449 * always first call getgroups with length 0 to get the actual number
7450 * of groups.
7451 */
7452 n = getgroups(0, NULL);
7453 if (n < 0) {
7454 return posix_error();
7455 } else if (n <= MAX_GROUPS) {
7456 /* groups will fit in existing array */
7457 alt_grouplist = grouplist;
7458 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007459 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007460 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007461 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007462 }
7463 }
7464
7465 n = getgroups(n, alt_grouplist);
7466 if (n == -1) {
7467 if (alt_grouplist != grouplist) {
7468 PyMem_Free(alt_grouplist);
7469 }
7470 return posix_error();
7471 }
7472#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007473 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007474 if (n < 0) {
7475 if (errno == EINVAL) {
7476 n = getgroups(0, NULL);
7477 if (n == -1) {
7478 return posix_error();
7479 }
7480 if (n == 0) {
7481 /* Avoid malloc(0) */
7482 alt_grouplist = grouplist;
7483 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007484 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007485 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007486 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007487 }
7488 n = getgroups(n, alt_grouplist);
7489 if (n == -1) {
7490 PyMem_Free(alt_grouplist);
7491 return posix_error();
7492 }
7493 }
7494 } else {
7495 return posix_error();
7496 }
7497 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007498#endif
7499
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007500 result = PyList_New(n);
7501 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007502 int i;
7503 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007504 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007505 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007506 Py_DECREF(result);
7507 result = NULL;
7508 break;
Fred Drakec9680921999-12-13 16:37:25 +00007509 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007510 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007511 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007512 }
7513
7514 if (alt_grouplist != grouplist) {
7515 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007516 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007517
Fred Drakec9680921999-12-13 16:37:25 +00007518 return result;
7519}
Larry Hastings2f936352014-08-05 14:04:04 +10007520#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007521
Antoine Pitroub7572f02009-12-02 20:46:48 +00007522#ifdef HAVE_INITGROUPS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007523#ifdef __APPLE__
7524/*[clinic input]
7525os.initgroups
Antoine Pitroub7572f02009-12-02 20:46:48 +00007526
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007527 username as oname: FSConverter
7528 gid: int
7529 /
7530
7531Initialize the group access list.
7532
7533Call the system initgroups() to initialize the group access list with all of
7534the groups of which the specified username is a member, plus the specified
7535group id.
7536[clinic start generated code]*/
7537
Antoine Pitroub7572f02009-12-02 20:46:48 +00007538static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007539os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7540/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7541#else
7542/*[clinic input]
7543os.initgroups
7544
7545 username as oname: FSConverter
7546 gid: gid_t
7547 /
7548
7549Initialize the group access list.
7550
7551Call the system initgroups() to initialize the group access list with all of
7552the groups of which the specified username is a member, plus the specified
7553group id.
7554[clinic start generated code]*/
7555
7556static PyObject *
7557os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7558/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7559#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007560{
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007561 const char *username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007562
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007563 if (initgroups(username, gid) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007564 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007565
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007566 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007567}
Larry Hastings2f936352014-08-05 14:04:04 +10007568#endif /* HAVE_INITGROUPS */
7569
Antoine Pitroub7572f02009-12-02 20:46:48 +00007570
Martin v. Löwis606edc12002-06-13 21:09:11 +00007571#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007572/*[clinic input]
7573os.getpgid
7574
7575 pid: pid_t
7576
7577Call the system call getpgid(), and return the result.
7578[clinic start generated code]*/
7579
Larry Hastings2f936352014-08-05 14:04:04 +10007580static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007581os_getpgid_impl(PyObject *module, pid_t pid)
7582/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007583{
7584 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007585 if (pgid < 0)
7586 return posix_error();
7587 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007588}
7589#endif /* HAVE_GETPGID */
7590
7591
Guido van Rossumb6775db1994-08-01 11:34:53 +00007592#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007593/*[clinic input]
7594os.getpgrp
7595
7596Return the current process group id.
7597[clinic start generated code]*/
7598
Larry Hastings2f936352014-08-05 14:04:04 +10007599static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007600os_getpgrp_impl(PyObject *module)
7601/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007602{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007603#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007605#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007606 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007607#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007608}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007609#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007610
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007611
Guido van Rossumb6775db1994-08-01 11:34:53 +00007612#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007613/*[clinic input]
7614os.setpgrp
7615
7616Make the current process the leader of its process group.
7617[clinic start generated code]*/
7618
Larry Hastings2f936352014-08-05 14:04:04 +10007619static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007620os_setpgrp_impl(PyObject *module)
7621/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007622{
Guido van Rossum64933891994-10-20 21:56:42 +00007623#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007624 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007625#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007626 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007627#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007628 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007629 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007630}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007631#endif /* HAVE_SETPGRP */
7632
Guido van Rossumad0ee831995-03-01 10:34:45 +00007633#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007634
7635#ifdef MS_WINDOWS
7636#include <tlhelp32.h>
7637
7638static PyObject*
7639win32_getppid()
7640{
7641 HANDLE snapshot;
7642 pid_t mypid;
7643 PyObject* result = NULL;
7644 BOOL have_record;
7645 PROCESSENTRY32 pe;
7646
7647 mypid = getpid(); /* This function never fails */
7648
7649 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7650 if (snapshot == INVALID_HANDLE_VALUE)
7651 return PyErr_SetFromWindowsErr(GetLastError());
7652
7653 pe.dwSize = sizeof(pe);
7654 have_record = Process32First(snapshot, &pe);
7655 while (have_record) {
7656 if (mypid == (pid_t)pe.th32ProcessID) {
7657 /* We could cache the ulong value in a static variable. */
7658 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7659 break;
7660 }
7661
7662 have_record = Process32Next(snapshot, &pe);
7663 }
7664
7665 /* If our loop exits and our pid was not found (result will be NULL)
7666 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7667 * error anyway, so let's raise it. */
7668 if (!result)
7669 result = PyErr_SetFromWindowsErr(GetLastError());
7670
7671 CloseHandle(snapshot);
7672
7673 return result;
7674}
7675#endif /*MS_WINDOWS*/
7676
Larry Hastings2f936352014-08-05 14:04:04 +10007677
7678/*[clinic input]
7679os.getppid
7680
7681Return the parent's process id.
7682
7683If the parent process has already exited, Windows machines will still
7684return its id; others systems will return the id of the 'init' process (1).
7685[clinic start generated code]*/
7686
Larry Hastings2f936352014-08-05 14:04:04 +10007687static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007688os_getppid_impl(PyObject *module)
7689/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007690{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007691#ifdef MS_WINDOWS
7692 return win32_getppid();
7693#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007694 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007695#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007696}
7697#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007698
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007699
Fred Drake12c6e2d1999-12-14 21:25:03 +00007700#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007701/*[clinic input]
7702os.getlogin
7703
7704Return the actual login name.
7705[clinic start generated code]*/
7706
Larry Hastings2f936352014-08-05 14:04:04 +10007707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007708os_getlogin_impl(PyObject *module)
7709/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007710{
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007712#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007713 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007714 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007715
7716 if (GetUserNameW(user_name, &num_chars)) {
7717 /* num_chars is the number of unicode chars plus null terminator */
7718 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007719 }
7720 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007721 result = PyErr_SetFromWindowsErr(GetLastError());
7722#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007723 char *name;
7724 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007725
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 errno = 0;
7727 name = getlogin();
7728 if (name == NULL) {
7729 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007730 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007731 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007732 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007733 }
7734 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007735 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007736 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007737#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007738 return result;
7739}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007740#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007741
Larry Hastings2f936352014-08-05 14:04:04 +10007742
Guido van Rossumad0ee831995-03-01 10:34:45 +00007743#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007744/*[clinic input]
7745os.getuid
7746
7747Return the current process's user id.
7748[clinic start generated code]*/
7749
Larry Hastings2f936352014-08-05 14:04:04 +10007750static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007751os_getuid_impl(PyObject *module)
7752/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007753{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007754 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007755}
Larry Hastings2f936352014-08-05 14:04:04 +10007756#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007757
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007758
Brian Curtineb24d742010-04-12 17:16:38 +00007759#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007760#define HAVE_KILL
7761#endif /* MS_WINDOWS */
7762
7763#ifdef HAVE_KILL
7764/*[clinic input]
7765os.kill
7766
7767 pid: pid_t
7768 signal: Py_ssize_t
7769 /
7770
7771Kill a process with a signal.
7772[clinic start generated code]*/
7773
Larry Hastings2f936352014-08-05 14:04:04 +10007774static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007775os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7776/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007777{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007778 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7779 return NULL;
7780 }
7781#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007782 if (kill(pid, (int)signal) == -1)
7783 return posix_error();
7784 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007785#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007786 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007787 DWORD sig = (DWORD)signal;
7788 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007790
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 /* Console processes which share a common console can be sent CTRL+C or
7792 CTRL+BREAK events, provided they handle said events. */
7793 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007794 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007795 err = GetLastError();
7796 PyErr_SetFromWindowsErr(err);
7797 }
7798 else
7799 Py_RETURN_NONE;
7800 }
Brian Curtineb24d742010-04-12 17:16:38 +00007801
Victor Stinner8c62be82010-05-06 00:08:46 +00007802 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7803 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007804 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007805 if (handle == NULL) {
7806 err = GetLastError();
7807 return PyErr_SetFromWindowsErr(err);
7808 }
Brian Curtineb24d742010-04-12 17:16:38 +00007809
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 if (TerminateProcess(handle, sig) == 0) {
7811 err = GetLastError();
7812 result = PyErr_SetFromWindowsErr(err);
7813 } else {
7814 Py_INCREF(Py_None);
7815 result = Py_None;
7816 }
Brian Curtineb24d742010-04-12 17:16:38 +00007817
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 CloseHandle(handle);
7819 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007820#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007821}
Larry Hastings2f936352014-08-05 14:04:04 +10007822#endif /* HAVE_KILL */
7823
7824
7825#ifdef HAVE_KILLPG
7826/*[clinic input]
7827os.killpg
7828
7829 pgid: pid_t
7830 signal: int
7831 /
7832
7833Kill a process group with a signal.
7834[clinic start generated code]*/
7835
Larry Hastings2f936352014-08-05 14:04:04 +10007836static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007837os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7838/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007839{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007840 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7841 return NULL;
7842 }
Larry Hastings2f936352014-08-05 14:04:04 +10007843 /* XXX some man pages make the `pgid` parameter an int, others
7844 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7845 take the same type. Moreover, pid_t is always at least as wide as
7846 int (else compilation of this module fails), which is safe. */
7847 if (killpg(pgid, signal) == -1)
7848 return posix_error();
7849 Py_RETURN_NONE;
7850}
7851#endif /* HAVE_KILLPG */
7852
Brian Curtineb24d742010-04-12 17:16:38 +00007853
Guido van Rossumc0125471996-06-28 18:55:32 +00007854#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007855#ifdef HAVE_SYS_LOCK_H
7856#include <sys/lock.h>
7857#endif
7858
Larry Hastings2f936352014-08-05 14:04:04 +10007859/*[clinic input]
7860os.plock
7861 op: int
7862 /
7863
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007864Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007865[clinic start generated code]*/
7866
Larry Hastings2f936352014-08-05 14:04:04 +10007867static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007868os_plock_impl(PyObject *module, int op)
7869/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007870{
Victor Stinner8c62be82010-05-06 00:08:46 +00007871 if (plock(op) == -1)
7872 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007873 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007874}
Larry Hastings2f936352014-08-05 14:04:04 +10007875#endif /* HAVE_PLOCK */
7876
Guido van Rossumc0125471996-06-28 18:55:32 +00007877
Guido van Rossumb6775db1994-08-01 11:34:53 +00007878#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007879/*[clinic input]
7880os.setuid
7881
7882 uid: uid_t
7883 /
7884
7885Set the current process's user id.
7886[clinic start generated code]*/
7887
Larry Hastings2f936352014-08-05 14:04:04 +10007888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007889os_setuid_impl(PyObject *module, uid_t uid)
7890/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007891{
Victor Stinner8c62be82010-05-06 00:08:46 +00007892 if (setuid(uid) < 0)
7893 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007894 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007895}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007896#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007898
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007899#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007900/*[clinic input]
7901os.seteuid
7902
7903 euid: uid_t
7904 /
7905
7906Set the current process's effective user id.
7907[clinic start generated code]*/
7908
Larry Hastings2f936352014-08-05 14:04:04 +10007909static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007910os_seteuid_impl(PyObject *module, uid_t euid)
7911/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007912{
7913 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007914 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007915 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007916}
7917#endif /* HAVE_SETEUID */
7918
Larry Hastings2f936352014-08-05 14:04:04 +10007919
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007920#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007921/*[clinic input]
7922os.setegid
7923
7924 egid: gid_t
7925 /
7926
7927Set the current process's effective group id.
7928[clinic start generated code]*/
7929
Larry Hastings2f936352014-08-05 14:04:04 +10007930static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007931os_setegid_impl(PyObject *module, gid_t egid)
7932/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007933{
7934 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007935 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007936 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007937}
7938#endif /* HAVE_SETEGID */
7939
Larry Hastings2f936352014-08-05 14:04:04 +10007940
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007941#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007942/*[clinic input]
7943os.setreuid
7944
7945 ruid: uid_t
7946 euid: uid_t
7947 /
7948
7949Set the current process's real and effective user ids.
7950[clinic start generated code]*/
7951
Larry Hastings2f936352014-08-05 14:04:04 +10007952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007953os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7954/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007955{
Victor Stinner8c62be82010-05-06 00:08:46 +00007956 if (setreuid(ruid, euid) < 0) {
7957 return posix_error();
7958 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007959 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007961}
7962#endif /* HAVE_SETREUID */
7963
Larry Hastings2f936352014-08-05 14:04:04 +10007964
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007965#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007966/*[clinic input]
7967os.setregid
7968
7969 rgid: gid_t
7970 egid: gid_t
7971 /
7972
7973Set the current process's real and effective group ids.
7974[clinic start generated code]*/
7975
Larry Hastings2f936352014-08-05 14:04:04 +10007976static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007977os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7978/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007979{
7980 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007982 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007983}
7984#endif /* HAVE_SETREGID */
7985
Larry Hastings2f936352014-08-05 14:04:04 +10007986
Guido van Rossumb6775db1994-08-01 11:34:53 +00007987#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007988/*[clinic input]
7989os.setgid
7990 gid: gid_t
7991 /
7992
7993Set the current process's group id.
7994[clinic start generated code]*/
7995
Larry Hastings2f936352014-08-05 14:04:04 +10007996static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007997os_setgid_impl(PyObject *module, gid_t gid)
7998/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007999{
Victor Stinner8c62be82010-05-06 00:08:46 +00008000 if (setgid(gid) < 0)
8001 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008002 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008003}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008004#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008005
Larry Hastings2f936352014-08-05 14:04:04 +10008006
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008007#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10008008/*[clinic input]
8009os.setgroups
8010
8011 groups: object
8012 /
8013
8014Set the groups of the current process to list.
8015[clinic start generated code]*/
8016
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008017static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008018os_setgroups(PyObject *module, PyObject *groups)
8019/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008020{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008021 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00008022 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00008023
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 if (!PySequence_Check(groups)) {
8025 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
8026 return NULL;
8027 }
8028 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008029 if (len < 0) {
8030 return NULL;
8031 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 if (len > MAX_GROUPS) {
8033 PyErr_SetString(PyExc_ValueError, "too many groups");
8034 return NULL;
8035 }
8036 for(i = 0; i < len; i++) {
8037 PyObject *elem;
8038 elem = PySequence_GetItem(groups, i);
8039 if (!elem)
8040 return NULL;
8041 if (!PyLong_Check(elem)) {
8042 PyErr_SetString(PyExc_TypeError,
8043 "groups must be integers");
8044 Py_DECREF(elem);
8045 return NULL;
8046 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008047 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008048 Py_DECREF(elem);
8049 return NULL;
8050 }
8051 }
8052 Py_DECREF(elem);
8053 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008054
Victor Stinner8c62be82010-05-06 00:08:46 +00008055 if (setgroups(len, grouplist) < 0)
8056 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008057 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008058}
8059#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008060
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008061#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
8062static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008063wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008064{
Victor Stinner8c62be82010-05-06 00:08:46 +00008065 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08008066 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008067
Victor Stinner8c62be82010-05-06 00:08:46 +00008068 if (pid == -1)
8069 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008070
Zackery Spytz682107c2019-09-09 09:48:32 -06008071 // If wait succeeded but no child was ready to report status, ru will not
8072 // have been populated.
8073 if (pid == 0) {
8074 memset(ru, 0, sizeof(*ru));
8075 }
8076
Eddie Elizondob3966632019-11-05 07:16:14 -08008077 PyObject *m = PyImport_ImportModuleNoBlock("resource");
8078 if (m == NULL)
8079 return NULL;
Victor Stinner1c2fa782020-05-10 11:05:29 +02008080 struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08008081 Py_DECREF(m);
8082 if (struct_rusage == NULL)
8083 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008084
Victor Stinner8c62be82010-05-06 00:08:46 +00008085 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
8086 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08008087 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00008088 if (!result)
8089 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008090
8091#ifndef doubletime
8092#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
8093#endif
8094
Victor Stinner8c62be82010-05-06 00:08:46 +00008095 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008096 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00008097 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008098 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008099#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00008100 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
8101 SET_INT(result, 2, ru->ru_maxrss);
8102 SET_INT(result, 3, ru->ru_ixrss);
8103 SET_INT(result, 4, ru->ru_idrss);
8104 SET_INT(result, 5, ru->ru_isrss);
8105 SET_INT(result, 6, ru->ru_minflt);
8106 SET_INT(result, 7, ru->ru_majflt);
8107 SET_INT(result, 8, ru->ru_nswap);
8108 SET_INT(result, 9, ru->ru_inblock);
8109 SET_INT(result, 10, ru->ru_oublock);
8110 SET_INT(result, 11, ru->ru_msgsnd);
8111 SET_INT(result, 12, ru->ru_msgrcv);
8112 SET_INT(result, 13, ru->ru_nsignals);
8113 SET_INT(result, 14, ru->ru_nvcsw);
8114 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008115#undef SET_INT
8116
Victor Stinner8c62be82010-05-06 00:08:46 +00008117 if (PyErr_Occurred()) {
8118 Py_DECREF(result);
8119 return NULL;
8120 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008121
Victor Stinner8c62be82010-05-06 00:08:46 +00008122 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008123}
8124#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
8125
Larry Hastings2f936352014-08-05 14:04:04 +10008126
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008127#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10008128/*[clinic input]
8129os.wait3
8130
8131 options: int
8132Wait for completion of a child process.
8133
8134Returns a tuple of information about the child process:
8135 (pid, status, rusage)
8136[clinic start generated code]*/
8137
Larry Hastings2f936352014-08-05 14:04:04 +10008138static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008139os_wait3_impl(PyObject *module, int options)
8140/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008141{
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008143 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008144 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008145 WAIT_TYPE status;
8146 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008147
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008148 do {
8149 Py_BEGIN_ALLOW_THREADS
8150 pid = wait3(&status, options, &ru);
8151 Py_END_ALLOW_THREADS
8152 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8153 if (pid < 0)
8154 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008155
Victor Stinner1c2fa782020-05-10 11:05:29 +02008156 return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008157}
8158#endif /* HAVE_WAIT3 */
8159
Larry Hastings2f936352014-08-05 14:04:04 +10008160
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008161#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10008162/*[clinic input]
8163
8164os.wait4
8165
8166 pid: pid_t
8167 options: int
8168
8169Wait for completion of a specific child process.
8170
8171Returns a tuple of information about the child process:
8172 (pid, status, rusage)
8173[clinic start generated code]*/
8174
Larry Hastings2f936352014-08-05 14:04:04 +10008175static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008176os_wait4_impl(PyObject *module, pid_t pid, int options)
8177/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008178{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008179 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008180 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008181 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008182 WAIT_TYPE status;
8183 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008184
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008185 do {
8186 Py_BEGIN_ALLOW_THREADS
8187 res = wait4(pid, &status, options, &ru);
8188 Py_END_ALLOW_THREADS
8189 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8190 if (res < 0)
8191 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008192
Victor Stinner1c2fa782020-05-10 11:05:29 +02008193 return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008194}
8195#endif /* HAVE_WAIT4 */
8196
Larry Hastings2f936352014-08-05 14:04:04 +10008197
Ross Lagerwall7807c352011-03-17 20:20:30 +02008198#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10008199/*[clinic input]
8200os.waitid
8201
8202 idtype: idtype_t
8203 Must be one of be P_PID, P_PGID or P_ALL.
8204 id: id_t
8205 The id to wait on.
8206 options: int
8207 Constructed from the ORing of one or more of WEXITED, WSTOPPED
8208 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
8209 /
8210
8211Returns the result of waiting for a process or processes.
8212
8213Returns either waitid_result or None if WNOHANG is specified and there are
8214no children in a waitable state.
8215[clinic start generated code]*/
8216
Larry Hastings2f936352014-08-05 14:04:04 +10008217static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008218os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
8219/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008220{
8221 PyObject *result;
8222 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008223 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008224 siginfo_t si;
8225 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008226
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008227 do {
8228 Py_BEGIN_ALLOW_THREADS
8229 res = waitid(idtype, id, &si, options);
8230 Py_END_ALLOW_THREADS
8231 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8232 if (res < 0)
8233 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008234
8235 if (si.si_pid == 0)
8236 Py_RETURN_NONE;
8237
Hai Shif707d942020-03-16 21:15:01 +08008238 PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008239 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008240 if (!result)
8241 return NULL;
8242
8243 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008244 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008245 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
8246 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
8247 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
8248 if (PyErr_Occurred()) {
8249 Py_DECREF(result);
8250 return NULL;
8251 }
8252
8253 return result;
8254}
Larry Hastings2f936352014-08-05 14:04:04 +10008255#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008256
Larry Hastings2f936352014-08-05 14:04:04 +10008257
8258#if defined(HAVE_WAITPID)
8259/*[clinic input]
8260os.waitpid
8261 pid: pid_t
8262 options: int
8263 /
8264
8265Wait for completion of a given child process.
8266
8267Returns a tuple of information regarding the child process:
8268 (pid, status)
8269
8270The options argument is ignored on Windows.
8271[clinic start generated code]*/
8272
Larry Hastings2f936352014-08-05 14:04:04 +10008273static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008274os_waitpid_impl(PyObject *module, pid_t pid, int options)
8275/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008276{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008277 pid_t res;
8278 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008279 WAIT_TYPE status;
8280 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008281
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008282 do {
8283 Py_BEGIN_ALLOW_THREADS
8284 res = waitpid(pid, &status, options);
8285 Py_END_ALLOW_THREADS
8286 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8287 if (res < 0)
8288 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008289
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008290 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00008291}
Tim Petersab034fa2002-02-01 11:27:43 +00008292#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00008293/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10008294/*[clinic input]
8295os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07008296 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10008297 options: int
8298 /
8299
8300Wait for completion of a given process.
8301
8302Returns a tuple of information regarding the process:
8303 (pid, status << 8)
8304
8305The options argument is ignored on Windows.
8306[clinic start generated code]*/
8307
Larry Hastings2f936352014-08-05 14:04:04 +10008308static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07008309os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07008310/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008311{
8312 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07008313 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008314 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008315
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008316 do {
8317 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08008318 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008319 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08008320 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008321 Py_END_ALLOW_THREADS
8322 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008323 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008324 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008325
Victor Stinner9bee32b2020-04-22 16:30:35 +02008326 unsigned long long ustatus = (unsigned int)status;
8327
Victor Stinner8c62be82010-05-06 00:08:46 +00008328 /* shift the status left a byte so this is more like the POSIX waitpid */
Victor Stinner9bee32b2020-04-22 16:30:35 +02008329 return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00008330}
Larry Hastings2f936352014-08-05 14:04:04 +10008331#endif
8332
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008333
Guido van Rossumad0ee831995-03-01 10:34:45 +00008334#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10008335/*[clinic input]
8336os.wait
8337
8338Wait for completion of a child process.
8339
8340Returns a tuple of information about the child process:
8341 (pid, status)
8342[clinic start generated code]*/
8343
Larry Hastings2f936352014-08-05 14:04:04 +10008344static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008345os_wait_impl(PyObject *module)
8346/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00008347{
Victor Stinner8c62be82010-05-06 00:08:46 +00008348 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008349 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008350 WAIT_TYPE status;
8351 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00008352
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008353 do {
8354 Py_BEGIN_ALLOW_THREADS
8355 pid = wait(&status);
8356 Py_END_ALLOW_THREADS
8357 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8358 if (pid < 0)
8359 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008360
Victor Stinner8c62be82010-05-06 00:08:46 +00008361 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00008362}
Larry Hastings2f936352014-08-05 14:04:04 +10008363#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008364
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08008365#if defined(__linux__) && defined(__NR_pidfd_open)
8366/*[clinic input]
8367os.pidfd_open
8368 pid: pid_t
8369 flags: unsigned_int = 0
8370
8371Return a file descriptor referring to the process *pid*.
8372
8373The descriptor can be used to perform process management without races and
8374signals.
8375[clinic start generated code]*/
8376
8377static PyObject *
8378os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8379/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8380{
8381 int fd = syscall(__NR_pidfd_open, pid, flags);
8382 if (fd < 0) {
8383 return posix_error();
8384 }
8385 return PyLong_FromLong(fd);
8386}
8387#endif
8388
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008389
Larry Hastings9cf065c2012-06-22 16:30:09 -07008390#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008391/*[clinic input]
8392os.readlink
8393
8394 path: path_t
8395 *
8396 dir_fd: dir_fd(requires='readlinkat') = None
8397
8398Return a string representing the path to which the symbolic link points.
8399
8400If dir_fd is not None, it should be a file descriptor open to a directory,
8401and path should be relative; path will then be relative to that directory.
8402
8403dir_fd may not be implemented on your platform. If it is unavailable,
8404using it will raise a NotImplementedError.
8405[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008406
Barry Warsaw53699e91996-12-10 23:23:01 +00008407static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008408os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8409/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008410{
Berker Peksage0b5b202018-08-15 13:03:41 +03008411#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008412 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008413 ssize_t length;
Ronald Oussorene8b1c032020-11-22 11:18:40 +01008414#ifdef HAVE_READLINKAT
8415 int readlinkat_unavailable = 0;
8416#endif
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008417
8418 Py_BEGIN_ALLOW_THREADS
8419#ifdef HAVE_READLINKAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +01008420 if (dir_fd != DEFAULT_DIR_FD) {
8421 if (HAVE_READLINKAT_RUNTIME) {
8422 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8423 } else {
8424 readlinkat_unavailable = 1;
8425 }
8426 } else
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008427#endif
8428 length = readlink(path->narrow, buffer, MAXPATHLEN);
8429 Py_END_ALLOW_THREADS
8430
Ronald Oussorene8b1c032020-11-22 11:18:40 +01008431#ifdef HAVE_READLINKAT
8432 if (readlinkat_unavailable) {
8433 argument_unavailable_error(NULL, "dir_fd");
8434 return NULL;
8435 }
8436#endif
8437
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008438 if (length < 0) {
8439 return path_error(path);
8440 }
8441 buffer[length] = '\0';
8442
8443 if (PyUnicode_Check(path->object))
8444 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8445 else
8446 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008447#elif defined(MS_WINDOWS)
8448 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008449 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008450 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008451 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8452 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008453 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008454
Larry Hastings2f936352014-08-05 14:04:04 +10008455 /* First get a handle to the reparse point */
8456 Py_BEGIN_ALLOW_THREADS
8457 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008458 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008459 0,
8460 0,
8461 0,
8462 OPEN_EXISTING,
8463 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8464 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008465 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8466 /* New call DeviceIoControl to read the reparse point */
8467 io_result = DeviceIoControl(
8468 reparse_point_handle,
8469 FSCTL_GET_REPARSE_POINT,
8470 0, 0, /* in buffer */
8471 target_buffer, sizeof(target_buffer),
8472 &n_bytes_returned,
8473 0 /* we're not using OVERLAPPED_IO */
8474 );
8475 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008476 }
Larry Hastings2f936352014-08-05 14:04:04 +10008477 Py_END_ALLOW_THREADS
8478
Berker Peksage0b5b202018-08-15 13:03:41 +03008479 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008480 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008481 }
Larry Hastings2f936352014-08-05 14:04:04 +10008482
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008483 wchar_t *name = NULL;
8484 Py_ssize_t nameLen = 0;
8485 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008486 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008487 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8488 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8489 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008490 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008491 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8492 {
8493 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8494 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8495 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8496 }
8497 else
8498 {
8499 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8500 }
8501 if (name) {
8502 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8503 /* Our buffer is mutable, so this is okay */
8504 name[1] = L'\\';
8505 }
8506 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008507 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008508 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8509 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008510 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008511 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008512#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008513}
Berker Peksage0b5b202018-08-15 13:03:41 +03008514#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008515
Larry Hastings9cf065c2012-06-22 16:30:09 -07008516#if defined(MS_WINDOWS)
8517
Steve Dower6921e732018-03-05 14:26:08 -08008518/* Remove the last portion of the path - return 0 on success */
8519static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008520_dirnameW(WCHAR *path)
8521{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008522 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008523 size_t length = wcsnlen_s(path, MAX_PATH);
8524 if (length == MAX_PATH) {
8525 return -1;
8526 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008527
8528 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008529 for(ptr = path + length; ptr != path; ptr--) {
8530 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008531 break;
Steve Dower6921e732018-03-05 14:26:08 -08008532 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008533 }
8534 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008535 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008536}
8537
Minmin Gong7f21c9a2020-05-18 09:17:19 -07008538#endif
8539
8540#ifdef HAVE_SYMLINK
8541
8542#if defined(MS_WINDOWS)
8543
Victor Stinner31b3b922013-06-05 01:49:17 +02008544/* Is this path absolute? */
8545static int
8546_is_absW(const WCHAR *path)
8547{
Steve Dower6921e732018-03-05 14:26:08 -08008548 return path[0] == L'\\' || path[0] == L'/' ||
8549 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008550}
8551
Steve Dower6921e732018-03-05 14:26:08 -08008552/* join root and rest with a backslash - return 0 on success */
8553static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008554_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8555{
Victor Stinner31b3b922013-06-05 01:49:17 +02008556 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008557 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008558 }
8559
Steve Dower6921e732018-03-05 14:26:08 -08008560 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8561 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008562 }
Steve Dower6921e732018-03-05 14:26:08 -08008563
8564 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8565 return -1;
8566 }
8567
8568 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008569}
8570
Victor Stinner31b3b922013-06-05 01:49:17 +02008571/* Return True if the path at src relative to dest is a directory */
8572static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008573_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008574{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008575 WIN32_FILE_ATTRIBUTE_DATA src_info;
8576 WCHAR dest_parent[MAX_PATH];
8577 WCHAR src_resolved[MAX_PATH] = L"";
8578
8579 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008580 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8581 _dirnameW(dest_parent)) {
8582 return 0;
8583 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008584 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008585 if (_joinW(src_resolved, dest_parent, src)) {
8586 return 0;
8587 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008588 return (
8589 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8590 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8591 );
8592}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008593#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008594
Larry Hastings2f936352014-08-05 14:04:04 +10008595
8596/*[clinic input]
8597os.symlink
8598 src: path_t
8599 dst: path_t
8600 target_is_directory: bool = False
8601 *
8602 dir_fd: dir_fd(requires='symlinkat')=None
8603
8604# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8605
8606Create a symbolic link pointing to src named dst.
8607
8608target_is_directory is required on Windows if the target is to be
8609 interpreted as a directory. (On Windows, symlink requires
8610 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8611 target_is_directory is ignored on non-Windows platforms.
8612
8613If dir_fd is not None, it should be a file descriptor open to a directory,
8614 and path should be relative; path will then be relative to that directory.
8615dir_fd may not be implemented on your platform.
8616 If it is unavailable, using it will raise a NotImplementedError.
8617
8618[clinic start generated code]*/
8619
Larry Hastings2f936352014-08-05 14:04:04 +10008620static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008621os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008622 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008623/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008624{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008625#ifdef MS_WINDOWS
8626 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008627 DWORD flags = 0;
8628
8629 /* Assumed true, set to false if detected to not be available. */
8630 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008631#else
8632 int result;
Ronald Oussorene8b1c032020-11-22 11:18:40 +01008633#ifdef HAVE_SYMLINKAT
8634 int symlinkat_unavailable = 0;
8635#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07008636#endif
8637
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008638 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8639 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8640 return NULL;
8641 }
8642
Larry Hastings9cf065c2012-06-22 16:30:09 -07008643#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008644
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008645 if (windows_has_symlink_unprivileged_flag) {
8646 /* Allow non-admin symlinks if system allows it. */
8647 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8648 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008649
Larry Hastings9cf065c2012-06-22 16:30:09 -07008650 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008651 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008652 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8653 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8654 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8655 }
8656
8657 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008658 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008659 Py_END_ALLOW_THREADS
8660
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008661 if (windows_has_symlink_unprivileged_flag && !result &&
8662 ERROR_INVALID_PARAMETER == GetLastError()) {
8663
8664 Py_BEGIN_ALLOW_THREADS
8665 _Py_BEGIN_SUPPRESS_IPH
8666 /* This error might be caused by
8667 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8668 Try again, and update windows_has_symlink_unprivileged_flag if we
8669 are successful this time.
8670
8671 NOTE: There is a risk of a race condition here if there are other
8672 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8673 another process (or thread) changes that condition in between our
8674 calls to CreateSymbolicLink.
8675 */
8676 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8677 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8678 _Py_END_SUPPRESS_IPH
8679 Py_END_ALLOW_THREADS
8680
8681 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8682 windows_has_symlink_unprivileged_flag = FALSE;
8683 }
8684 }
8685
Larry Hastings2f936352014-08-05 14:04:04 +10008686 if (!result)
8687 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008688
8689#else
8690
Steve Dower6921e732018-03-05 14:26:08 -08008691 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8692 PyErr_SetString(PyExc_ValueError,
8693 "symlink: src and dst must be the same type");
8694 return NULL;
8695 }
8696
Larry Hastings9cf065c2012-06-22 16:30:09 -07008697 Py_BEGIN_ALLOW_THREADS
Ronald Oussorene8b1c032020-11-22 11:18:40 +01008698#ifdef HAVE_SYMLINKAT
8699 if (dir_fd != DEFAULT_DIR_FD) {
8700 if (HAVE_SYMLINKAT_RUNTIME) {
8701 result = symlinkat(src->narrow, dir_fd, dst->narrow);
8702 } else {
8703 symlinkat_unavailable = 1;
8704 }
8705 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008706#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008707 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008708 Py_END_ALLOW_THREADS
8709
Ronald Oussorene8b1c032020-11-22 11:18:40 +01008710#ifdef HAVE_SYMLINKAT
8711 if (symlinkat_unavailable) {
8712 argument_unavailable_error(NULL, "dir_fd");
8713 return NULL;
8714 }
8715#endif
8716
Larry Hastings2f936352014-08-05 14:04:04 +10008717 if (result)
8718 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008719#endif
8720
Larry Hastings2f936352014-08-05 14:04:04 +10008721 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008722}
8723#endif /* HAVE_SYMLINK */
8724
Larry Hastings9cf065c2012-06-22 16:30:09 -07008725
Brian Curtind40e6f72010-07-08 21:39:08 +00008726
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008727
Larry Hastings605a62d2012-06-24 04:33:36 -07008728static PyStructSequence_Field times_result_fields[] = {
8729 {"user", "user time"},
8730 {"system", "system time"},
8731 {"children_user", "user time of children"},
8732 {"children_system", "system time of children"},
8733 {"elapsed", "elapsed time since an arbitrary point in the past"},
8734 {NULL}
8735};
8736
8737PyDoc_STRVAR(times_result__doc__,
8738"times_result: Result from os.times().\n\n\
8739This object may be accessed either as a tuple of\n\
8740 (user, system, children_user, children_system, elapsed),\n\
8741or via the attributes user, system, children_user, children_system,\n\
8742and elapsed.\n\
8743\n\
8744See os.times for more information.");
8745
8746static PyStructSequence_Desc times_result_desc = {
8747 "times_result", /* name */
8748 times_result__doc__, /* doc */
8749 times_result_fields,
8750 5
8751};
8752
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008753#ifdef MS_WINDOWS
8754#define HAVE_TIMES /* mandatory, for the method table */
8755#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008756
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008757#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008758
8759static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008760build_times_result(PyObject *module, double user, double system,
Larry Hastings605a62d2012-06-24 04:33:36 -07008761 double children_user, double children_system,
8762 double elapsed)
8763{
Victor Stinner1c2fa782020-05-10 11:05:29 +02008764 PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008765 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008766 if (value == NULL)
8767 return NULL;
8768
8769#define SET(i, field) \
8770 { \
8771 PyObject *o = PyFloat_FromDouble(field); \
8772 if (!o) { \
8773 Py_DECREF(value); \
8774 return NULL; \
8775 } \
8776 PyStructSequence_SET_ITEM(value, i, o); \
8777 } \
8778
8779 SET(0, user);
8780 SET(1, system);
8781 SET(2, children_user);
8782 SET(3, children_system);
8783 SET(4, elapsed);
8784
8785#undef SET
8786
8787 return value;
8788}
8789
Larry Hastings605a62d2012-06-24 04:33:36 -07008790
Larry Hastings2f936352014-08-05 14:04:04 +10008791#ifndef MS_WINDOWS
8792#define NEED_TICKS_PER_SECOND
8793static long ticks_per_second = -1;
8794#endif /* MS_WINDOWS */
8795
8796/*[clinic input]
8797os.times
8798
8799Return a collection containing process timing information.
8800
8801The object returned behaves like a named tuple with these fields:
8802 (utime, stime, cutime, cstime, elapsed_time)
8803All fields are floating point numbers.
8804[clinic start generated code]*/
8805
Larry Hastings2f936352014-08-05 14:04:04 +10008806static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008807os_times_impl(PyObject *module)
8808/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008809#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008810{
Victor Stinner8c62be82010-05-06 00:08:46 +00008811 FILETIME create, exit, kernel, user;
8812 HANDLE hProc;
8813 hProc = GetCurrentProcess();
8814 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8815 /* The fields of a FILETIME structure are the hi and lo part
8816 of a 64-bit value expressed in 100 nanosecond units.
8817 1e7 is one second in such units; 1e-7 the inverse.
8818 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8819 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02008820 return build_times_result(module,
Victor Stinner8c62be82010-05-06 00:08:46 +00008821 (double)(user.dwHighDateTime*429.4967296 +
8822 user.dwLowDateTime*1e-7),
8823 (double)(kernel.dwHighDateTime*429.4967296 +
8824 kernel.dwLowDateTime*1e-7),
8825 (double)0,
8826 (double)0,
8827 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008828}
Larry Hastings2f936352014-08-05 14:04:04 +10008829#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008830{
Larry Hastings2f936352014-08-05 14:04:04 +10008831
8832
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008833 struct tms t;
8834 clock_t c;
8835 errno = 0;
8836 c = times(&t);
8837 if (c == (clock_t) -1)
8838 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02008839 return build_times_result(module,
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008840 (double)t.tms_utime / ticks_per_second,
8841 (double)t.tms_stime / ticks_per_second,
8842 (double)t.tms_cutime / ticks_per_second,
8843 (double)t.tms_cstime / ticks_per_second,
8844 (double)c / ticks_per_second);
8845}
Larry Hastings2f936352014-08-05 14:04:04 +10008846#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008847#endif /* HAVE_TIMES */
8848
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008849
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008850#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008851/*[clinic input]
8852os.getsid
8853
8854 pid: pid_t
8855 /
8856
8857Call the system call getsid(pid) and return the result.
8858[clinic start generated code]*/
8859
Larry Hastings2f936352014-08-05 14:04:04 +10008860static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008861os_getsid_impl(PyObject *module, pid_t pid)
8862/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008863{
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008865 sid = getsid(pid);
8866 if (sid < 0)
8867 return posix_error();
8868 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008869}
8870#endif /* HAVE_GETSID */
8871
8872
Guido van Rossumb6775db1994-08-01 11:34:53 +00008873#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008874/*[clinic input]
8875os.setsid
8876
8877Call the system call setsid().
8878[clinic start generated code]*/
8879
Larry Hastings2f936352014-08-05 14:04:04 +10008880static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008881os_setsid_impl(PyObject *module)
8882/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008883{
Victor Stinner8c62be82010-05-06 00:08:46 +00008884 if (setsid() < 0)
8885 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008886 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008887}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008888#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008889
Larry Hastings2f936352014-08-05 14:04:04 +10008890
Guido van Rossumb6775db1994-08-01 11:34:53 +00008891#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008892/*[clinic input]
8893os.setpgid
8894
8895 pid: pid_t
8896 pgrp: pid_t
8897 /
8898
8899Call the system call setpgid(pid, pgrp).
8900[clinic start generated code]*/
8901
Larry Hastings2f936352014-08-05 14:04:04 +10008902static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008903os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8904/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008905{
Victor Stinner8c62be82010-05-06 00:08:46 +00008906 if (setpgid(pid, pgrp) < 0)
8907 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008908 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008909}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008910#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008911
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008912
Guido van Rossumb6775db1994-08-01 11:34:53 +00008913#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008914/*[clinic input]
8915os.tcgetpgrp
8916
8917 fd: int
8918 /
8919
8920Return the process group associated with the terminal specified by fd.
8921[clinic start generated code]*/
8922
Larry Hastings2f936352014-08-05 14:04:04 +10008923static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008924os_tcgetpgrp_impl(PyObject *module, int fd)
8925/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008926{
8927 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008928 if (pgid < 0)
8929 return posix_error();
8930 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008931}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008932#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008933
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008934
Guido van Rossumb6775db1994-08-01 11:34:53 +00008935#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008936/*[clinic input]
8937os.tcsetpgrp
8938
8939 fd: int
8940 pgid: pid_t
8941 /
8942
8943Set the process group associated with the terminal specified by fd.
8944[clinic start generated code]*/
8945
Larry Hastings2f936352014-08-05 14:04:04 +10008946static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008947os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8948/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008949{
Victor Stinner8c62be82010-05-06 00:08:46 +00008950 if (tcsetpgrp(fd, pgid) < 0)
8951 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008952 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008953}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008954#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008955
Guido van Rossum687dd131993-05-17 08:34:16 +00008956/* Functions acting on file descriptors */
8957
Victor Stinnerdaf45552013-08-28 00:53:59 +02008958#ifdef O_CLOEXEC
8959extern int _Py_open_cloexec_works;
8960#endif
8961
Larry Hastings2f936352014-08-05 14:04:04 +10008962
8963/*[clinic input]
8964os.open -> int
8965 path: path_t
8966 flags: int
8967 mode: int = 0o777
8968 *
8969 dir_fd: dir_fd(requires='openat') = None
8970
8971# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8972
8973Open a file for low level IO. Returns a file descriptor (integer).
8974
8975If dir_fd is not None, it should be a file descriptor open to a directory,
8976 and path should be relative; path will then be relative to that directory.
8977dir_fd may not be implemented on your platform.
8978 If it is unavailable, using it will raise a NotImplementedError.
8979[clinic start generated code]*/
8980
Larry Hastings2f936352014-08-05 14:04:04 +10008981static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008982os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8983/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008984{
8985 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008986 int async_err = 0;
Ronald Oussorene8b1c032020-11-22 11:18:40 +01008987#ifdef HAVE_OPENAT
8988 int openat_unavailable = 0;
8989#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008990
Victor Stinnerdaf45552013-08-28 00:53:59 +02008991#ifdef O_CLOEXEC
8992 int *atomic_flag_works = &_Py_open_cloexec_works;
8993#elif !defined(MS_WINDOWS)
8994 int *atomic_flag_works = NULL;
8995#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008996
Victor Stinnerdaf45552013-08-28 00:53:59 +02008997#ifdef MS_WINDOWS
8998 flags |= O_NOINHERIT;
8999#elif defined(O_CLOEXEC)
9000 flags |= O_CLOEXEC;
9001#endif
9002
Steve Dowerb82e17e2019-05-23 08:45:22 -07009003 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
9004 return -1;
9005 }
9006
Steve Dower8fc89802015-04-12 00:26:27 -04009007 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009008 do {
9009 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07009010#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009011 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009012#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07009013#ifdef HAVE_OPENAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +01009014 if (dir_fd != DEFAULT_DIR_FD) {
9015 if (HAVE_OPENAT_RUNTIME) {
9016 fd = openat(dir_fd, path->narrow, flags, mode);
9017
9018 } else {
9019 openat_unavailable = 1;
9020 fd = -1;
9021 }
9022 } else
Steve Dower6230aaf2016-09-09 09:03:15 -07009023#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009024 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009025#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009026 Py_END_ALLOW_THREADS
9027 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009028 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00009029
Ronald Oussorene8b1c032020-11-22 11:18:40 +01009030#ifdef HAVE_OPENAT
9031 if (openat_unavailable) {
9032 argument_unavailable_error(NULL, "dir_fd");
9033 return -1;
9034 }
9035#endif
9036
Victor Stinnerd3ffd322015-09-15 10:11:03 +02009037 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009038 if (!async_err)
9039 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10009040 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009041 }
9042
Victor Stinnerdaf45552013-08-28 00:53:59 +02009043#ifndef MS_WINDOWS
9044 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
9045 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10009046 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009047 }
9048#endif
9049
Larry Hastings2f936352014-08-05 14:04:04 +10009050 return fd;
9051}
9052
9053
9054/*[clinic input]
9055os.close
9056
9057 fd: int
9058
9059Close a file descriptor.
9060[clinic start generated code]*/
9061
Barry Warsaw53699e91996-12-10 23:23:01 +00009062static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009063os_close_impl(PyObject *module, int fd)
9064/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009065{
Larry Hastings2f936352014-08-05 14:04:04 +10009066 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009067 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
9068 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
9069 * for more details.
9070 */
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009072 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009073 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04009074 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009075 Py_END_ALLOW_THREADS
9076 if (res < 0)
9077 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009078 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00009079}
9080
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009081
Jakub Kulíke20134f2019-09-11 17:11:57 +02009082#ifdef HAVE_FDWALK
9083static int
9084_fdwalk_close_func(void *lohi, int fd)
9085{
9086 int lo = ((int *)lohi)[0];
9087 int hi = ((int *)lohi)[1];
9088
Victor Stinner162c5672020-04-24 12:00:51 +02009089 if (fd >= hi) {
Jakub Kulíke20134f2019-09-11 17:11:57 +02009090 return 1;
Victor Stinner162c5672020-04-24 12:00:51 +02009091 }
9092 else if (fd >= lo) {
9093 /* Ignore errors */
9094 (void)close(fd);
9095 }
Jakub Kulíke20134f2019-09-11 17:11:57 +02009096 return 0;
9097}
9098#endif /* HAVE_FDWALK */
9099
Larry Hastings2f936352014-08-05 14:04:04 +10009100/*[clinic input]
9101os.closerange
9102
9103 fd_low: int
9104 fd_high: int
9105 /
9106
9107Closes all file descriptors in [fd_low, fd_high), ignoring errors.
9108[clinic start generated code]*/
9109
Larry Hastings2f936352014-08-05 14:04:04 +10009110static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009111os_closerange_impl(PyObject *module, int fd_low, int fd_high)
9112/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009113{
Jakub Kulíke20134f2019-09-11 17:11:57 +02009114#ifdef HAVE_FDWALK
9115 int lohi[2];
Jakub Kulíke20134f2019-09-11 17:11:57 +02009116#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009117 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009118 _Py_BEGIN_SUPPRESS_IPH
Jakub Kulíke20134f2019-09-11 17:11:57 +02009119#ifdef HAVE_FDWALK
9120 lohi[0] = Py_MAX(fd_low, 0);
9121 lohi[1] = fd_high;
9122 fdwalk(_fdwalk_close_func, lohi);
9123#else
Victor Stinner162c5672020-04-24 12:00:51 +02009124 fd_low = Py_MAX(fd_low, 0);
9125#ifdef __FreeBSD__
9126 if (fd_high >= sysconf(_SC_OPEN_MAX)) {
9127 /* Any errors encountered while closing file descriptors are ignored */
9128 closefrom(fd_low);
9129 }
9130 else
9131#endif
9132 {
9133 for (int i = fd_low; i < fd_high; i++) {
9134 /* Ignore errors */
9135 (void)close(i);
9136 }
9137 }
Jakub Kulíke20134f2019-09-11 17:11:57 +02009138#endif
Steve Dower8fc89802015-04-12 00:26:27 -04009139 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009140 Py_END_ALLOW_THREADS
9141 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00009142}
9143
9144
Larry Hastings2f936352014-08-05 14:04:04 +10009145/*[clinic input]
9146os.dup -> int
9147
9148 fd: int
9149 /
9150
9151Return a duplicate of a file descriptor.
9152[clinic start generated code]*/
9153
Larry Hastings2f936352014-08-05 14:04:04 +10009154static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009155os_dup_impl(PyObject *module, int fd)
9156/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009157{
9158 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00009159}
9160
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009161
Larry Hastings2f936352014-08-05 14:04:04 +10009162/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009163os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10009164 fd: int
9165 fd2: int
9166 inheritable: bool=True
9167
9168Duplicate file descriptor.
9169[clinic start generated code]*/
9170
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009171static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009172os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009173/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009174{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01009175 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009176#if defined(HAVE_DUP3) && \
9177 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
9178 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03009179 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009180#endif
9181
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009182 if (fd < 0 || fd2 < 0) {
9183 posix_error();
9184 return -1;
9185 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009186
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009187 /* dup2() can fail with EINTR if the target FD is already open, because it
9188 * then has to be closed. See os_close_impl() for why we don't handle EINTR
9189 * upon close(), and therefore below.
9190 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02009191#ifdef MS_WINDOWS
9192 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009193 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009194 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04009195 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009196 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009197 if (res < 0) {
9198 posix_error();
9199 return -1;
9200 }
9201 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02009202
9203 /* Character files like console cannot be make non-inheritable */
9204 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9205 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009206 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009207 }
9208
9209#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
9210 Py_BEGIN_ALLOW_THREADS
9211 if (!inheritable)
9212 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
9213 else
9214 res = dup2(fd, fd2);
9215 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009216 if (res < 0) {
9217 posix_error();
9218 return -1;
9219 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009220
9221#else
9222
9223#ifdef HAVE_DUP3
9224 if (!inheritable && dup3_works != 0) {
9225 Py_BEGIN_ALLOW_THREADS
9226 res = dup3(fd, fd2, O_CLOEXEC);
9227 Py_END_ALLOW_THREADS
9228 if (res < 0) {
9229 if (dup3_works == -1)
9230 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009231 if (dup3_works) {
9232 posix_error();
9233 return -1;
9234 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009235 }
9236 }
9237
9238 if (inheritable || dup3_works == 0)
9239 {
9240#endif
9241 Py_BEGIN_ALLOW_THREADS
9242 res = dup2(fd, fd2);
9243 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009244 if (res < 0) {
9245 posix_error();
9246 return -1;
9247 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009248
9249 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9250 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009251 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009252 }
9253#ifdef HAVE_DUP3
9254 }
9255#endif
9256
9257#endif
9258
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009259 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00009260}
9261
Larry Hastings2f936352014-08-05 14:04:04 +10009262
Ross Lagerwall7807c352011-03-17 20:20:30 +02009263#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10009264/*[clinic input]
9265os.lockf
9266
9267 fd: int
9268 An open file descriptor.
9269 command: int
9270 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
9271 length: Py_off_t
9272 The number of bytes to lock, starting at the current position.
9273 /
9274
9275Apply, test or remove a POSIX lock on an open file descriptor.
9276
9277[clinic start generated code]*/
9278
Larry Hastings2f936352014-08-05 14:04:04 +10009279static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009280os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
9281/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009282{
9283 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009284
Saiyang Gou7514f4f2020-02-12 23:47:42 -08009285 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
9286 return NULL;
9287 }
9288
Ross Lagerwall7807c352011-03-17 20:20:30 +02009289 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009290 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009291 Py_END_ALLOW_THREADS
9292
9293 if (res < 0)
9294 return posix_error();
9295
9296 Py_RETURN_NONE;
9297}
Larry Hastings2f936352014-08-05 14:04:04 +10009298#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009300
Larry Hastings2f936352014-08-05 14:04:04 +10009301/*[clinic input]
9302os.lseek -> Py_off_t
9303
9304 fd: int
9305 position: Py_off_t
9306 how: int
9307 /
9308
9309Set the position of a file descriptor. Return the new position.
9310
9311Return the new cursor position in number of bytes
9312relative to the beginning of the file.
9313[clinic start generated code]*/
9314
Larry Hastings2f936352014-08-05 14:04:04 +10009315static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009316os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
9317/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009318{
9319 Py_off_t result;
9320
Guido van Rossum687dd131993-05-17 08:34:16 +00009321#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00009322 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
9323 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10009324 case 0: how = SEEK_SET; break;
9325 case 1: how = SEEK_CUR; break;
9326 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00009327 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009328#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009329
Victor Stinner8c62be82010-05-06 00:08:46 +00009330 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009331 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02009332#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009333 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009334#else
Larry Hastings2f936352014-08-05 14:04:04 +10009335 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009336#endif
Steve Dower8fc89802015-04-12 00:26:27 -04009337 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009339 if (result < 0)
9340 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00009341
Larry Hastings2f936352014-08-05 14:04:04 +10009342 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00009343}
9344
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009345
Larry Hastings2f936352014-08-05 14:04:04 +10009346/*[clinic input]
9347os.read
9348 fd: int
9349 length: Py_ssize_t
9350 /
9351
9352Read from a file descriptor. Returns a bytes object.
9353[clinic start generated code]*/
9354
Larry Hastings2f936352014-08-05 14:04:04 +10009355static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009356os_read_impl(PyObject *module, int fd, Py_ssize_t length)
9357/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009358{
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 Py_ssize_t n;
9360 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10009361
9362 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 errno = EINVAL;
9364 return posix_error();
9365 }
Larry Hastings2f936352014-08-05 14:04:04 +10009366
Victor Stinner9a0d7a72018-11-22 15:03:40 +01009367 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10009368
9369 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 if (buffer == NULL)
9371 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009372
Victor Stinner66aab0c2015-03-19 22:53:20 +01009373 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
9374 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009375 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01009376 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 }
Larry Hastings2f936352014-08-05 14:04:04 +10009378
9379 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10009381
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00009383}
9384
Ross Lagerwall7807c352011-03-17 20:20:30 +02009385#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009386 || defined(__APPLE__))) \
9387 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
9388 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9389static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009390iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009391{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009392 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009393
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009394 *iov = PyMem_New(struct iovec, cnt);
9395 if (*iov == NULL) {
9396 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009397 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009398 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009399
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009400 *buf = PyMem_New(Py_buffer, cnt);
9401 if (*buf == NULL) {
9402 PyMem_Del(*iov);
9403 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009404 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009405 }
9406
9407 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009408 PyObject *item = PySequence_GetItem(seq, i);
9409 if (item == NULL)
9410 goto fail;
9411 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
9412 Py_DECREF(item);
9413 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009414 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009415 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009416 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009417 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009418 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009419 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009420
9421fail:
9422 PyMem_Del(*iov);
9423 for (j = 0; j < i; j++) {
9424 PyBuffer_Release(&(*buf)[j]);
9425 }
9426 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01009427 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009428}
9429
9430static void
9431iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9432{
9433 int i;
9434 PyMem_Del(iov);
9435 for (i = 0; i < cnt; i++) {
9436 PyBuffer_Release(&buf[i]);
9437 }
9438 PyMem_Del(buf);
9439}
9440#endif
9441
Larry Hastings2f936352014-08-05 14:04:04 +10009442
Ross Lagerwall7807c352011-03-17 20:20:30 +02009443#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10009444/*[clinic input]
9445os.readv -> Py_ssize_t
9446
9447 fd: int
9448 buffers: object
9449 /
9450
9451Read from a file descriptor fd into an iterable of buffers.
9452
9453The buffers should be mutable buffers accepting bytes.
9454readv will transfer data into each buffer until it is full
9455and then move on to the next buffer in the sequence to hold
9456the rest of the data.
9457
9458readv returns the total number of bytes read,
9459which may be less than the total capacity of all the buffers.
9460[clinic start generated code]*/
9461
Larry Hastings2f936352014-08-05 14:04:04 +10009462static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009463os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9464/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009465{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009466 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009467 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009468 struct iovec *iov;
9469 Py_buffer *buf;
9470
Larry Hastings2f936352014-08-05 14:04:04 +10009471 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009472 PyErr_SetString(PyExc_TypeError,
9473 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009474 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009475 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009476
Larry Hastings2f936352014-08-05 14:04:04 +10009477 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009478 if (cnt < 0)
9479 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009480
9481 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9482 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009483
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009484 do {
9485 Py_BEGIN_ALLOW_THREADS
9486 n = readv(fd, iov, cnt);
9487 Py_END_ALLOW_THREADS
9488 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009489
9490 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009491 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009492 if (!async_err)
9493 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009494 return -1;
9495 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009496
Larry Hastings2f936352014-08-05 14:04:04 +10009497 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009498}
Larry Hastings2f936352014-08-05 14:04:04 +10009499#endif /* HAVE_READV */
9500
Ross Lagerwall7807c352011-03-17 20:20:30 +02009501
9502#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009503/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009504os.pread
9505
9506 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009507 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009508 offset: Py_off_t
9509 /
9510
9511Read a number of bytes from a file descriptor starting at a particular offset.
9512
9513Read length bytes from file descriptor fd, starting at offset bytes from
9514the beginning of the file. The file offset remains unchanged.
9515[clinic start generated code]*/
9516
Larry Hastings2f936352014-08-05 14:04:04 +10009517static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009518os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9519/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009520{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009521 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009522 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009523 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009524
Larry Hastings2f936352014-08-05 14:04:04 +10009525 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009526 errno = EINVAL;
9527 return posix_error();
9528 }
Larry Hastings2f936352014-08-05 14:04:04 +10009529 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009530 if (buffer == NULL)
9531 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009532
9533 do {
9534 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009535 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009536 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009537 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009538 Py_END_ALLOW_THREADS
9539 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9540
Ross Lagerwall7807c352011-03-17 20:20:30 +02009541 if (n < 0) {
9542 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009543 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009544 }
Larry Hastings2f936352014-08-05 14:04:04 +10009545 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009546 _PyBytes_Resize(&buffer, n);
9547 return buffer;
9548}
Larry Hastings2f936352014-08-05 14:04:04 +10009549#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009550
Pablo Galindo4defba32018-01-27 16:16:37 +00009551#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9552/*[clinic input]
9553os.preadv -> Py_ssize_t
9554
9555 fd: int
9556 buffers: object
9557 offset: Py_off_t
9558 flags: int = 0
9559 /
9560
9561Reads from a file descriptor into a number of mutable bytes-like objects.
9562
9563Combines the functionality of readv() and pread(). As readv(), it will
9564transfer data into each buffer until it is full and then move on to the next
9565buffer in the sequence to hold the rest of the data. Its fourth argument,
9566specifies the file offset at which the input operation is to be performed. It
9567will return the total number of bytes read (which can be less than the total
9568capacity of all the objects).
9569
9570The flags argument contains a bitwise OR of zero or more of the following flags:
9571
9572- RWF_HIPRI
9573- RWF_NOWAIT
9574
9575Using non-zero flags requires Linux 4.6 or newer.
9576[clinic start generated code]*/
9577
9578static Py_ssize_t
9579os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9580 int flags)
9581/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9582{
9583 Py_ssize_t cnt, n;
9584 int async_err = 0;
9585 struct iovec *iov;
9586 Py_buffer *buf;
9587
9588 if (!PySequence_Check(buffers)) {
9589 PyErr_SetString(PyExc_TypeError,
9590 "preadv2() arg 2 must be a sequence");
9591 return -1;
9592 }
9593
9594 cnt = PySequence_Size(buffers);
9595 if (cnt < 0) {
9596 return -1;
9597 }
9598
9599#ifndef HAVE_PREADV2
9600 if(flags != 0) {
9601 argument_unavailable_error("preadv2", "flags");
9602 return -1;
9603 }
9604#endif
9605
9606 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9607 return -1;
9608 }
9609#ifdef HAVE_PREADV2
9610 do {
9611 Py_BEGIN_ALLOW_THREADS
9612 _Py_BEGIN_SUPPRESS_IPH
9613 n = preadv2(fd, iov, cnt, offset, flags);
9614 _Py_END_SUPPRESS_IPH
9615 Py_END_ALLOW_THREADS
9616 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9617#else
9618 do {
Ronald Oussorene8b1c032020-11-22 11:18:40 +01009619#ifdef __APPLE__
9620/* This entire function will be removed from the module dict when the API
9621 * is not available.
9622 */
9623#pragma clang diagnostic push
9624#pragma clang diagnostic ignored "-Wunguarded-availability"
9625#pragma clang diagnostic ignored "-Wunguarded-availability-new"
9626#endif
Pablo Galindo4defba32018-01-27 16:16:37 +00009627 Py_BEGIN_ALLOW_THREADS
9628 _Py_BEGIN_SUPPRESS_IPH
9629 n = preadv(fd, iov, cnt, offset);
9630 _Py_END_SUPPRESS_IPH
9631 Py_END_ALLOW_THREADS
9632 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussorene8b1c032020-11-22 11:18:40 +01009633
9634#ifdef __APPLE__
9635#pragma clang diagnostic pop
9636#endif
9637
Pablo Galindo4defba32018-01-27 16:16:37 +00009638#endif
9639
9640 iov_cleanup(iov, buf, cnt);
9641 if (n < 0) {
9642 if (!async_err) {
9643 posix_error();
9644 }
9645 return -1;
9646 }
9647
9648 return n;
9649}
9650#endif /* HAVE_PREADV */
9651
Larry Hastings2f936352014-08-05 14:04:04 +10009652
9653/*[clinic input]
9654os.write -> Py_ssize_t
9655
9656 fd: int
9657 data: Py_buffer
9658 /
9659
9660Write a bytes object to a file descriptor.
9661[clinic start generated code]*/
9662
Larry Hastings2f936352014-08-05 14:04:04 +10009663static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009664os_write_impl(PyObject *module, int fd, Py_buffer *data)
9665/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009666{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009667 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009668}
9669
9670#ifdef HAVE_SENDFILE
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009671#ifdef __APPLE__
9672/*[clinic input]
9673os.sendfile
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009674
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009675 out_fd: int
9676 in_fd: int
9677 offset: Py_off_t
9678 count as sbytes: Py_off_t
9679 headers: object(c_default="NULL") = ()
9680 trailers: object(c_default="NULL") = ()
9681 flags: int = 0
9682
9683Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9684[clinic start generated code]*/
9685
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009686static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009687os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9688 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9689 int flags)
9690/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9691#elif defined(__FreeBSD__) || defined(__DragonFly__)
9692/*[clinic input]
9693os.sendfile
9694
9695 out_fd: int
9696 in_fd: int
9697 offset: Py_off_t
9698 count: Py_ssize_t
9699 headers: object(c_default="NULL") = ()
9700 trailers: object(c_default="NULL") = ()
9701 flags: int = 0
9702
9703Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9704[clinic start generated code]*/
9705
9706static PyObject *
9707os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9708 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9709 int flags)
9710/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9711#else
9712/*[clinic input]
9713os.sendfile
9714
9715 out_fd: int
9716 in_fd: int
9717 offset as offobj: object
9718 count: Py_ssize_t
9719
9720Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9721[clinic start generated code]*/
9722
9723static PyObject *
9724os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9725 Py_ssize_t count)
9726/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9727#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009728{
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009729 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009730 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009731
9732#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9733#ifndef __APPLE__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009734 off_t sbytes;
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009735#endif
9736 Py_buffer *hbuf, *tbuf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009737 struct sf_hdtr sf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009738
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009739 sf.headers = NULL;
9740 sf.trailers = NULL;
9741
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009742 if (headers != NULL) {
9743 if (!PySequence_Check(headers)) {
9744 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009745 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009746 return NULL;
9747 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009748 Py_ssize_t i = PySequence_Size(headers);
9749 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009750 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009751 if (i > INT_MAX) {
9752 PyErr_SetString(PyExc_OverflowError,
9753 "sendfile() header is too large");
9754 return NULL;
9755 }
9756 if (i > 0) {
9757 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009758 if (iov_setup(&(sf.headers), &hbuf,
9759 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009760 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009761#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009762 for (i = 0; i < sf.hdr_cnt; i++) {
9763 Py_ssize_t blen = sf.headers[i].iov_len;
9764# define OFF_T_MAX 0x7fffffffffffffff
9765 if (sbytes >= OFF_T_MAX - blen) {
9766 PyErr_SetString(PyExc_OverflowError,
9767 "sendfile() header is too large");
9768 return NULL;
9769 }
9770 sbytes += blen;
9771 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009772#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009773 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009774 }
9775 }
9776 if (trailers != NULL) {
9777 if (!PySequence_Check(trailers)) {
9778 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009779 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009780 return NULL;
9781 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009782 Py_ssize_t i = PySequence_Size(trailers);
9783 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009784 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009785 if (i > INT_MAX) {
9786 PyErr_SetString(PyExc_OverflowError,
9787 "sendfile() trailer is too large");
9788 return NULL;
9789 }
9790 if (i > 0) {
9791 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009792 if (iov_setup(&(sf.trailers), &tbuf,
9793 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009794 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009795 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009796 }
9797 }
9798
Steve Dower8fc89802015-04-12 00:26:27 -04009799 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009800 do {
9801 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009802#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009803 ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009804#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009805 ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009806#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009807 Py_END_ALLOW_THREADS
9808 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009809 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009810
9811 if (sf.headers != NULL)
9812 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9813 if (sf.trailers != NULL)
9814 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9815
9816 if (ret < 0) {
9817 if ((errno == EAGAIN) || (errno == EBUSY)) {
9818 if (sbytes != 0) {
9819 // some data has been sent
9820 goto done;
9821 }
9822 else {
9823 // no data has been sent; upper application is supposed
9824 // to retry on EAGAIN or EBUSY
9825 return posix_error();
9826 }
9827 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009828 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009829 }
9830 goto done;
9831
9832done:
9833 #if !defined(HAVE_LARGEFILE_SUPPORT)
9834 return Py_BuildValue("l", sbytes);
9835 #else
9836 return Py_BuildValue("L", sbytes);
9837 #endif
9838
9839#else
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009840#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009841 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009842 do {
9843 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009844 ret = sendfile(out_fd, in_fd, NULL, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009845 Py_END_ALLOW_THREADS
9846 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009847 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009848 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009849 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009850 }
9851#endif
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009852 off_t offset;
Larry Hastings2f936352014-08-05 14:04:04 +10009853 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009854 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009855
Łukasz Langa7e356f12020-09-16 13:52:26 +02009856#if defined(__sun) && defined(__SVR4)
9857 // On Solaris, sendfile raises EINVAL rather than returning 0
9858 // when the offset is equal or bigger than the in_fd size.
Łukasz Langa7e356f12020-09-16 13:52:26 +02009859 struct stat st;
9860
9861 do {
9862 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)6a398882020-09-16 05:25:09 -07009863 ret = fstat(in_fd, &st);
Łukasz Langa7e356f12020-09-16 13:52:26 +02009864 Py_END_ALLOW_THREADS
Miss Islington (bot)6a398882020-09-16 05:25:09 -07009865 } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Łukasz Langa7e356f12020-09-16 13:52:26 +02009866 if (ret < 0)
9867 return (!async_err) ? posix_error() : NULL;
9868
9869 if (offset >= st.st_size) {
9870 return Py_BuildValue("i", 0);
9871 }
Miss Islington (bot)7ae19ef2020-11-12 02:14:03 -08009872
9873 // On illumos specifically sendfile() may perform a partial write but
9874 // return -1/an error (in one confirmed case the destination socket
9875 // had a 5 second timeout set and errno was EAGAIN) and it's on the client
9876 // code to check if the offset parameter was modified by sendfile().
9877 //
9878 // We need this variable to track said change.
9879 off_t original_offset = offset;
Łukasz Langa7e356f12020-09-16 13:52:26 +02009880#endif
9881
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009882 do {
9883 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009884 ret = sendfile(out_fd, in_fd, &offset, count);
Miss Islington (bot)7ae19ef2020-11-12 02:14:03 -08009885#if defined(__sun) && defined(__SVR4)
9886 // This handles illumos-specific sendfile() partial write behavior,
9887 // see a comment above for more details.
9888 if (ret < 0 && offset != original_offset) {
9889 ret = offset - original_offset;
9890 }
9891#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009892 Py_END_ALLOW_THREADS
9893 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009894 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009895 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009896 return Py_BuildValue("n", ret);
9897#endif
9898}
Larry Hastings2f936352014-08-05 14:04:04 +10009899#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009900
Larry Hastings2f936352014-08-05 14:04:04 +10009901
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009902#if defined(__APPLE__)
9903/*[clinic input]
9904os._fcopyfile
9905
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009906 in_fd: int
9907 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009908 flags: int
9909 /
9910
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009911Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009912[clinic start generated code]*/
9913
9914static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009915os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9916/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009917{
9918 int ret;
9919
9920 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009921 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009922 Py_END_ALLOW_THREADS
9923 if (ret < 0)
9924 return posix_error();
9925 Py_RETURN_NONE;
9926}
9927#endif
9928
9929
Larry Hastings2f936352014-08-05 14:04:04 +10009930/*[clinic input]
9931os.fstat
9932
9933 fd : int
9934
9935Perform a stat system call on the given file descriptor.
9936
9937Like stat(), but for an open file descriptor.
9938Equivalent to os.stat(fd).
9939[clinic start generated code]*/
9940
Larry Hastings2f936352014-08-05 14:04:04 +10009941static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009942os_fstat_impl(PyObject *module, int fd)
9943/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009944{
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 STRUCT_STAT st;
9946 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009947 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009948
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009949 do {
9950 Py_BEGIN_ALLOW_THREADS
9951 res = FSTAT(fd, &st);
9952 Py_END_ALLOW_THREADS
9953 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009955#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009956 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009957#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009958 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009959#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 }
Tim Peters5aa91602002-01-30 05:46:57 +00009961
Victor Stinner1c2fa782020-05-10 11:05:29 +02009962 return _pystat_fromstructstat(module, &st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009963}
9964
Larry Hastings2f936352014-08-05 14:04:04 +10009965
9966/*[clinic input]
9967os.isatty -> bool
9968 fd: int
9969 /
9970
9971Return True if the fd is connected to a terminal.
9972
9973Return True if the file descriptor is an open file descriptor
9974connected to the slave end of a terminal.
9975[clinic start generated code]*/
9976
Larry Hastings2f936352014-08-05 14:04:04 +10009977static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009978os_isatty_impl(PyObject *module, int fd)
9979/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009980{
Steve Dower8fc89802015-04-12 00:26:27 -04009981 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009982 _Py_BEGIN_SUPPRESS_IPH
9983 return_value = isatty(fd);
9984 _Py_END_SUPPRESS_IPH
9985 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009986}
9987
9988
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009989#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009990/*[clinic input]
9991os.pipe
9992
9993Create a pipe.
9994
9995Returns a tuple of two file descriptors:
9996 (read_fd, write_fd)
9997[clinic start generated code]*/
9998
Larry Hastings2f936352014-08-05 14:04:04 +10009999static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010000os_pipe_impl(PyObject *module)
10001/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +000010002{
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +020010004#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010006 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010008#else
10009 int res;
10010#endif
10011
10012#ifdef MS_WINDOWS
10013 attr.nLength = sizeof(attr);
10014 attr.lpSecurityDescriptor = NULL;
10015 attr.bInheritHandle = FALSE;
10016
10017 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -080010018 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +020010019 ok = CreatePipe(&read, &write, &attr, 0);
10020 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -070010021 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
10022 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010023 if (fds[0] == -1 || fds[1] == -1) {
10024 CloseHandle(read);
10025 CloseHandle(write);
10026 ok = 0;
10027 }
10028 }
Steve Dowerc3630612016-11-19 18:41:16 -080010029 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +020010030 Py_END_ALLOW_THREADS
10031
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +010010033 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010034#else
10035
10036#ifdef HAVE_PIPE2
10037 Py_BEGIN_ALLOW_THREADS
10038 res = pipe2(fds, O_CLOEXEC);
10039 Py_END_ALLOW_THREADS
10040
10041 if (res != 0 && errno == ENOSYS)
10042 {
10043#endif
10044 Py_BEGIN_ALLOW_THREADS
10045 res = pipe(fds);
10046 Py_END_ALLOW_THREADS
10047
10048 if (res == 0) {
10049 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
10050 close(fds[0]);
10051 close(fds[1]);
10052 return NULL;
10053 }
10054 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
10055 close(fds[0]);
10056 close(fds[1]);
10057 return NULL;
10058 }
10059 }
10060#ifdef HAVE_PIPE2
10061 }
10062#endif
10063
10064 if (res != 0)
10065 return PyErr_SetFromErrno(PyExc_OSError);
10066#endif /* !MS_WINDOWS */
10067 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +000010068}
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010069#endif /* HAVE_PIPE */
10070
Larry Hastings2f936352014-08-05 14:04:04 +100010071
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010072#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +100010073/*[clinic input]
10074os.pipe2
10075
10076 flags: int
10077 /
10078
10079Create a pipe with flags set atomically.
10080
10081Returns a tuple of two file descriptors:
10082 (read_fd, write_fd)
10083
10084flags can be constructed by ORing together one or more of these values:
10085O_NONBLOCK, O_CLOEXEC.
10086[clinic start generated code]*/
10087
Larry Hastings2f936352014-08-05 14:04:04 +100010088static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010089os_pipe2_impl(PyObject *module, int flags)
10090/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010091{
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010092 int fds[2];
10093 int res;
10094
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010095 res = pipe2(fds, flags);
10096 if (res != 0)
10097 return posix_error();
10098 return Py_BuildValue("(ii)", fds[0], fds[1]);
10099}
10100#endif /* HAVE_PIPE2 */
10101
Larry Hastings2f936352014-08-05 14:04:04 +100010102
Ross Lagerwall7807c352011-03-17 20:20:30 +020010103#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +100010104/*[clinic input]
10105os.writev -> Py_ssize_t
10106 fd: int
10107 buffers: object
10108 /
10109
10110Iterate over buffers, and write the contents of each to a file descriptor.
10111
10112Returns the total number of bytes written.
10113buffers must be a sequence of bytes-like objects.
10114[clinic start generated code]*/
10115
Larry Hastings2f936352014-08-05 14:04:04 +100010116static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010117os_writev_impl(PyObject *module, int fd, PyObject *buffers)
10118/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010119{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010120 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +100010121 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010122 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010123 struct iovec *iov;
10124 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +100010125
10126 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020010127 PyErr_SetString(PyExc_TypeError,
10128 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +100010129 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010130 }
Larry Hastings2f936352014-08-05 14:04:04 +100010131 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010132 if (cnt < 0)
10133 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010134
Larry Hastings2f936352014-08-05 14:04:04 +100010135 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10136 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010137 }
10138
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010139 do {
10140 Py_BEGIN_ALLOW_THREADS
10141 result = writev(fd, iov, cnt);
10142 Py_END_ALLOW_THREADS
10143 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +020010144
10145 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010146 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010147 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +010010148
Georg Brandl306336b2012-06-24 12:55:33 +020010149 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010150}
Larry Hastings2f936352014-08-05 14:04:04 +100010151#endif /* HAVE_WRITEV */
10152
10153
10154#ifdef HAVE_PWRITE
10155/*[clinic input]
10156os.pwrite -> Py_ssize_t
10157
10158 fd: int
10159 buffer: Py_buffer
10160 offset: Py_off_t
10161 /
10162
10163Write bytes to a file descriptor starting at a particular offset.
10164
10165Write buffer to fd, starting at offset bytes from the beginning of
10166the file. Returns the number of bytes writte. Does not change the
10167current file offset.
10168[clinic start generated code]*/
10169
Larry Hastings2f936352014-08-05 14:04:04 +100010170static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010171os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
10172/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010173{
10174 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010175 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010176
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010177 do {
10178 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -040010179 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010180 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -040010181 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010182 Py_END_ALLOW_THREADS
10183 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010184
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010185 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010186 posix_error();
10187 return size;
10188}
10189#endif /* HAVE_PWRITE */
10190
Pablo Galindo4defba32018-01-27 16:16:37 +000010191#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
10192/*[clinic input]
10193os.pwritev -> Py_ssize_t
10194
10195 fd: int
10196 buffers: object
10197 offset: Py_off_t
10198 flags: int = 0
10199 /
10200
10201Writes the contents of bytes-like objects to a file descriptor at a given offset.
10202
10203Combines the functionality of writev() and pwrite(). All buffers must be a sequence
10204of bytes-like objects. Buffers are processed in array order. Entire contents of first
10205buffer is written before proceeding to second, and so on. The operating system may
10206set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
10207This function writes the contents of each object to the file descriptor and returns
10208the total number of bytes written.
10209
10210The flags argument contains a bitwise OR of zero or more of the following flags:
10211
10212- RWF_DSYNC
10213- RWF_SYNC
10214
10215Using non-zero flags requires Linux 4.7 or newer.
10216[clinic start generated code]*/
10217
10218static Py_ssize_t
10219os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
10220 int flags)
10221/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
10222{
10223 Py_ssize_t cnt;
10224 Py_ssize_t result;
10225 int async_err = 0;
10226 struct iovec *iov;
10227 Py_buffer *buf;
10228
10229 if (!PySequence_Check(buffers)) {
10230 PyErr_SetString(PyExc_TypeError,
10231 "pwritev() arg 2 must be a sequence");
10232 return -1;
10233 }
10234
10235 cnt = PySequence_Size(buffers);
10236 if (cnt < 0) {
10237 return -1;
10238 }
10239
10240#ifndef HAVE_PWRITEV2
10241 if(flags != 0) {
10242 argument_unavailable_error("pwritev2", "flags");
10243 return -1;
10244 }
10245#endif
10246
10247 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10248 return -1;
10249 }
10250#ifdef HAVE_PWRITEV2
10251 do {
10252 Py_BEGIN_ALLOW_THREADS
10253 _Py_BEGIN_SUPPRESS_IPH
10254 result = pwritev2(fd, iov, cnt, offset, flags);
10255 _Py_END_SUPPRESS_IPH
10256 Py_END_ALLOW_THREADS
10257 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10258#else
Ronald Oussorene8b1c032020-11-22 11:18:40 +010010259
10260#ifdef __APPLE__
10261/* This entire function will be removed from the module dict when the API
10262 * is not available.
10263 */
10264#pragma clang diagnostic push
10265#pragma clang diagnostic ignored "-Wunguarded-availability"
10266#pragma clang diagnostic ignored "-Wunguarded-availability-new"
10267#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000010268 do {
10269 Py_BEGIN_ALLOW_THREADS
10270 _Py_BEGIN_SUPPRESS_IPH
10271 result = pwritev(fd, iov, cnt, offset);
10272 _Py_END_SUPPRESS_IPH
10273 Py_END_ALLOW_THREADS
10274 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussorene8b1c032020-11-22 11:18:40 +010010275
10276#ifdef __APPLE__
10277#pragma clang diagnostic pop
10278#endif
10279
Pablo Galindo4defba32018-01-27 16:16:37 +000010280#endif
10281
10282 iov_cleanup(iov, buf, cnt);
10283 if (result < 0) {
10284 if (!async_err) {
10285 posix_error();
10286 }
10287 return -1;
10288 }
10289
10290 return result;
10291}
10292#endif /* HAVE_PWRITEV */
10293
Pablo Galindoaac4d032019-05-31 19:39:47 +010010294#ifdef HAVE_COPY_FILE_RANGE
10295/*[clinic input]
10296
10297os.copy_file_range
10298 src: int
10299 Source file descriptor.
10300 dst: int
10301 Destination file descriptor.
10302 count: Py_ssize_t
10303 Number of bytes to copy.
10304 offset_src: object = None
10305 Starting offset in src.
10306 offset_dst: object = None
10307 Starting offset in dst.
10308
10309Copy count bytes from one file descriptor to another.
10310
10311If offset_src is None, then src is read from the current position;
10312respectively for offset_dst.
10313[clinic start generated code]*/
10314
10315static PyObject *
10316os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10317 PyObject *offset_src, PyObject *offset_dst)
10318/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
10319{
10320 off_t offset_src_val, offset_dst_val;
10321 off_t *p_offset_src = NULL;
10322 off_t *p_offset_dst = NULL;
10323 Py_ssize_t ret;
10324 int async_err = 0;
10325 /* The flags argument is provided to allow
10326 * for future extensions and currently must be to 0. */
10327 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +000010328
10329
Pablo Galindoaac4d032019-05-31 19:39:47 +010010330 if (count < 0) {
10331 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10332 return NULL;
10333 }
10334
10335 if (offset_src != Py_None) {
10336 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10337 return NULL;
10338 }
10339 p_offset_src = &offset_src_val;
10340 }
10341
10342 if (offset_dst != Py_None) {
10343 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10344 return NULL;
10345 }
10346 p_offset_dst = &offset_dst_val;
10347 }
10348
10349 do {
10350 Py_BEGIN_ALLOW_THREADS
10351 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
10352 Py_END_ALLOW_THREADS
10353 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10354
10355 if (ret < 0) {
10356 return (!async_err) ? posix_error() : NULL;
10357 }
10358
10359 return PyLong_FromSsize_t(ret);
10360}
10361#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +100010362
10363#ifdef HAVE_MKFIFO
10364/*[clinic input]
10365os.mkfifo
10366
10367 path: path_t
10368 mode: int=0o666
10369 *
10370 dir_fd: dir_fd(requires='mkfifoat')=None
10371
10372Create a "fifo" (a POSIX named pipe).
10373
10374If dir_fd is not None, it should be a file descriptor open to a directory,
10375 and path should be relative; path will then be relative to that directory.
10376dir_fd may not be implemented on your platform.
10377 If it is unavailable, using it will raise a NotImplementedError.
10378[clinic start generated code]*/
10379
Larry Hastings2f936352014-08-05 14:04:04 +100010380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010381os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
10382/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010383{
10384 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010385 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010386
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010387 do {
10388 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010389#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010390 if (dir_fd != DEFAULT_DIR_FD)
10391 result = mkfifoat(dir_fd, path->narrow, mode);
10392 else
Ross Lagerwall7807c352011-03-17 20:20:30 +020010393#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010394 result = mkfifo(path->narrow, mode);
10395 Py_END_ALLOW_THREADS
10396 } while (result != 0 && errno == EINTR &&
10397 !(async_err = PyErr_CheckSignals()));
10398 if (result != 0)
10399 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010400
10401 Py_RETURN_NONE;
10402}
10403#endif /* HAVE_MKFIFO */
10404
10405
10406#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
10407/*[clinic input]
10408os.mknod
10409
10410 path: path_t
10411 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010412 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +100010413 *
10414 dir_fd: dir_fd(requires='mknodat')=None
10415
10416Create a node in the file system.
10417
10418Create a node in the file system (file, device special file or named pipe)
10419at path. mode specifies both the permissions to use and the
10420type of node to be created, being combined (bitwise OR) with one of
10421S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
10422device defines the newly created device special file (probably using
10423os.makedev()). Otherwise device is ignored.
10424
10425If dir_fd is not None, it should be a file descriptor open to a directory,
10426 and path should be relative; path will then be relative to that directory.
10427dir_fd may not be implemented on your platform.
10428 If it is unavailable, using it will raise a NotImplementedError.
10429[clinic start generated code]*/
10430
Larry Hastings2f936352014-08-05 14:04:04 +100010431static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010432os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -040010433 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010434/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010435{
10436 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010437 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010438
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010439 do {
10440 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010441#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010442 if (dir_fd != DEFAULT_DIR_FD)
10443 result = mknodat(dir_fd, path->narrow, mode, device);
10444 else
Larry Hastings2f936352014-08-05 14:04:04 +100010445#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010446 result = mknod(path->narrow, mode, device);
10447 Py_END_ALLOW_THREADS
10448 } while (result != 0 && errno == EINTR &&
10449 !(async_err = PyErr_CheckSignals()));
10450 if (result != 0)
10451 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010452
10453 Py_RETURN_NONE;
10454}
10455#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10456
10457
10458#ifdef HAVE_DEVICE_MACROS
10459/*[clinic input]
10460os.major -> unsigned_int
10461
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010462 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010463 /
10464
10465Extracts a device major number from a raw device number.
10466[clinic start generated code]*/
10467
Larry Hastings2f936352014-08-05 14:04:04 +100010468static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010469os_major_impl(PyObject *module, dev_t device)
10470/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010471{
10472 return major(device);
10473}
10474
10475
10476/*[clinic input]
10477os.minor -> unsigned_int
10478
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010479 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010480 /
10481
10482Extracts a device minor number from a raw device number.
10483[clinic start generated code]*/
10484
Larry Hastings2f936352014-08-05 14:04:04 +100010485static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010486os_minor_impl(PyObject *module, dev_t device)
10487/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010488{
10489 return minor(device);
10490}
10491
10492
10493/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010494os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010495
10496 major: int
10497 minor: int
10498 /
10499
10500Composes a raw device number from the major and minor device numbers.
10501[clinic start generated code]*/
10502
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010503static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010504os_makedev_impl(PyObject *module, int major, int minor)
10505/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010506{
10507 return makedev(major, minor);
10508}
10509#endif /* HAVE_DEVICE_MACROS */
10510
10511
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010512#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010513/*[clinic input]
10514os.ftruncate
10515
10516 fd: int
10517 length: Py_off_t
10518 /
10519
10520Truncate a file, specified by file descriptor, to a specific length.
10521[clinic start generated code]*/
10522
Larry Hastings2f936352014-08-05 14:04:04 +100010523static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010524os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10525/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010526{
10527 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010528 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010529
Steve Dowerb82e17e2019-05-23 08:45:22 -070010530 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
10531 return NULL;
10532 }
10533
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010534 do {
10535 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010536 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010537#ifdef MS_WINDOWS
10538 result = _chsize_s(fd, length);
10539#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010540 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010541#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010542 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010543 Py_END_ALLOW_THREADS
10544 } while (result != 0 && errno == EINTR &&
10545 !(async_err = PyErr_CheckSignals()));
10546 if (result != 0)
10547 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010548 Py_RETURN_NONE;
10549}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010550#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010551
10552
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010553#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010554/*[clinic input]
10555os.truncate
10556 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10557 length: Py_off_t
10558
10559Truncate a file, specified by path, to a specific length.
10560
10561On some platforms, path may also be specified as an open file descriptor.
10562 If this functionality is unavailable, using it raises an exception.
10563[clinic start generated code]*/
10564
Larry Hastings2f936352014-08-05 14:04:04 +100010565static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010566os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10567/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010568{
10569 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010570#ifdef MS_WINDOWS
10571 int fd;
10572#endif
10573
10574 if (path->fd != -1)
10575 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010576
Steve Dowerb82e17e2019-05-23 08:45:22 -070010577 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10578 return NULL;
10579 }
10580
Larry Hastings2f936352014-08-05 14:04:04 +100010581 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010582 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010583#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010584 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010585 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010586 result = -1;
10587 else {
10588 result = _chsize_s(fd, length);
10589 close(fd);
10590 if (result < 0)
10591 errno = result;
10592 }
10593#else
10594 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010595#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010596 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010597 Py_END_ALLOW_THREADS
10598 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010599 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010600
10601 Py_RETURN_NONE;
10602}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010603#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010604
Ross Lagerwall7807c352011-03-17 20:20:30 +020010605
Victor Stinnerd6b17692014-09-30 12:20:05 +020010606/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10607 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10608 defined, which is the case in Python on AIX. AIX bug report:
10609 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10610#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10611# define POSIX_FADVISE_AIX_BUG
10612#endif
10613
Victor Stinnerec39e262014-09-30 12:35:58 +020010614
Victor Stinnerd6b17692014-09-30 12:20:05 +020010615#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010616/*[clinic input]
10617os.posix_fallocate
10618
10619 fd: int
10620 offset: Py_off_t
10621 length: Py_off_t
10622 /
10623
10624Ensure a file has allocated at least a particular number of bytes on disk.
10625
10626Ensure that the file specified by fd encompasses a range of bytes
10627starting at offset bytes from the beginning and continuing for length bytes.
10628[clinic start generated code]*/
10629
Larry Hastings2f936352014-08-05 14:04:04 +100010630static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010631os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010632 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010633/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010634{
10635 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010636 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010637
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010638 do {
10639 Py_BEGIN_ALLOW_THREADS
10640 result = posix_fallocate(fd, offset, length);
10641 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010642 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10643
10644 if (result == 0)
10645 Py_RETURN_NONE;
10646
10647 if (async_err)
10648 return NULL;
10649
10650 errno = result;
10651 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010652}
Victor Stinnerec39e262014-09-30 12:35:58 +020010653#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010654
Ross Lagerwall7807c352011-03-17 20:20:30 +020010655
Victor Stinnerd6b17692014-09-30 12:20:05 +020010656#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010657/*[clinic input]
10658os.posix_fadvise
10659
10660 fd: int
10661 offset: Py_off_t
10662 length: Py_off_t
10663 advice: int
10664 /
10665
10666Announce an intention to access data in a specific pattern.
10667
10668Announce an intention to access data in a specific pattern, thus allowing
10669the kernel to make optimizations.
10670The advice applies to the region of the file specified by fd starting at
10671offset and continuing for length bytes.
10672advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10673POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10674POSIX_FADV_DONTNEED.
10675[clinic start generated code]*/
10676
Larry Hastings2f936352014-08-05 14:04:04 +100010677static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010678os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010679 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010680/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010681{
10682 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010683 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010684
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010685 do {
10686 Py_BEGIN_ALLOW_THREADS
10687 result = posix_fadvise(fd, offset, length, advice);
10688 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010689 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10690
10691 if (result == 0)
10692 Py_RETURN_NONE;
10693
10694 if (async_err)
10695 return NULL;
10696
10697 errno = result;
10698 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010699}
Victor Stinnerec39e262014-09-30 12:35:58 +020010700#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010701
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010702
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010703#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010704static PyObject*
10705win32_putenv(PyObject *name, PyObject *value)
10706{
10707 /* Search from index 1 because on Windows starting '=' is allowed for
10708 defining hidden environment variables. */
10709 if (PyUnicode_GET_LENGTH(name) == 0 ||
10710 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10711 {
10712 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10713 return NULL;
10714 }
10715 PyObject *unicode;
10716 if (value != NULL) {
10717 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10718 }
10719 else {
10720 unicode = PyUnicode_FromFormat("%U=", name);
10721 }
10722 if (unicode == NULL) {
10723 return NULL;
10724 }
10725
10726 Py_ssize_t size;
10727 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10728 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10729 Py_DECREF(unicode);
10730
10731 if (env == NULL) {
10732 return NULL;
10733 }
10734 if (size > _MAX_ENV) {
10735 PyErr_Format(PyExc_ValueError,
10736 "the environment variable is longer than %u characters",
10737 _MAX_ENV);
10738 PyMem_Free(env);
10739 return NULL;
10740 }
10741
10742 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10743 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10744 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10745
10746 Prefer _wputenv() to be compatible with C libraries using CRT
10747 variables and CRT functions using these variables (ex: getenv()). */
10748 int err = _wputenv(env);
10749 PyMem_Free(env);
10750
10751 if (err) {
10752 posix_error();
10753 return NULL;
10754 }
10755
10756 Py_RETURN_NONE;
10757}
10758#endif
10759
10760
10761#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010762/*[clinic input]
10763os.putenv
10764
10765 name: unicode
10766 value: unicode
10767 /
10768
10769Change or add an environment variable.
10770[clinic start generated code]*/
10771
Larry Hastings2f936352014-08-05 14:04:04 +100010772static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010773os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10774/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010775{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010776 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10777 return NULL;
10778 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010779 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010780}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010781#else
Larry Hastings2f936352014-08-05 14:04:04 +100010782/*[clinic input]
10783os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010784
Larry Hastings2f936352014-08-05 14:04:04 +100010785 name: FSConverter
10786 value: FSConverter
10787 /
10788
10789Change or add an environment variable.
10790[clinic start generated code]*/
10791
Larry Hastings2f936352014-08-05 14:04:04 +100010792static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010793os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10794/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010795{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010796 const char *name_string = PyBytes_AS_STRING(name);
10797 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010798
Serhiy Storchaka77703942017-06-25 07:33:01 +030010799 if (strchr(name_string, '=') != NULL) {
10800 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10801 return NULL;
10802 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010803
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010804 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10805 return NULL;
10806 }
10807
Victor Stinnerb477d192020-01-22 22:48:16 +010010808 if (setenv(name_string, value_string, 1)) {
10809 return posix_error();
10810 }
Larry Hastings2f936352014-08-05 14:04:04 +100010811 Py_RETURN_NONE;
10812}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010813#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010814
10815
Victor Stinner161e7b32020-01-24 11:53:44 +010010816#ifdef MS_WINDOWS
10817/*[clinic input]
10818os.unsetenv
10819 name: unicode
10820 /
10821
10822Delete an environment variable.
10823[clinic start generated code]*/
10824
10825static PyObject *
10826os_unsetenv_impl(PyObject *module, PyObject *name)
10827/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10828{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010829 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10830 return NULL;
10831 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010832 return win32_putenv(name, NULL);
10833}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010834#else
Larry Hastings2f936352014-08-05 14:04:04 +100010835/*[clinic input]
10836os.unsetenv
10837 name: FSConverter
10838 /
10839
10840Delete an environment variable.
10841[clinic start generated code]*/
10842
Larry Hastings2f936352014-08-05 14:04:04 +100010843static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010844os_unsetenv_impl(PyObject *module, PyObject *name)
10845/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010846{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010847 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10848 return NULL;
10849 }
Victor Stinner984890f2011-11-24 13:53:38 +010010850#ifdef HAVE_BROKEN_UNSETENV
10851 unsetenv(PyBytes_AS_STRING(name));
10852#else
Victor Stinner161e7b32020-01-24 11:53:44 +010010853 int err = unsetenv(PyBytes_AS_STRING(name));
10854 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010010855 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010010856 }
Victor Stinner984890f2011-11-24 13:53:38 +010010857#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010858
Victor Stinner84ae1182010-05-06 22:05:07 +000010859 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010860}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010861#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000010862
Larry Hastings2f936352014-08-05 14:04:04 +100010863
10864/*[clinic input]
10865os.strerror
10866
10867 code: int
10868 /
10869
10870Translate an error code to a message string.
10871[clinic start generated code]*/
10872
Larry Hastings2f936352014-08-05 14:04:04 +100010873static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010874os_strerror_impl(PyObject *module, int code)
10875/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010876{
10877 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010878 if (message == NULL) {
10879 PyErr_SetString(PyExc_ValueError,
10880 "strerror() argument out of range");
10881 return NULL;
10882 }
Victor Stinner1b579672011-12-17 05:47:23 +010010883 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010884}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010885
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010886
Guido van Rossumc9641791998-08-04 15:26:23 +000010887#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010888#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010889/*[clinic input]
10890os.WCOREDUMP -> bool
10891
10892 status: int
10893 /
10894
10895Return True if the process returning status was dumped to a core file.
10896[clinic start generated code]*/
10897
Larry Hastings2f936352014-08-05 14:04:04 +100010898static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010899os_WCOREDUMP_impl(PyObject *module, int status)
10900/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010901{
10902 WAIT_TYPE wait_status;
10903 WAIT_STATUS_INT(wait_status) = status;
10904 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010905}
10906#endif /* WCOREDUMP */
10907
Larry Hastings2f936352014-08-05 14:04:04 +100010908
Fred Drake106c1a02002-04-23 15:58:02 +000010909#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010910/*[clinic input]
10911os.WIFCONTINUED -> bool
10912
10913 status: int
10914
10915Return True if a particular process was continued from a job control stop.
10916
10917Return True if the process returning status was continued from a
10918job control stop.
10919[clinic start generated code]*/
10920
Larry Hastings2f936352014-08-05 14:04:04 +100010921static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010922os_WIFCONTINUED_impl(PyObject *module, int status)
10923/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010924{
10925 WAIT_TYPE wait_status;
10926 WAIT_STATUS_INT(wait_status) = status;
10927 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010928}
10929#endif /* WIFCONTINUED */
10930
Larry Hastings2f936352014-08-05 14:04:04 +100010931
Guido van Rossumc9641791998-08-04 15:26:23 +000010932#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010933/*[clinic input]
10934os.WIFSTOPPED -> bool
10935
10936 status: int
10937
10938Return True if the process returning status was stopped.
10939[clinic start generated code]*/
10940
Larry Hastings2f936352014-08-05 14:04:04 +100010941static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010942os_WIFSTOPPED_impl(PyObject *module, int status)
10943/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010944{
10945 WAIT_TYPE wait_status;
10946 WAIT_STATUS_INT(wait_status) = status;
10947 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010948}
10949#endif /* WIFSTOPPED */
10950
Larry Hastings2f936352014-08-05 14:04:04 +100010951
Guido van Rossumc9641791998-08-04 15:26:23 +000010952#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010953/*[clinic input]
10954os.WIFSIGNALED -> bool
10955
10956 status: int
10957
10958Return True if the process returning status was terminated by a signal.
10959[clinic start generated code]*/
10960
Larry Hastings2f936352014-08-05 14:04:04 +100010961static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010962os_WIFSIGNALED_impl(PyObject *module, int status)
10963/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010964{
10965 WAIT_TYPE wait_status;
10966 WAIT_STATUS_INT(wait_status) = status;
10967 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010968}
10969#endif /* WIFSIGNALED */
10970
Larry Hastings2f936352014-08-05 14:04:04 +100010971
Guido van Rossumc9641791998-08-04 15:26:23 +000010972#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010973/*[clinic input]
10974os.WIFEXITED -> bool
10975
10976 status: int
10977
10978Return True if the process returning status exited via the exit() system call.
10979[clinic start generated code]*/
10980
Larry Hastings2f936352014-08-05 14:04:04 +100010981static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010982os_WIFEXITED_impl(PyObject *module, int status)
10983/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010984{
10985 WAIT_TYPE wait_status;
10986 WAIT_STATUS_INT(wait_status) = status;
10987 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010988}
10989#endif /* WIFEXITED */
10990
Larry Hastings2f936352014-08-05 14:04:04 +100010991
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010992#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010993/*[clinic input]
10994os.WEXITSTATUS -> int
10995
10996 status: int
10997
10998Return the process return code from status.
10999[clinic start generated code]*/
11000
Larry Hastings2f936352014-08-05 14:04:04 +100011001static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011002os_WEXITSTATUS_impl(PyObject *module, int status)
11003/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011004{
11005 WAIT_TYPE wait_status;
11006 WAIT_STATUS_INT(wait_status) = status;
11007 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011008}
11009#endif /* WEXITSTATUS */
11010
Larry Hastings2f936352014-08-05 14:04:04 +100011011
Guido van Rossumc9641791998-08-04 15:26:23 +000011012#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011013/*[clinic input]
11014os.WTERMSIG -> int
11015
11016 status: int
11017
11018Return the signal that terminated the process that provided the status value.
11019[clinic start generated code]*/
11020
Larry Hastings2f936352014-08-05 14:04:04 +100011021static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011022os_WTERMSIG_impl(PyObject *module, int status)
11023/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011024{
11025 WAIT_TYPE wait_status;
11026 WAIT_STATUS_INT(wait_status) = status;
11027 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011028}
11029#endif /* WTERMSIG */
11030
Larry Hastings2f936352014-08-05 14:04:04 +100011031
Guido van Rossumc9641791998-08-04 15:26:23 +000011032#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011033/*[clinic input]
11034os.WSTOPSIG -> int
11035
11036 status: int
11037
11038Return the signal that stopped the process that provided the status value.
11039[clinic start generated code]*/
11040
Larry Hastings2f936352014-08-05 14:04:04 +100011041static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011042os_WSTOPSIG_impl(PyObject *module, int status)
11043/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011044{
11045 WAIT_TYPE wait_status;
11046 WAIT_STATUS_INT(wait_status) = status;
11047 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011048}
11049#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000011050#endif /* HAVE_SYS_WAIT_H */
11051
11052
Thomas Wouters477c8d52006-05-27 19:21:47 +000011053#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000011054#ifdef _SCO_DS
11055/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
11056 needed definitions in sys/statvfs.h */
11057#define _SVID3
11058#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011059#include <sys/statvfs.h>
11060
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011061static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +020011062_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
11063 PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080011064 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 if (v == NULL)
11066 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011067
11068#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011069 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11070 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11071 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
11072 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
11073 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
11074 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
11075 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
11076 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
11077 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11078 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011079#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11081 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11082 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011083 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000011084 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011085 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011087 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011088 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011089 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000011090 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011091 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011093 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011094 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11095 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011096#endif
Michael Felt502d5512018-01-05 13:01:58 +010011097/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
11098 * (issue #32390). */
11099#if defined(_AIX) && defined(_ALL_SOURCE)
11100 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
11101#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010011102 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010011103#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010011104 if (PyErr_Occurred()) {
11105 Py_DECREF(v);
11106 return NULL;
11107 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011108
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011110}
11111
Larry Hastings2f936352014-08-05 14:04:04 +100011112
11113/*[clinic input]
11114os.fstatvfs
11115 fd: int
11116 /
11117
11118Perform an fstatvfs system call on the given fd.
11119
11120Equivalent to statvfs(fd).
11121[clinic start generated code]*/
11122
Larry Hastings2f936352014-08-05 14:04:04 +100011123static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011124os_fstatvfs_impl(PyObject *module, int fd)
11125/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011126{
11127 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011128 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011129 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011130
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011131 do {
11132 Py_BEGIN_ALLOW_THREADS
11133 result = fstatvfs(fd, &st);
11134 Py_END_ALLOW_THREADS
11135 } while (result != 0 && errno == EINTR &&
11136 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100011137 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011138 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011139
Victor Stinner1c2fa782020-05-10 11:05:29 +020011140 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011141}
Larry Hastings2f936352014-08-05 14:04:04 +100011142#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000011143
11144
Thomas Wouters477c8d52006-05-27 19:21:47 +000011145#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000011146#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100011147/*[clinic input]
11148os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000011149
Larry Hastings2f936352014-08-05 14:04:04 +100011150 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
11151
11152Perform a statvfs system call on the given path.
11153
11154path may always be specified as a string.
11155On some platforms, path may also be specified as an open file descriptor.
11156 If this functionality is unavailable, using it raises an exception.
11157[clinic start generated code]*/
11158
Larry Hastings2f936352014-08-05 14:04:04 +100011159static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011160os_statvfs_impl(PyObject *module, path_t *path)
11161/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011162{
11163 int result;
11164 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011165
11166 Py_BEGIN_ALLOW_THREADS
11167#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100011168 if (path->fd != -1) {
Larry Hastings2f936352014-08-05 14:04:04 +100011169 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011170 }
11171 else
11172#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011173 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011174 Py_END_ALLOW_THREADS
11175
11176 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011177 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011178 }
11179
Victor Stinner1c2fa782020-05-10 11:05:29 +020011180 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011181}
Larry Hastings2f936352014-08-05 14:04:04 +100011182#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
11183
Guido van Rossum94f6f721999-01-06 18:42:14 +000011184
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011185#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011186/*[clinic input]
11187os._getdiskusage
11188
Steve Dower23ad6d02018-02-22 10:39:10 -080011189 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100011190
11191Return disk usage statistics about the given path as a (total, free) tuple.
11192[clinic start generated code]*/
11193
Larry Hastings2f936352014-08-05 14:04:04 +100011194static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080011195os__getdiskusage_impl(PyObject *module, path_t *path)
11196/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011197{
11198 BOOL retval;
11199 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040011200 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011201
11202 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080011203 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011204 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040011205 if (retval == 0) {
11206 if (GetLastError() == ERROR_DIRECTORY) {
11207 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011208
Joe Pamerc8c02492018-09-25 10:57:36 -040011209 dir_path = PyMem_New(wchar_t, path->length + 1);
11210 if (dir_path == NULL) {
11211 return PyErr_NoMemory();
11212 }
11213
11214 wcscpy_s(dir_path, path->length + 1, path->wide);
11215
11216 if (_dirnameW(dir_path) != -1) {
11217 Py_BEGIN_ALLOW_THREADS
11218 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
11219 Py_END_ALLOW_THREADS
11220 }
11221 /* Record the last error in case it's modified by PyMem_Free. */
11222 err = GetLastError();
11223 PyMem_Free(dir_path);
11224 if (retval) {
11225 goto success;
11226 }
11227 }
11228 return PyErr_SetFromWindowsErr(err);
11229 }
11230
11231success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011232 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
11233}
Larry Hastings2f936352014-08-05 14:04:04 +100011234#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011235
11236
Fred Drakec9680921999-12-13 16:37:25 +000011237/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
11238 * It maps strings representing configuration variable names to
11239 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000011240 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000011241 * rarely-used constants. There are three separate tables that use
11242 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000011243 *
11244 * This code is always included, even if none of the interfaces that
11245 * need it are included. The #if hackery needed to avoid it would be
11246 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000011247 */
11248struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011249 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011250 int value;
Fred Drakec9680921999-12-13 16:37:25 +000011251};
11252
Fred Drake12c6e2d1999-12-14 21:25:03 +000011253static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011254conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000011255 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000011256{
Christian Heimes217cfd12007-12-02 14:31:20 +000011257 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011258 int value = _PyLong_AsInt(arg);
11259 if (value == -1 && PyErr_Occurred())
11260 return 0;
11261 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000011262 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000011263 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000011264 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000011265 /* look up the value in the table using a binary search */
11266 size_t lo = 0;
11267 size_t mid;
11268 size_t hi = tablesize;
11269 int cmp;
11270 const char *confname;
11271 if (!PyUnicode_Check(arg)) {
11272 PyErr_SetString(PyExc_TypeError,
11273 "configuration names must be strings or integers");
11274 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011275 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020011276 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000011277 if (confname == NULL)
11278 return 0;
11279 while (lo < hi) {
11280 mid = (lo + hi) / 2;
11281 cmp = strcmp(confname, table[mid].name);
11282 if (cmp < 0)
11283 hi = mid;
11284 else if (cmp > 0)
11285 lo = mid + 1;
11286 else {
11287 *valuep = table[mid].value;
11288 return 1;
11289 }
11290 }
11291 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
11292 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011293 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000011294}
11295
11296
11297#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
11298static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011299#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011300 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011301#endif
11302#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011303 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011304#endif
Fred Drakec9680921999-12-13 16:37:25 +000011305#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011306 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011307#endif
11308#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000011309 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000011310#endif
11311#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000011313#endif
11314#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000011315 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000011316#endif
11317#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011318 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011319#endif
11320#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000011321 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000011322#endif
11323#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011324 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000011325#endif
11326#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011327 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011328#endif
11329#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011330 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000011331#endif
11332#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011334#endif
11335#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011336 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000011337#endif
11338#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011339 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011340#endif
11341#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011342 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000011343#endif
11344#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011345 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011346#endif
11347#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011348 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000011349#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000011350#ifdef _PC_ACL_ENABLED
11351 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
11352#endif
11353#ifdef _PC_MIN_HOLE_SIZE
11354 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
11355#endif
11356#ifdef _PC_ALLOC_SIZE_MIN
11357 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
11358#endif
11359#ifdef _PC_REC_INCR_XFER_SIZE
11360 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
11361#endif
11362#ifdef _PC_REC_MAX_XFER_SIZE
11363 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
11364#endif
11365#ifdef _PC_REC_MIN_XFER_SIZE
11366 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
11367#endif
11368#ifdef _PC_REC_XFER_ALIGN
11369 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
11370#endif
11371#ifdef _PC_SYMLINK_MAX
11372 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
11373#endif
11374#ifdef _PC_XATTR_ENABLED
11375 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
11376#endif
11377#ifdef _PC_XATTR_EXISTS
11378 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
11379#endif
11380#ifdef _PC_TIMESTAMP_RESOLUTION
11381 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
11382#endif
Fred Drakec9680921999-12-13 16:37:25 +000011383};
11384
Fred Drakec9680921999-12-13 16:37:25 +000011385static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011386conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011387{
11388 return conv_confname(arg, valuep, posix_constants_pathconf,
11389 sizeof(posix_constants_pathconf)
11390 / sizeof(struct constdef));
11391}
11392#endif
11393
Larry Hastings2f936352014-08-05 14:04:04 +100011394
Fred Drakec9680921999-12-13 16:37:25 +000011395#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011396/*[clinic input]
11397os.fpathconf -> long
11398
11399 fd: int
11400 name: path_confname
11401 /
11402
11403Return the configuration limit name for the file descriptor fd.
11404
11405If there is no limit, return -1.
11406[clinic start generated code]*/
11407
Larry Hastings2f936352014-08-05 14:04:04 +100011408static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011409os_fpathconf_impl(PyObject *module, int fd, int name)
11410/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011411{
11412 long limit;
11413
11414 errno = 0;
11415 limit = fpathconf(fd, name);
11416 if (limit == -1 && errno != 0)
11417 posix_error();
11418
11419 return limit;
11420}
11421#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011422
11423
11424#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011425/*[clinic input]
11426os.pathconf -> long
11427 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
11428 name: path_confname
11429
11430Return the configuration limit name for the file or directory path.
11431
11432If there is no limit, return -1.
11433On some platforms, path may also be specified as an open file descriptor.
11434 If this functionality is unavailable, using it raises an exception.
11435[clinic start generated code]*/
11436
Larry Hastings2f936352014-08-05 14:04:04 +100011437static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011438os_pathconf_impl(PyObject *module, path_t *path, int name)
11439/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011440{
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000011442
Victor Stinner8c62be82010-05-06 00:08:46 +000011443 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020011444#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011445 if (path->fd != -1)
11446 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020011447 else
11448#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011449 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000011450 if (limit == -1 && errno != 0) {
11451 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000011452 /* could be a path or name problem */
11453 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000011454 else
Larry Hastings2f936352014-08-05 14:04:04 +100011455 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000011456 }
Larry Hastings2f936352014-08-05 14:04:04 +100011457
11458 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000011459}
Larry Hastings2f936352014-08-05 14:04:04 +100011460#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011461
11462#ifdef HAVE_CONFSTR
11463static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011464#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000011466#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000011467#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011468 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011469#endif
11470#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011472#endif
Fred Draked86ed291999-12-15 15:34:33 +000011473#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011474 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011475#endif
11476#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011477 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011478#endif
11479#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011480 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011481#endif
11482#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011484#endif
Fred Drakec9680921999-12-13 16:37:25 +000011485#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011486 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011487#endif
11488#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011489 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011490#endif
11491#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011492 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011493#endif
11494#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011495 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011496#endif
11497#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011498 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011499#endif
11500#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011501 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011502#endif
11503#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011504 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011505#endif
11506#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011507 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011508#endif
Fred Draked86ed291999-12-15 15:34:33 +000011509#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000011510 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000011511#endif
Fred Drakec9680921999-12-13 16:37:25 +000011512#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000011513 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000011514#endif
Fred Draked86ed291999-12-15 15:34:33 +000011515#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011516 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000011517#endif
11518#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011519 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000011520#endif
11521#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011522 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011523#endif
11524#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011525 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000011526#endif
Fred Drakec9680921999-12-13 16:37:25 +000011527#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011529#endif
11530#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011531 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011532#endif
11533#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011535#endif
11536#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011537 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011538#endif
11539#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011540 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011541#endif
11542#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011544#endif
11545#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011547#endif
11548#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011549 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011550#endif
11551#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011553#endif
11554#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011556#endif
11557#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011559#endif
11560#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011561 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011562#endif
11563#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011564 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011565#endif
11566#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011567 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011568#endif
11569#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011570 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011571#endif
11572#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011573 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011574#endif
Fred Draked86ed291999-12-15 15:34:33 +000011575#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011576 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011577#endif
11578#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011579 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011580#endif
11581#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011582 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011583#endif
11584#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011585 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011586#endif
11587#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011588 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011589#endif
11590#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011591 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011592#endif
11593#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011594 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011595#endif
11596#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011597 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011598#endif
11599#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011600 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011601#endif
11602#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011603 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011604#endif
11605#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011606 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011607#endif
11608#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011609 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011610#endif
11611#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011612 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011613#endif
Fred Drakec9680921999-12-13 16:37:25 +000011614};
11615
11616static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011617conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011618{
11619 return conv_confname(arg, valuep, posix_constants_confstr,
11620 sizeof(posix_constants_confstr)
11621 / sizeof(struct constdef));
11622}
11623
Larry Hastings2f936352014-08-05 14:04:04 +100011624
11625/*[clinic input]
11626os.confstr
11627
11628 name: confstr_confname
11629 /
11630
11631Return a string-valued system configuration variable.
11632[clinic start generated code]*/
11633
Larry Hastings2f936352014-08-05 14:04:04 +100011634static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011635os_confstr_impl(PyObject *module, int name)
11636/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011637{
11638 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011639 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011640 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011641
Victor Stinnercb043522010-09-10 23:49:04 +000011642 errno = 0;
11643 len = confstr(name, buffer, sizeof(buffer));
11644 if (len == 0) {
11645 if (errno) {
11646 posix_error();
11647 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011648 }
11649 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011650 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011651 }
11652 }
Victor Stinnercb043522010-09-10 23:49:04 +000011653
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011654 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011655 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011656 char *buf = PyMem_Malloc(len);
11657 if (buf == NULL)
11658 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011659 len2 = confstr(name, buf, len);
11660 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011661 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011662 PyMem_Free(buf);
11663 }
11664 else
11665 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011666 return result;
11667}
Larry Hastings2f936352014-08-05 14:04:04 +100011668#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011669
11670
11671#ifdef HAVE_SYSCONF
11672static struct constdef posix_constants_sysconf[] = {
11673#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011674 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011675#endif
11676#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011677 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011678#endif
11679#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011680 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011681#endif
11682#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011683 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011684#endif
11685#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011686 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011687#endif
11688#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011689 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011690#endif
11691#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011692 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011693#endif
11694#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011695 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011696#endif
11697#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011698 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011699#endif
11700#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011701 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011702#endif
Fred Draked86ed291999-12-15 15:34:33 +000011703#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011704 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011705#endif
11706#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011707 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011708#endif
Fred Drakec9680921999-12-13 16:37:25 +000011709#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011710 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011711#endif
Fred Drakec9680921999-12-13 16:37:25 +000011712#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011713 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011714#endif
11715#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011716 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011717#endif
11718#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011719 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011720#endif
11721#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011722 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011723#endif
11724#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011725 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011726#endif
Fred Draked86ed291999-12-15 15:34:33 +000011727#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011728 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011729#endif
Fred Drakec9680921999-12-13 16:37:25 +000011730#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011731 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011732#endif
11733#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011734 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011735#endif
11736#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011737 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011738#endif
11739#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011740 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011741#endif
11742#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011743 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011744#endif
Fred Draked86ed291999-12-15 15:34:33 +000011745#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011746 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011747#endif
Fred Drakec9680921999-12-13 16:37:25 +000011748#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011749 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011750#endif
11751#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011752 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011753#endif
11754#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011755 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011756#endif
11757#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011758 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011759#endif
11760#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011761 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011762#endif
11763#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011764 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011765#endif
11766#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011767 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011768#endif
11769#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011770 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011771#endif
11772#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011773 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011774#endif
11775#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011776 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011777#endif
11778#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011779 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011780#endif
11781#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011782 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011783#endif
11784#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011785 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011786#endif
11787#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011788 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011789#endif
11790#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011791 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011792#endif
11793#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011794 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011795#endif
11796#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011797 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011798#endif
11799#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011800 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011801#endif
11802#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011803 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011804#endif
11805#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011806 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011807#endif
11808#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011809 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011810#endif
11811#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011812 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011813#endif
11814#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011815 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011816#endif
Fred Draked86ed291999-12-15 15:34:33 +000011817#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011818 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011819#endif
Fred Drakec9680921999-12-13 16:37:25 +000011820#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011821 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011822#endif
11823#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011824 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011825#endif
11826#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011827 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011828#endif
Fred Draked86ed291999-12-15 15:34:33 +000011829#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011830 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011831#endif
Fred Drakec9680921999-12-13 16:37:25 +000011832#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011833 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011834#endif
Fred Draked86ed291999-12-15 15:34:33 +000011835#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011836 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011837#endif
11838#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011839 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011840#endif
Fred Drakec9680921999-12-13 16:37:25 +000011841#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011842 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011843#endif
11844#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011845 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011846#endif
11847#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011848 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011849#endif
11850#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011851 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011852#endif
Fred Draked86ed291999-12-15 15:34:33 +000011853#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011854 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011855#endif
Fred Drakec9680921999-12-13 16:37:25 +000011856#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011857 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011858#endif
11859#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011860 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011861#endif
11862#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011863 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011864#endif
11865#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011866 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011867#endif
11868#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011869 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011870#endif
11871#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011872 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011873#endif
11874#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011875 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011876#endif
Fred Draked86ed291999-12-15 15:34:33 +000011877#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011878 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011879#endif
Fred Drakec9680921999-12-13 16:37:25 +000011880#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011881 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011882#endif
11883#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011884 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011885#endif
Fred Draked86ed291999-12-15 15:34:33 +000011886#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011887 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011888#endif
Fred Drakec9680921999-12-13 16:37:25 +000011889#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011890 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011891#endif
11892#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011893 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011894#endif
11895#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011896 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011897#endif
11898#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011899 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011900#endif
11901#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011902 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011903#endif
11904#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011905 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011906#endif
11907#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011908 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011909#endif
11910#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011911 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011912#endif
11913#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011914 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011915#endif
Fred Draked86ed291999-12-15 15:34:33 +000011916#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011917 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011918#endif
11919#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011920 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011921#endif
Fred Drakec9680921999-12-13 16:37:25 +000011922#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011923 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011924#endif
11925#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011926 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011927#endif
11928#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011929 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011930#endif
11931#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011932 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011933#endif
Batuhan Taşkaya909f4a32020-04-05 03:40:49 +030011934#ifdef _SC_AIX_REALMEM
11935 {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
11936#endif
Fred Drakec9680921999-12-13 16:37:25 +000011937#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011938 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011939#endif
11940#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011941 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011942#endif
11943#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011944 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011945#endif
11946#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011947 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011948#endif
11949#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011950 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011951#endif
11952#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011953 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011954#endif
11955#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011956 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011957#endif
11958#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011959 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011960#endif
11961#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011962 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011963#endif
11964#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011965 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011966#endif
11967#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011968 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011969#endif
11970#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011971 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011972#endif
11973#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011974 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011975#endif
11976#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011977 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011978#endif
11979#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011980 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011981#endif
11982#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011983 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011984#endif
11985#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011986 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011987#endif
11988#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011989 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011990#endif
11991#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011992 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011993#endif
11994#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011995 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011996#endif
11997#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011998 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011999#endif
12000#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012001 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000012002#endif
12003#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000012004 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000012005#endif
12006#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012007 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012008#endif
12009#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012010 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012011#endif
12012#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012013 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000012014#endif
12015#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012016 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012017#endif
12018#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012019 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012020#endif
12021#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012022 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012023#endif
12024#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012025 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012026#endif
12027#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012028 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012029#endif
Fred Draked86ed291999-12-15 15:34:33 +000012030#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000012031 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000012032#endif
Fred Drakec9680921999-12-13 16:37:25 +000012033#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000012034 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000012035#endif
12036#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012037 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012038#endif
12039#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000012040 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000012041#endif
12042#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012043 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012044#endif
12045#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012046 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012047#endif
12048#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012049 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012050#endif
12051#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000012052 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000012053#endif
12054#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012055 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012056#endif
12057#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012058 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012059#endif
12060#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012061 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012062#endif
12063#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012064 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012065#endif
12066#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012067 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000012068#endif
12069#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012070 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000012071#endif
12072#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000012073 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000012074#endif
12075#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012076 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012077#endif
12078#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012079 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012080#endif
12081#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012082 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012083#endif
12084#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000012085 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000012086#endif
12087#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012088 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012089#endif
12090#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012091 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012092#endif
12093#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012094 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012095#endif
12096#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012097 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012098#endif
12099#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012100 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012101#endif
12102#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012103 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012104#endif
12105#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000012106 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000012107#endif
12108#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012109 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012110#endif
12111#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012112 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012113#endif
12114#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012115 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012116#endif
12117#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012118 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000012119#endif
12120#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000012121 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000012122#endif
12123#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012124 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012125#endif
12126#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000012127 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000012128#endif
12129#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012130 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012131#endif
12132#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000012133 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000012134#endif
12135#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000012136 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000012137#endif
12138#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000012139 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000012140#endif
12141#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012142 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000012143#endif
12144#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012145 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012146#endif
12147#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000012148 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000012149#endif
12150#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000012151 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000012152#endif
12153#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012154 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012155#endif
12156#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012157 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012158#endif
12159#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000012160 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000012161#endif
12162#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000012163 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000012164#endif
12165#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000012166 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000012167#endif
12168};
12169
12170static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012171conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000012172{
12173 return conv_confname(arg, valuep, posix_constants_sysconf,
12174 sizeof(posix_constants_sysconf)
12175 / sizeof(struct constdef));
12176}
12177
Larry Hastings2f936352014-08-05 14:04:04 +100012178
12179/*[clinic input]
12180os.sysconf -> long
12181 name: sysconf_confname
12182 /
12183
12184Return an integer-valued system configuration variable.
12185[clinic start generated code]*/
12186
Larry Hastings2f936352014-08-05 14:04:04 +100012187static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012188os_sysconf_impl(PyObject *module, int name)
12189/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012190{
12191 long value;
12192
12193 errno = 0;
12194 value = sysconf(name);
12195 if (value == -1 && errno != 0)
12196 posix_error();
12197 return value;
12198}
12199#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000012200
12201
Fred Drakebec628d1999-12-15 18:31:10 +000012202/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020012203 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000012204 * the exported dictionaries that are used to publish information about the
12205 * names available on the host platform.
12206 *
12207 * Sorting the table at runtime ensures that the table is properly ordered
12208 * when used, even for platforms we're not able to test on. It also makes
12209 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000012210 */
Fred Drakebec628d1999-12-15 18:31:10 +000012211
12212static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012213cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000012214{
12215 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012216 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000012217 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012218 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000012219
12220 return strcmp(c1->name, c2->name);
12221}
12222
12223static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012224setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012225 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012226{
Fred Drakebec628d1999-12-15 18:31:10 +000012227 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000012228 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000012229
12230 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
12231 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000012232 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000012233 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012234
Barry Warsaw3155db32000-04-13 15:20:40 +000012235 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000012236 PyObject *o = PyLong_FromLong(table[i].value);
12237 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
12238 Py_XDECREF(o);
12239 Py_DECREF(d);
12240 return -1;
12241 }
12242 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000012243 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000012244 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000012245}
12246
Fred Drakebec628d1999-12-15 18:31:10 +000012247/* Return -1 on failure, 0 on success. */
12248static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000012249setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012250{
12251#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000012252 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000012253 sizeof(posix_constants_pathconf)
12254 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012255 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012256 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012257#endif
12258#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000012259 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000012260 sizeof(posix_constants_confstr)
12261 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012262 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012263 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012264#endif
12265#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000012266 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000012267 sizeof(posix_constants_sysconf)
12268 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012269 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012270 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012271#endif
Fred Drakebec628d1999-12-15 18:31:10 +000012272 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000012273}
Fred Draked86ed291999-12-15 15:34:33 +000012274
12275
Larry Hastings2f936352014-08-05 14:04:04 +100012276/*[clinic input]
12277os.abort
12278
12279Abort the interpreter immediately.
12280
12281This function 'dumps core' or otherwise fails in the hardest way possible
12282on the hosting operating system. This function never returns.
12283[clinic start generated code]*/
12284
Larry Hastings2f936352014-08-05 14:04:04 +100012285static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012286os_abort_impl(PyObject *module)
12287/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012288{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012289 abort();
12290 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010012291#ifndef __clang__
12292 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
12293 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
12294 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012295 Py_FatalError("abort() called from Python code didn't abort!");
12296 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010012297#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012298}
Fred Drakebec628d1999-12-15 18:31:10 +000012299
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000012300#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012301/* Grab ShellExecute dynamically from shell32 */
12302static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012303static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
12304 LPCWSTR, INT);
12305static int
12306check_ShellExecute()
12307{
12308 HINSTANCE hShell32;
12309
12310 /* only recheck */
12311 if (-1 == has_ShellExecute) {
12312 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070012313 /* Security note: this call is not vulnerable to "DLL hijacking".
12314 SHELL32 is part of "KnownDLLs" and so Windows always load
12315 the system SHELL32.DLL, even if there is another SHELL32.DLL
12316 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080012317 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080012318 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080012319 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
12320 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070012321 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012322 } else {
12323 has_ShellExecute = 0;
12324 }
Tony Roberts4860f012019-02-02 18:16:42 +010012325 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012326 }
12327 return has_ShellExecute;
12328}
12329
12330
Steve Dowercc16be82016-09-08 10:35:16 -070012331/*[clinic input]
12332os.startfile
12333 filepath: path_t
12334 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000012335
Steve Dowercc16be82016-09-08 10:35:16 -070012336Start a file with its associated application.
12337
12338When "operation" is not specified or "open", this acts like
12339double-clicking the file in Explorer, or giving the file name as an
12340argument to the DOS "start" command: the file is opened with whatever
12341application (if any) its extension is associated.
12342When another "operation" is given, it specifies what should be done with
12343the file. A typical operation is "print".
12344
12345startfile returns as soon as the associated application is launched.
12346There is no option to wait for the application to close, and no way
12347to retrieve the application's exit status.
12348
12349The filepath is relative to the current directory. If you want to use
12350an absolute path, make sure the first character is not a slash ("/");
12351the underlying Win32 ShellExecute function doesn't work if it is.
12352[clinic start generated code]*/
12353
12354static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020012355os_startfile_impl(PyObject *module, path_t *filepath,
12356 const Py_UNICODE *operation)
Serhiy Storchaka279f4462019-09-14 12:24:05 +030012357/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
Steve Dowercc16be82016-09-08 10:35:16 -070012358{
12359 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012360
12361 if(!check_ShellExecute()) {
12362 /* If the OS doesn't have ShellExecute, return a
12363 NotImplementedError. */
12364 return PyErr_Format(PyExc_NotImplementedError,
12365 "startfile not available on this platform");
12366 }
12367
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012368 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080012369 return NULL;
12370 }
12371
Victor Stinner8c62be82010-05-06 00:08:46 +000012372 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070012373 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080012374 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000012375 Py_END_ALLOW_THREADS
12376
Victor Stinner8c62be82010-05-06 00:08:46 +000012377 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070012378 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020012379 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012380 }
Steve Dowercc16be82016-09-08 10:35:16 -070012381 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000012382}
Larry Hastings2f936352014-08-05 14:04:04 +100012383#endif /* MS_WINDOWS */
12384
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012385
Martin v. Löwis438b5342002-12-27 10:16:42 +000012386#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100012387/*[clinic input]
12388os.getloadavg
12389
12390Return average recent system load information.
12391
12392Return the number of processes in the system run queue averaged over
12393the last 1, 5, and 15 minutes as a tuple of three floats.
12394Raises OSError if the load average was unobtainable.
12395[clinic start generated code]*/
12396
Larry Hastings2f936352014-08-05 14:04:04 +100012397static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012398os_getloadavg_impl(PyObject *module)
12399/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000012400{
12401 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000012402 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000012403 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
12404 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000012405 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000012406 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000012407}
Larry Hastings2f936352014-08-05 14:04:04 +100012408#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000012409
Larry Hastings2f936352014-08-05 14:04:04 +100012410
12411/*[clinic input]
12412os.device_encoding
12413 fd: int
12414
12415Return a string describing the encoding of a terminal's file descriptor.
12416
12417The file descriptor must be attached to a terminal.
12418If the device is not a terminal, return None.
12419[clinic start generated code]*/
12420
Larry Hastings2f936352014-08-05 14:04:04 +100012421static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012422os_device_encoding_impl(PyObject *module, int fd)
12423/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012424{
Brett Cannonefb00c02012-02-29 18:31:31 -050012425 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000012426}
12427
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012428
Larry Hastings2f936352014-08-05 14:04:04 +100012429#ifdef HAVE_SETRESUID
12430/*[clinic input]
12431os.setresuid
12432
12433 ruid: uid_t
12434 euid: uid_t
12435 suid: uid_t
12436 /
12437
12438Set the current process's real, effective, and saved user ids.
12439[clinic start generated code]*/
12440
Larry Hastings2f936352014-08-05 14:04:04 +100012441static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012442os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
12443/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012444{
Victor Stinner8c62be82010-05-06 00:08:46 +000012445 if (setresuid(ruid, euid, suid) < 0)
12446 return posix_error();
12447 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012448}
Larry Hastings2f936352014-08-05 14:04:04 +100012449#endif /* HAVE_SETRESUID */
12450
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012451
12452#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012453/*[clinic input]
12454os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012455
Larry Hastings2f936352014-08-05 14:04:04 +100012456 rgid: gid_t
12457 egid: gid_t
12458 sgid: gid_t
12459 /
12460
12461Set the current process's real, effective, and saved group ids.
12462[clinic start generated code]*/
12463
Larry Hastings2f936352014-08-05 14:04:04 +100012464static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012465os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12466/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012467{
Victor Stinner8c62be82010-05-06 00:08:46 +000012468 if (setresgid(rgid, egid, sgid) < 0)
12469 return posix_error();
12470 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012471}
Larry Hastings2f936352014-08-05 14:04:04 +100012472#endif /* HAVE_SETRESGID */
12473
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012474
12475#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100012476/*[clinic input]
12477os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012478
Larry Hastings2f936352014-08-05 14:04:04 +100012479Return a tuple of the current process's real, effective, and saved user ids.
12480[clinic start generated code]*/
12481
Larry Hastings2f936352014-08-05 14:04:04 +100012482static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012483os_getresuid_impl(PyObject *module)
12484/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012485{
Victor Stinner8c62be82010-05-06 00:08:46 +000012486 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012487 if (getresuid(&ruid, &euid, &suid) < 0)
12488 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012489 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
12490 _PyLong_FromUid(euid),
12491 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012492}
Larry Hastings2f936352014-08-05 14:04:04 +100012493#endif /* HAVE_GETRESUID */
12494
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012495
12496#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012497/*[clinic input]
12498os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012499
Larry Hastings2f936352014-08-05 14:04:04 +100012500Return a tuple of the current process's real, effective, and saved group ids.
12501[clinic start generated code]*/
12502
Larry Hastings2f936352014-08-05 14:04:04 +100012503static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012504os_getresgid_impl(PyObject *module)
12505/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012506{
12507 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012508 if (getresgid(&rgid, &egid, &sgid) < 0)
12509 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012510 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
12511 _PyLong_FromGid(egid),
12512 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012513}
Larry Hastings2f936352014-08-05 14:04:04 +100012514#endif /* HAVE_GETRESGID */
12515
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012516
Benjamin Peterson9428d532011-09-14 11:45:52 -040012517#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100012518/*[clinic input]
12519os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040012520
Larry Hastings2f936352014-08-05 14:04:04 +100012521 path: path_t(allow_fd=True)
12522 attribute: path_t
12523 *
12524 follow_symlinks: bool = True
12525
12526Return the value of extended attribute attribute on path.
12527
BNMetricsb9427072018-11-02 15:20:19 +000012528path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012529If follow_symlinks is False, and the last element of the path is a symbolic
12530 link, getxattr will examine the symbolic link itself instead of the file
12531 the link points to.
12532
12533[clinic start generated code]*/
12534
Larry Hastings2f936352014-08-05 14:04:04 +100012535static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012536os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012537 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012538/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012539{
12540 Py_ssize_t i;
12541 PyObject *buffer = NULL;
12542
12543 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12544 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012545
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012546 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12547 return NULL;
12548 }
12549
Larry Hastings9cf065c2012-06-22 16:30:09 -070012550 for (i = 0; ; i++) {
12551 void *ptr;
12552 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012553 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012554 Py_ssize_t buffer_size = buffer_sizes[i];
12555 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012556 path_error(path);
12557 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012558 }
12559 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12560 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012561 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012562 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012563
Larry Hastings9cf065c2012-06-22 16:30:09 -070012564 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012565 if (path->fd >= 0)
12566 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012567 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012568 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012569 else
Larry Hastings2f936352014-08-05 14:04:04 +100012570 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012571 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012572
Larry Hastings9cf065c2012-06-22 16:30:09 -070012573 if (result < 0) {
12574 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012575 if (errno == ERANGE)
12576 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012577 path_error(path);
12578 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012579 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012580
Larry Hastings9cf065c2012-06-22 16:30:09 -070012581 if (result != buffer_size) {
12582 /* Can only shrink. */
12583 _PyBytes_Resize(&buffer, result);
12584 }
12585 break;
12586 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012587
Larry Hastings9cf065c2012-06-22 16:30:09 -070012588 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012589}
12590
Larry Hastings2f936352014-08-05 14:04:04 +100012591
12592/*[clinic input]
12593os.setxattr
12594
12595 path: path_t(allow_fd=True)
12596 attribute: path_t
12597 value: Py_buffer
12598 flags: int = 0
12599 *
12600 follow_symlinks: bool = True
12601
12602Set extended attribute attribute on path to value.
12603
BNMetricsb9427072018-11-02 15:20:19 +000012604path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012605If follow_symlinks is False, and the last element of the path is a symbolic
12606 link, setxattr will modify the symbolic link itself instead of the file
12607 the link points to.
12608
12609[clinic start generated code]*/
12610
Benjamin Peterson799bd802011-08-31 22:15:17 -040012611static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012612os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012613 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012614/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012615{
Larry Hastings2f936352014-08-05 14:04:04 +100012616 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012617
Larry Hastings2f936352014-08-05 14:04:04 +100012618 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012619 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012620
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012621 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12622 value->buf, value->len, flags) < 0) {
12623 return NULL;
12624 }
12625
Benjamin Peterson799bd802011-08-31 22:15:17 -040012626 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012627 if (path->fd > -1)
12628 result = fsetxattr(path->fd, attribute->narrow,
12629 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012630 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012631 result = setxattr(path->narrow, attribute->narrow,
12632 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012633 else
Larry Hastings2f936352014-08-05 14:04:04 +100012634 result = lsetxattr(path->narrow, attribute->narrow,
12635 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012636 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012637
Larry Hastings9cf065c2012-06-22 16:30:09 -070012638 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012639 path_error(path);
12640 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012641 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012642
Larry Hastings2f936352014-08-05 14:04:04 +100012643 Py_RETURN_NONE;
12644}
12645
12646
12647/*[clinic input]
12648os.removexattr
12649
12650 path: path_t(allow_fd=True)
12651 attribute: path_t
12652 *
12653 follow_symlinks: bool = True
12654
12655Remove extended attribute attribute on path.
12656
BNMetricsb9427072018-11-02 15:20:19 +000012657path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012658If follow_symlinks is False, and the last element of the path is a symbolic
12659 link, removexattr will modify the symbolic link itself instead of the file
12660 the link points to.
12661
12662[clinic start generated code]*/
12663
Larry Hastings2f936352014-08-05 14:04:04 +100012664static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012665os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012666 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012667/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012668{
12669 ssize_t result;
12670
12671 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12672 return NULL;
12673
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012674 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12675 return NULL;
12676 }
12677
Larry Hastings2f936352014-08-05 14:04:04 +100012678 Py_BEGIN_ALLOW_THREADS;
12679 if (path->fd > -1)
12680 result = fremovexattr(path->fd, attribute->narrow);
12681 else if (follow_symlinks)
12682 result = removexattr(path->narrow, attribute->narrow);
12683 else
12684 result = lremovexattr(path->narrow, attribute->narrow);
12685 Py_END_ALLOW_THREADS;
12686
12687 if (result) {
12688 return path_error(path);
12689 }
12690
12691 Py_RETURN_NONE;
12692}
12693
12694
12695/*[clinic input]
12696os.listxattr
12697
12698 path: path_t(allow_fd=True, nullable=True) = None
12699 *
12700 follow_symlinks: bool = True
12701
12702Return a list of extended attributes on path.
12703
BNMetricsb9427072018-11-02 15:20:19 +000012704path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012705if path is None, listxattr will examine the current directory.
12706If follow_symlinks is False, and the last element of the path is a symbolic
12707 link, listxattr will examine the symbolic link itself instead of the file
12708 the link points to.
12709[clinic start generated code]*/
12710
Larry Hastings2f936352014-08-05 14:04:04 +100012711static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012712os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012713/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012714{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012715 Py_ssize_t i;
12716 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012717 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012718 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012719
Larry Hastings2f936352014-08-05 14:04:04 +100012720 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012721 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012722
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012723 if (PySys_Audit("os.listxattr", "(O)",
12724 path->object ? path->object : Py_None) < 0) {
12725 return NULL;
12726 }
12727
Larry Hastings2f936352014-08-05 14:04:04 +100012728 name = path->narrow ? path->narrow : ".";
12729
Larry Hastings9cf065c2012-06-22 16:30:09 -070012730 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012731 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012732 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012733 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012734 Py_ssize_t buffer_size = buffer_sizes[i];
12735 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012736 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012737 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012738 break;
12739 }
12740 buffer = PyMem_MALLOC(buffer_size);
12741 if (!buffer) {
12742 PyErr_NoMemory();
12743 break;
12744 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012745
Larry Hastings9cf065c2012-06-22 16:30:09 -070012746 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012747 if (path->fd > -1)
12748 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012749 else if (follow_symlinks)
12750 length = listxattr(name, buffer, buffer_size);
12751 else
12752 length = llistxattr(name, buffer, buffer_size);
12753 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012754
Larry Hastings9cf065c2012-06-22 16:30:09 -070012755 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012756 if (errno == ERANGE) {
12757 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012758 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012759 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012760 }
Larry Hastings2f936352014-08-05 14:04:04 +100012761 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012762 break;
12763 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012764
Larry Hastings9cf065c2012-06-22 16:30:09 -070012765 result = PyList_New(0);
12766 if (!result) {
12767 goto exit;
12768 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012769
Larry Hastings9cf065c2012-06-22 16:30:09 -070012770 end = buffer + length;
12771 for (trace = start = buffer; trace != end; trace++) {
12772 if (!*trace) {
12773 int error;
12774 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12775 trace - start);
12776 if (!attribute) {
12777 Py_DECREF(result);
12778 result = NULL;
12779 goto exit;
12780 }
12781 error = PyList_Append(result, attribute);
12782 Py_DECREF(attribute);
12783 if (error) {
12784 Py_DECREF(result);
12785 result = NULL;
12786 goto exit;
12787 }
12788 start = trace + 1;
12789 }
12790 }
12791 break;
12792 }
12793exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012794 if (buffer)
12795 PyMem_FREE(buffer);
12796 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012797}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012798#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012799
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012800
Larry Hastings2f936352014-08-05 14:04:04 +100012801/*[clinic input]
12802os.urandom
12803
12804 size: Py_ssize_t
12805 /
12806
12807Return a bytes object containing random bytes suitable for cryptographic use.
12808[clinic start generated code]*/
12809
Larry Hastings2f936352014-08-05 14:04:04 +100012810static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012811os_urandom_impl(PyObject *module, Py_ssize_t size)
12812/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012813{
12814 PyObject *bytes;
12815 int result;
12816
Georg Brandl2fb477c2012-02-21 00:33:36 +010012817 if (size < 0)
12818 return PyErr_Format(PyExc_ValueError,
12819 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012820 bytes = PyBytes_FromStringAndSize(NULL, size);
12821 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012822 return NULL;
12823
Victor Stinnere66987e2016-09-06 16:33:52 -070012824 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012825 if (result == -1) {
12826 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012827 return NULL;
12828 }
Larry Hastings2f936352014-08-05 14:04:04 +100012829 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012830}
12831
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012832#ifdef HAVE_MEMFD_CREATE
12833/*[clinic input]
12834os.memfd_create
12835
12836 name: FSConverter
12837 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12838
12839[clinic start generated code]*/
12840
12841static PyObject *
12842os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12843/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12844{
12845 int fd;
12846 const char *bytes = PyBytes_AS_STRING(name);
12847 Py_BEGIN_ALLOW_THREADS
12848 fd = memfd_create(bytes, flags);
12849 Py_END_ALLOW_THREADS
12850 if (fd == -1) {
12851 return PyErr_SetFromErrno(PyExc_OSError);
12852 }
12853 return PyLong_FromLong(fd);
12854}
12855#endif
12856
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012857/* Terminal size querying */
12858
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012859PyDoc_STRVAR(TerminalSize_docstring,
12860 "A tuple of (columns, lines) for holding terminal window size");
12861
12862static PyStructSequence_Field TerminalSize_fields[] = {
12863 {"columns", "width of the terminal window in characters"},
12864 {"lines", "height of the terminal window in characters"},
12865 {NULL, NULL}
12866};
12867
12868static PyStructSequence_Desc TerminalSize_desc = {
12869 "os.terminal_size",
12870 TerminalSize_docstring,
12871 TerminalSize_fields,
12872 2,
12873};
12874
12875#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012876/*[clinic input]
12877os.get_terminal_size
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012878
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012879 fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
12880 /
12881
12882Return the size of the terminal window as (columns, lines).
12883
12884The optional argument fd (default standard output) specifies
12885which file descriptor should be queried.
12886
12887If the file descriptor is not connected to a terminal, an OSError
12888is thrown.
12889
12890This function will only be defined if an implementation is
12891available for this system.
12892
12893shutil.get_terminal_size is the high-level function which should
12894normally be used, os.get_terminal_size is the low-level implementation.
12895[clinic start generated code]*/
12896
12897static PyObject *
12898os_get_terminal_size_impl(PyObject *module, int fd)
12899/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012900{
12901 int columns, lines;
12902 PyObject *termsize;
12903
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012904 /* Under some conditions stdout may not be connected and
12905 * fileno(stdout) may point to an invalid file descriptor. For example
12906 * GUI apps don't have valid standard streams by default.
12907 *
12908 * If this happens, and the optional fd argument is not present,
12909 * the ioctl below will fail returning EBADF. This is what we want.
12910 */
12911
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012912#ifdef TERMSIZE_USE_IOCTL
12913 {
12914 struct winsize w;
12915 if (ioctl(fd, TIOCGWINSZ, &w))
12916 return PyErr_SetFromErrno(PyExc_OSError);
12917 columns = w.ws_col;
12918 lines = w.ws_row;
12919 }
12920#endif /* TERMSIZE_USE_IOCTL */
12921
12922#ifdef TERMSIZE_USE_CONIO
12923 {
12924 DWORD nhandle;
12925 HANDLE handle;
12926 CONSOLE_SCREEN_BUFFER_INFO csbi;
12927 switch (fd) {
12928 case 0: nhandle = STD_INPUT_HANDLE;
12929 break;
12930 case 1: nhandle = STD_OUTPUT_HANDLE;
12931 break;
12932 case 2: nhandle = STD_ERROR_HANDLE;
12933 break;
12934 default:
12935 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12936 }
12937 handle = GetStdHandle(nhandle);
12938 if (handle == NULL)
12939 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12940 if (handle == INVALID_HANDLE_VALUE)
12941 return PyErr_SetFromWindowsErr(0);
12942
12943 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12944 return PyErr_SetFromWindowsErr(0);
12945
12946 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12947 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12948 }
12949#endif /* TERMSIZE_USE_CONIO */
12950
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012951 PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080012952 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012953 if (termsize == NULL)
12954 return NULL;
12955 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12956 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12957 if (PyErr_Occurred()) {
12958 Py_DECREF(termsize);
12959 return NULL;
12960 }
12961 return termsize;
12962}
12963#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12964
Larry Hastings2f936352014-08-05 14:04:04 +100012965
12966/*[clinic input]
12967os.cpu_count
12968
Charles-François Natali80d62e62015-08-13 20:37:08 +010012969Return the number of CPUs in the system; return None if indeterminable.
12970
12971This number is not equivalent to the number of CPUs the current process can
12972use. The number of usable CPUs can be obtained with
12973``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012974[clinic start generated code]*/
12975
Larry Hastings2f936352014-08-05 14:04:04 +100012976static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012977os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012978/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012979{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012980 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012981#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010012982 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012983#elif defined(__hpux)
12984 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12985#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12986 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012987#elif defined(__DragonFly__) || \
12988 defined(__OpenBSD__) || \
12989 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012990 defined(__NetBSD__) || \
12991 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012992 int mib[2];
12993 size_t len = sizeof(ncpu);
12994 mib[0] = CTL_HW;
12995 mib[1] = HW_NCPU;
12996 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12997 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012998#endif
12999 if (ncpu >= 1)
13000 return PyLong_FromLong(ncpu);
13001 else
13002 Py_RETURN_NONE;
13003}
13004
Victor Stinnerdaf45552013-08-28 00:53:59 +020013005
Larry Hastings2f936352014-08-05 14:04:04 +100013006/*[clinic input]
13007os.get_inheritable -> bool
13008
13009 fd: int
13010 /
13011
13012Get the close-on-exe flag of the specified file descriptor.
13013[clinic start generated code]*/
13014
Larry Hastings2f936352014-08-05 14:04:04 +100013015static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013016os_get_inheritable_impl(PyObject *module, int fd)
13017/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013018{
Steve Dower8fc89802015-04-12 00:26:27 -040013019 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040013020 _Py_BEGIN_SUPPRESS_IPH
13021 return_value = _Py_get_inheritable(fd);
13022 _Py_END_SUPPRESS_IPH
13023 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100013024}
13025
13026
13027/*[clinic input]
13028os.set_inheritable
13029 fd: int
13030 inheritable: int
13031 /
13032
13033Set the inheritable flag of the specified file descriptor.
13034[clinic start generated code]*/
13035
Larry Hastings2f936352014-08-05 14:04:04 +100013036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013037os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
13038/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020013039{
Steve Dower8fc89802015-04-12 00:26:27 -040013040 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013041
Steve Dower8fc89802015-04-12 00:26:27 -040013042 _Py_BEGIN_SUPPRESS_IPH
13043 result = _Py_set_inheritable(fd, inheritable, NULL);
13044 _Py_END_SUPPRESS_IPH
13045 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020013046 return NULL;
13047 Py_RETURN_NONE;
13048}
13049
13050
13051#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100013052/*[clinic input]
13053os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070013054 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013055 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020013056
Larry Hastings2f936352014-08-05 14:04:04 +100013057Get the close-on-exe flag of the specified file descriptor.
13058[clinic start generated code]*/
13059
Larry Hastings2f936352014-08-05 14:04:04 +100013060static int
Benjamin Petersonca470632016-09-06 13:47:26 -070013061os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070013062/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013063{
13064 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013065
13066 if (!GetHandleInformation((HANDLE)handle, &flags)) {
13067 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100013068 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013069 }
13070
Larry Hastings2f936352014-08-05 14:04:04 +100013071 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013072}
13073
Victor Stinnerdaf45552013-08-28 00:53:59 +020013074
Larry Hastings2f936352014-08-05 14:04:04 +100013075/*[clinic input]
13076os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070013077 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013078 inheritable: bool
13079 /
13080
13081Set the inheritable flag of the specified handle.
13082[clinic start generated code]*/
13083
Larry Hastings2f936352014-08-05 14:04:04 +100013084static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070013085os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040013086 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070013087/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013088{
13089 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013090 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
13091 PyErr_SetFromWindowsErr(0);
13092 return NULL;
13093 }
13094 Py_RETURN_NONE;
13095}
Larry Hastings2f936352014-08-05 14:04:04 +100013096#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013097
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013098#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013099/*[clinic input]
13100os.get_blocking -> bool
13101 fd: int
13102 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013103
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013104Get the blocking mode of the file descriptor.
13105
13106Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
13107[clinic start generated code]*/
13108
13109static int
13110os_get_blocking_impl(PyObject *module, int fd)
13111/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013112{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013113 int blocking;
13114
Steve Dower8fc89802015-04-12 00:26:27 -040013115 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013116 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040013117 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013118 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013119}
13120
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013121/*[clinic input]
13122os.set_blocking
13123 fd: int
13124 blocking: bool(accept={int})
13125 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013126
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013127Set the blocking mode of the specified file descriptor.
13128
13129Set the O_NONBLOCK flag if blocking is False,
13130clear the O_NONBLOCK flag otherwise.
13131[clinic start generated code]*/
13132
13133static PyObject *
13134os_set_blocking_impl(PyObject *module, int fd, int blocking)
13135/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013136{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013137 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013138
Steve Dower8fc89802015-04-12 00:26:27 -040013139 _Py_BEGIN_SUPPRESS_IPH
13140 result = _Py_set_blocking(fd, blocking);
13141 _Py_END_SUPPRESS_IPH
13142 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013143 return NULL;
13144 Py_RETURN_NONE;
13145}
13146#endif /* !MS_WINDOWS */
13147
13148
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013149/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080013150class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013151[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080013152/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013153
13154typedef struct {
13155 PyObject_HEAD
13156 PyObject *name;
13157 PyObject *path;
13158 PyObject *stat;
13159 PyObject *lstat;
13160#ifdef MS_WINDOWS
13161 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010013162 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010013163 int got_file_index;
13164#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010013165#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013166 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013167#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013168 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013169 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010013170#endif
13171} DirEntry;
13172
Eddie Elizondob3966632019-11-05 07:16:14 -080013173static PyObject *
13174_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
13175{
13176 PyErr_Format(PyExc_TypeError,
13177 "cannot create '%.100s' instances", _PyType_Name(type));
13178 return NULL;
13179}
13180
Victor Stinner6036e442015-03-08 01:58:04 +010013181static void
13182DirEntry_dealloc(DirEntry *entry)
13183{
Eddie Elizondob3966632019-11-05 07:16:14 -080013184 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010013185 Py_XDECREF(entry->name);
13186 Py_XDECREF(entry->path);
13187 Py_XDECREF(entry->stat);
13188 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080013189 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13190 free_func(entry);
13191 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013192}
13193
13194/* Forward reference */
13195static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013196DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13197 int follow_symlinks, unsigned short mode_bits);
Victor Stinner6036e442015-03-08 01:58:04 +010013198
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013199/*[clinic input]
13200os.DirEntry.is_symlink -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013201 defining_class: defining_class
13202 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013203
13204Return True if the entry is a symbolic link; cached per entry.
13205[clinic start generated code]*/
13206
Victor Stinner6036e442015-03-08 01:58:04 +010013207static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013208os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
13209/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013210{
13211#ifdef MS_WINDOWS
13212 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010013213#elif defined(HAVE_DIRENT_D_TYPE)
13214 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013215 if (self->d_type != DT_UNKNOWN)
13216 return self->d_type == DT_LNK;
13217 else
Victor Stinner97f33c32020-05-14 18:05:58 +020013218 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010013219#else
13220 /* POSIX without d_type */
Victor Stinner97f33c32020-05-14 18:05:58 +020013221 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010013222#endif
13223}
13224
13225static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013226DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
Victor Stinner6036e442015-03-08 01:58:04 +010013227{
13228 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013229 STRUCT_STAT st;
13230 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010013231
13232#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013233 if (!PyUnicode_FSDecoder(self->path, &ub))
13234 return NULL;
13235 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010013236#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013237 if (!PyUnicode_FSConverter(self->path, &ub))
13238 return NULL;
13239 const char *path = PyBytes_AS_STRING(ub);
13240 if (self->dir_fd != DEFAULT_DIR_FD) {
13241#ifdef HAVE_FSTATAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +010013242 if (HAVE_FSTATAT_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013243 result = fstatat(self->dir_fd, path, &st,
13244 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussorene8b1c032020-11-22 11:18:40 +010013245 } else
13246
13247#endif /* HAVE_FSTATAT */
13248 {
13249 Py_DECREF(ub);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013250 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
13251 return NULL;
Ronald Oussorene8b1c032020-11-22 11:18:40 +010013252 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013253 }
13254 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013255#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013256 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013257 if (follow_symlinks)
13258 result = STAT(path, &st);
13259 else
13260 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013261 }
13262 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010013263
13264 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013265 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013266
Victor Stinner97f33c32020-05-14 18:05:58 +020013267 return _pystat_fromstructstat(module, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010013268}
13269
13270static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013271DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
Victor Stinner6036e442015-03-08 01:58:04 +010013272{
13273 if (!self->lstat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013274 PyObject *module = PyType_GetModule(defining_class);
Victor Stinner6036e442015-03-08 01:58:04 +010013275#ifdef MS_WINDOWS
Victor Stinner97f33c32020-05-14 18:05:58 +020013276 self->lstat = _pystat_fromstructstat(module, &self->win32_lstat);
Victor Stinner6036e442015-03-08 01:58:04 +010013277#else /* POSIX */
Victor Stinner97f33c32020-05-14 18:05:58 +020013278 self->lstat = DirEntry_fetch_stat(module, self, 0);
Victor Stinner6036e442015-03-08 01:58:04 +010013279#endif
13280 }
13281 Py_XINCREF(self->lstat);
13282 return self->lstat;
13283}
13284
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013285/*[clinic input]
13286os.DirEntry.stat
Victor Stinner97f33c32020-05-14 18:05:58 +020013287 defining_class: defining_class
13288 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013289 *
13290 follow_symlinks: bool = True
13291
13292Return stat_result object for the entry; cached per entry.
13293[clinic start generated code]*/
13294
Victor Stinner6036e442015-03-08 01:58:04 +010013295static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013296os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
13297 int follow_symlinks)
13298/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013299{
Victor Stinner97f33c32020-05-14 18:05:58 +020013300 if (!follow_symlinks) {
13301 return DirEntry_get_lstat(defining_class, self);
13302 }
Victor Stinner6036e442015-03-08 01:58:04 +010013303
13304 if (!self->stat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013305 int result = os_DirEntry_is_symlink_impl(self, defining_class);
13306 if (result == -1) {
Victor Stinner6036e442015-03-08 01:58:04 +010013307 return NULL;
Victor Stinner97f33c32020-05-14 18:05:58 +020013308 }
13309 if (result) {
13310 PyObject *module = PyType_GetModule(defining_class);
13311 self->stat = DirEntry_fetch_stat(module, self, 1);
13312 }
13313 else {
13314 self->stat = DirEntry_get_lstat(defining_class, self);
13315 }
Victor Stinner6036e442015-03-08 01:58:04 +010013316 }
13317
13318 Py_XINCREF(self->stat);
13319 return self->stat;
13320}
13321
Victor Stinner6036e442015-03-08 01:58:04 +010013322/* Set exception and return -1 on error, 0 for False, 1 for True */
13323static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013324DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13325 int follow_symlinks, unsigned short mode_bits)
Victor Stinner6036e442015-03-08 01:58:04 +010013326{
13327 PyObject *stat = NULL;
13328 PyObject *st_mode = NULL;
13329 long mode;
13330 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010013331#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013332 int is_symlink;
13333 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010013334#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013335#ifdef MS_WINDOWS
13336 unsigned long dir_bits;
13337#endif
13338
13339#ifdef MS_WINDOWS
13340 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
13341 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010013342#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013343 is_symlink = self->d_type == DT_LNK;
13344 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
13345#endif
13346
Victor Stinner35a97c02015-03-08 02:59:09 +010013347#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013348 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010013349#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020013350 stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010013351 if (!stat) {
13352 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
13353 /* If file doesn't exist (anymore), then return False
13354 (i.e., say it's not a file/directory) */
13355 PyErr_Clear();
13356 return 0;
13357 }
13358 goto error;
13359 }
Victor Stinner97f33c32020-05-14 18:05:58 +020013360 _posixstate* state = get_posix_state(PyType_GetModule(defining_class));
13361 st_mode = PyObject_GetAttr(stat, state->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010013362 if (!st_mode)
13363 goto error;
13364
13365 mode = PyLong_AsLong(st_mode);
13366 if (mode == -1 && PyErr_Occurred())
13367 goto error;
13368 Py_CLEAR(st_mode);
13369 Py_CLEAR(stat);
13370 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010013371#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013372 }
13373 else if (is_symlink) {
13374 assert(mode_bits != S_IFLNK);
13375 result = 0;
13376 }
13377 else {
13378 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
13379#ifdef MS_WINDOWS
13380 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
13381 if (mode_bits == S_IFDIR)
13382 result = dir_bits != 0;
13383 else
13384 result = dir_bits == 0;
13385#else /* POSIX */
13386 if (mode_bits == S_IFDIR)
13387 result = self->d_type == DT_DIR;
13388 else
13389 result = self->d_type == DT_REG;
13390#endif
13391 }
Victor Stinner35a97c02015-03-08 02:59:09 +010013392#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013393
13394 return result;
13395
13396error:
13397 Py_XDECREF(st_mode);
13398 Py_XDECREF(stat);
13399 return -1;
13400}
13401
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013402/*[clinic input]
13403os.DirEntry.is_dir -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013404 defining_class: defining_class
13405 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013406 *
13407 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010013408
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013409Return True if the entry is a directory; cached per entry.
13410[clinic start generated code]*/
13411
13412static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013413os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
13414 int follow_symlinks)
13415/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013416{
Victor Stinner97f33c32020-05-14 18:05:58 +020013417 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010013418}
13419
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013420/*[clinic input]
13421os.DirEntry.is_file -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013422 defining_class: defining_class
13423 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013424 *
13425 follow_symlinks: bool = True
13426
13427Return True if the entry is a file; cached per entry.
13428[clinic start generated code]*/
13429
13430static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013431os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
13432 int follow_symlinks)
13433/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013434{
Victor Stinner97f33c32020-05-14 18:05:58 +020013435 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010013436}
13437
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013438/*[clinic input]
13439os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010013440
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013441Return inode of the entry; cached per entry.
13442[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013443
13444static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013445os_DirEntry_inode_impl(DirEntry *self)
13446/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013447{
13448#ifdef MS_WINDOWS
13449 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013450 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013451 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013452 STRUCT_STAT stat;
13453 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010013454
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013455 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010013456 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013457 path = PyUnicode_AsUnicode(unicode);
13458 result = LSTAT(path, &stat);
13459 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010013460
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013461 if (result != 0)
13462 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013463
13464 self->win32_file_index = stat.st_ino;
13465 self->got_file_index = 1;
13466 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010013467 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
13468 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010013469#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020013470 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
13471 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010013472#endif
13473}
13474
13475static PyObject *
13476DirEntry_repr(DirEntry *self)
13477{
13478 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13479}
13480
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013481/*[clinic input]
13482os.DirEntry.__fspath__
13483
13484Returns the path for the entry.
13485[clinic start generated code]*/
13486
Brett Cannon96881cd2016-06-10 14:37:21 -070013487static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013488os_DirEntry___fspath___impl(DirEntry *self)
13489/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070013490{
13491 Py_INCREF(self->path);
13492 return self->path;
13493}
13494
Victor Stinner6036e442015-03-08 01:58:04 +010013495static PyMemberDef DirEntry_members[] = {
13496 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13497 "the entry's base filename, relative to scandir() \"path\" argument"},
13498 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13499 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13500 {NULL}
13501};
13502
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013503#include "clinic/posixmodule.c.h"
13504
Victor Stinner6036e442015-03-08 01:58:04 +010013505static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013506 OS_DIRENTRY_IS_DIR_METHODDEF
13507 OS_DIRENTRY_IS_FILE_METHODDEF
13508 OS_DIRENTRY_IS_SYMLINK_METHODDEF
13509 OS_DIRENTRY_STAT_METHODDEF
13510 OS_DIRENTRY_INODE_METHODDEF
13511 OS_DIRENTRY___FSPATH___METHODDEF
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013512 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
13513 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Victor Stinner6036e442015-03-08 01:58:04 +010013514 {NULL}
13515};
13516
Eddie Elizondob3966632019-11-05 07:16:14 -080013517static PyType_Slot DirEntryType_slots[] = {
13518 {Py_tp_new, _disabled_new},
13519 {Py_tp_dealloc, DirEntry_dealloc},
13520 {Py_tp_repr, DirEntry_repr},
13521 {Py_tp_methods, DirEntry_methods},
13522 {Py_tp_members, DirEntry_members},
13523 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010013524};
13525
Eddie Elizondob3966632019-11-05 07:16:14 -080013526static PyType_Spec DirEntryType_spec = {
13527 MODNAME ".DirEntry",
13528 sizeof(DirEntry),
13529 0,
13530 Py_TPFLAGS_DEFAULT,
13531 DirEntryType_slots
13532};
13533
13534
Victor Stinner6036e442015-03-08 01:58:04 +010013535#ifdef MS_WINDOWS
13536
13537static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013538join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010013539{
13540 Py_ssize_t path_len;
13541 Py_ssize_t size;
13542 wchar_t *result;
13543 wchar_t ch;
13544
13545 if (!path_wide) { /* Default arg: "." */
13546 path_wide = L".";
13547 path_len = 1;
13548 }
13549 else {
13550 path_len = wcslen(path_wide);
13551 }
13552
13553 /* The +1's are for the path separator and the NUL */
13554 size = path_len + 1 + wcslen(filename) + 1;
13555 result = PyMem_New(wchar_t, size);
13556 if (!result) {
13557 PyErr_NoMemory();
13558 return NULL;
13559 }
13560 wcscpy(result, path_wide);
13561 if (path_len > 0) {
13562 ch = result[path_len - 1];
13563 if (ch != SEP && ch != ALTSEP && ch != L':')
13564 result[path_len++] = SEP;
13565 wcscpy(result + path_len, filename);
13566 }
13567 return result;
13568}
13569
13570static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013571DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
Victor Stinner6036e442015-03-08 01:58:04 +010013572{
13573 DirEntry *entry;
13574 BY_HANDLE_FILE_INFORMATION file_info;
13575 ULONG reparse_tag;
13576 wchar_t *joined_path;
13577
Victor Stinner1c2fa782020-05-10 11:05:29 +020013578 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013579 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013580 if (!entry)
13581 return NULL;
13582 entry->name = NULL;
13583 entry->path = NULL;
13584 entry->stat = NULL;
13585 entry->lstat = NULL;
13586 entry->got_file_index = 0;
13587
13588 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13589 if (!entry->name)
13590 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013591 if (path->narrow) {
13592 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13593 if (!entry->name)
13594 goto error;
13595 }
Victor Stinner6036e442015-03-08 01:58:04 +010013596
13597 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13598 if (!joined_path)
13599 goto error;
13600
13601 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13602 PyMem_Free(joined_path);
13603 if (!entry->path)
13604 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013605 if (path->narrow) {
13606 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13607 if (!entry->path)
13608 goto error;
13609 }
Victor Stinner6036e442015-03-08 01:58:04 +010013610
Steve Dowercc16be82016-09-08 10:35:16 -070013611 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013612 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13613
13614 return (PyObject *)entry;
13615
13616error:
13617 Py_DECREF(entry);
13618 return NULL;
13619}
13620
13621#else /* POSIX */
13622
13623static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013624join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013625{
13626 Py_ssize_t path_len;
13627 Py_ssize_t size;
13628 char *result;
13629
13630 if (!path_narrow) { /* Default arg: "." */
13631 path_narrow = ".";
13632 path_len = 1;
13633 }
13634 else {
13635 path_len = strlen(path_narrow);
13636 }
13637
13638 if (filename_len == -1)
13639 filename_len = strlen(filename);
13640
13641 /* The +1's are for the path separator and the NUL */
13642 size = path_len + 1 + filename_len + 1;
13643 result = PyMem_New(char, size);
13644 if (!result) {
13645 PyErr_NoMemory();
13646 return NULL;
13647 }
13648 strcpy(result, path_narrow);
13649 if (path_len > 0 && result[path_len - 1] != '/')
13650 result[path_len++] = '/';
13651 strcpy(result + path_len, filename);
13652 return result;
13653}
13654
13655static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013656DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13657 Py_ssize_t name_len, ino_t d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013658#ifdef HAVE_DIRENT_D_TYPE
13659 , unsigned char d_type
13660#endif
13661 )
Victor Stinner6036e442015-03-08 01:58:04 +010013662{
13663 DirEntry *entry;
13664 char *joined_path;
13665
Victor Stinner1c2fa782020-05-10 11:05:29 +020013666 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013667 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013668 if (!entry)
13669 return NULL;
13670 entry->name = NULL;
13671 entry->path = NULL;
13672 entry->stat = NULL;
13673 entry->lstat = NULL;
13674
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013675 if (path->fd != -1) {
13676 entry->dir_fd = path->fd;
13677 joined_path = NULL;
13678 }
13679 else {
13680 entry->dir_fd = DEFAULT_DIR_FD;
13681 joined_path = join_path_filename(path->narrow, name, name_len);
13682 if (!joined_path)
13683 goto error;
13684 }
Victor Stinner6036e442015-03-08 01:58:04 +010013685
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013686 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013687 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013688 if (joined_path)
13689 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013690 }
13691 else {
13692 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013693 if (joined_path)
13694 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013695 }
13696 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013697 if (!entry->name)
13698 goto error;
13699
13700 if (path->fd != -1) {
13701 entry->path = entry->name;
13702 Py_INCREF(entry->path);
13703 }
13704 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013705 goto error;
13706
Victor Stinner35a97c02015-03-08 02:59:09 +010013707#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013708 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013709#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013710 entry->d_ino = d_ino;
13711
13712 return (PyObject *)entry;
13713
13714error:
13715 Py_XDECREF(entry);
13716 return NULL;
13717}
13718
13719#endif
13720
13721
13722typedef struct {
13723 PyObject_HEAD
13724 path_t path;
13725#ifdef MS_WINDOWS
13726 HANDLE handle;
13727 WIN32_FIND_DATAW file_data;
13728 int first_time;
13729#else /* POSIX */
13730 DIR *dirp;
13731#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013732#ifdef HAVE_FDOPENDIR
13733 int fd;
13734#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013735} ScandirIterator;
13736
13737#ifdef MS_WINDOWS
13738
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013739static int
13740ScandirIterator_is_closed(ScandirIterator *iterator)
13741{
13742 return iterator->handle == INVALID_HANDLE_VALUE;
13743}
13744
Victor Stinner6036e442015-03-08 01:58:04 +010013745static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013746ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013747{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013748 HANDLE handle = iterator->handle;
13749
13750 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013751 return;
13752
Victor Stinner6036e442015-03-08 01:58:04 +010013753 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013754 Py_BEGIN_ALLOW_THREADS
13755 FindClose(handle);
13756 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013757}
13758
13759static PyObject *
13760ScandirIterator_iternext(ScandirIterator *iterator)
13761{
13762 WIN32_FIND_DATAW *file_data = &iterator->file_data;
13763 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013764 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013765
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013766 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013767 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013768 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013769
13770 while (1) {
13771 if (!iterator->first_time) {
13772 Py_BEGIN_ALLOW_THREADS
13773 success = FindNextFileW(iterator->handle, file_data);
13774 Py_END_ALLOW_THREADS
13775 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013776 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013777 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013778 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013779 break;
13780 }
13781 }
13782 iterator->first_time = 0;
13783
13784 /* Skip over . and .. */
13785 if (wcscmp(file_data->cFileName, L".") != 0 &&
Victor Stinner1c2fa782020-05-10 11:05:29 +020013786 wcscmp(file_data->cFileName, L"..") != 0)
13787 {
13788 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13789 entry = DirEntry_from_find_data(module, &iterator->path, file_data);
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013790 if (!entry)
13791 break;
13792 return entry;
13793 }
Victor Stinner6036e442015-03-08 01:58:04 +010013794
13795 /* Loop till we get a non-dot directory or finish iterating */
13796 }
13797
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013798 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013799 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013800 return NULL;
13801}
13802
13803#else /* POSIX */
13804
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013805static int
13806ScandirIterator_is_closed(ScandirIterator *iterator)
13807{
13808 return !iterator->dirp;
13809}
13810
Victor Stinner6036e442015-03-08 01:58:04 +010013811static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013812ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013813{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013814 DIR *dirp = iterator->dirp;
13815
13816 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013817 return;
13818
Victor Stinner6036e442015-03-08 01:58:04 +010013819 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013820 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013821#ifdef HAVE_FDOPENDIR
13822 if (iterator->path.fd != -1)
13823 rewinddir(dirp);
13824#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013825 closedir(dirp);
13826 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013827 return;
13828}
13829
13830static PyObject *
13831ScandirIterator_iternext(ScandirIterator *iterator)
13832{
13833 struct dirent *direntp;
13834 Py_ssize_t name_len;
13835 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013836 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013837
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013838 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013839 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013840 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013841
13842 while (1) {
13843 errno = 0;
13844 Py_BEGIN_ALLOW_THREADS
13845 direntp = readdir(iterator->dirp);
13846 Py_END_ALLOW_THREADS
13847
13848 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013849 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013850 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013851 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013852 break;
13853 }
13854
13855 /* Skip over . and .. */
13856 name_len = NAMLEN(direntp);
13857 is_dot = direntp->d_name[0] == '.' &&
13858 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
13859 if (!is_dot) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020013860 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13861 entry = DirEntry_from_posix_info(module,
13862 &iterator->path, direntp->d_name,
13863 name_len, direntp->d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013864#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner1c2fa782020-05-10 11:05:29 +020013865 , direntp->d_type
Victor Stinner35a97c02015-03-08 02:59:09 +010013866#endif
13867 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013868 if (!entry)
13869 break;
13870 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013871 }
13872
13873 /* Loop till we get a non-dot directory or finish iterating */
13874 }
13875
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013876 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013877 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013878 return NULL;
13879}
13880
13881#endif
13882
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013883static PyObject *
13884ScandirIterator_close(ScandirIterator *self, PyObject *args)
13885{
13886 ScandirIterator_closedir(self);
13887 Py_RETURN_NONE;
13888}
13889
13890static PyObject *
13891ScandirIterator_enter(PyObject *self, PyObject *args)
13892{
13893 Py_INCREF(self);
13894 return self;
13895}
13896
13897static PyObject *
13898ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13899{
13900 ScandirIterator_closedir(self);
13901 Py_RETURN_NONE;
13902}
13903
Victor Stinner6036e442015-03-08 01:58:04 +010013904static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013905ScandirIterator_finalize(ScandirIterator *iterator)
13906{
13907 PyObject *error_type, *error_value, *error_traceback;
13908
13909 /* Save the current exception, if any. */
13910 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13911
13912 if (!ScandirIterator_is_closed(iterator)) {
13913 ScandirIterator_closedir(iterator);
13914
13915 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13916 "unclosed scandir iterator %R", iterator)) {
13917 /* Spurious errors can appear at shutdown */
13918 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13919 PyErr_WriteUnraisable((PyObject *) iterator);
13920 }
13921 }
13922 }
13923
Victor Stinner7bfa4092016-03-23 00:43:54 +010013924 path_cleanup(&iterator->path);
13925
13926 /* Restore the saved exception. */
13927 PyErr_Restore(error_type, error_value, error_traceback);
13928}
13929
13930static void
Victor Stinner6036e442015-03-08 01:58:04 +010013931ScandirIterator_dealloc(ScandirIterator *iterator)
13932{
Eddie Elizondob3966632019-11-05 07:16:14 -080013933 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010013934 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13935 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013936
Eddie Elizondob3966632019-11-05 07:16:14 -080013937 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13938 free_func(iterator);
13939 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013940}
13941
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013942static PyMethodDef ScandirIterator_methods[] = {
13943 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13944 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13945 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13946 {NULL}
13947};
13948
Eddie Elizondob3966632019-11-05 07:16:14 -080013949static PyType_Slot ScandirIteratorType_slots[] = {
13950 {Py_tp_new, _disabled_new},
13951 {Py_tp_dealloc, ScandirIterator_dealloc},
13952 {Py_tp_finalize, ScandirIterator_finalize},
13953 {Py_tp_iter, PyObject_SelfIter},
13954 {Py_tp_iternext, ScandirIterator_iternext},
13955 {Py_tp_methods, ScandirIterator_methods},
13956 {0, 0},
13957};
13958
13959static PyType_Spec ScandirIteratorType_spec = {
13960 MODNAME ".ScandirIterator",
13961 sizeof(ScandirIterator),
13962 0,
Victor Stinner97f33c32020-05-14 18:05:58 +020013963 // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
13964 // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
Eddie Elizondob3966632019-11-05 07:16:14 -080013965 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
13966 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010013967};
13968
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013969/*[clinic input]
13970os.scandir
13971
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013972 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013973
13974Return an iterator of DirEntry objects for given path.
13975
BNMetricsb9427072018-11-02 15:20:19 +000013976path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013977is bytes, the names of yielded DirEntry objects will also be bytes; in
13978all other circumstances they will be str.
13979
13980If path is None, uses the path='.'.
13981[clinic start generated code]*/
13982
Victor Stinner6036e442015-03-08 01:58:04 +010013983static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013984os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013985/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013986{
13987 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013988#ifdef MS_WINDOWS
13989 wchar_t *path_strW;
13990#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013991 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013992#ifdef HAVE_FDOPENDIR
13993 int fd = -1;
13994#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013995#endif
13996
Steve Dower60419a72019-06-24 08:42:54 -070013997 if (PySys_Audit("os.scandir", "O",
13998 path->object ? path->object : Py_None) < 0) {
13999 return NULL;
14000 }
14001
Hai Shif707d942020-03-16 21:15:01 +080014002 PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014003 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010014004 if (!iterator)
14005 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014006
14007#ifdef MS_WINDOWS
14008 iterator->handle = INVALID_HANDLE_VALUE;
14009#else
14010 iterator->dirp = NULL;
14011#endif
14012
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014013 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020014014 /* Move the ownership to iterator->path */
14015 path->object = NULL;
14016 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014017
14018#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010014019 iterator->first_time = 1;
14020
14021 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
14022 if (!path_strW)
14023 goto error;
14024
14025 Py_BEGIN_ALLOW_THREADS
14026 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
14027 Py_END_ALLOW_THREADS
14028
14029 PyMem_Free(path_strW);
14030
14031 if (iterator->handle == INVALID_HANDLE_VALUE) {
14032 path_error(&iterator->path);
14033 goto error;
14034 }
14035#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010014036 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014037#ifdef HAVE_FDOPENDIR
Ronald Oussorene8b1c032020-11-22 11:18:40 +010014038 if (iterator->path.fd != -1) {
14039 if (HAVE_FDOPENDIR_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014040 /* closedir() closes the FD, so we duplicate it */
14041 fd = _Py_dup(path->fd);
14042 if (fd == -1)
14043 goto error;
14044
14045 Py_BEGIN_ALLOW_THREADS
14046 iterator->dirp = fdopendir(fd);
14047 Py_END_ALLOW_THREADS
Ronald Oussorene8b1c032020-11-22 11:18:40 +010014048 } else {
14049 PyErr_SetString(PyExc_TypeError,
14050 "scandir: path should be string, bytes, os.PathLike or None, not int");
14051 return NULL;
14052 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014053 }
14054 else
14055#endif
14056 {
14057 if (iterator->path.narrow)
14058 path_str = iterator->path.narrow;
14059 else
14060 path_str = ".";
14061
14062 Py_BEGIN_ALLOW_THREADS
14063 iterator->dirp = opendir(path_str);
14064 Py_END_ALLOW_THREADS
14065 }
Victor Stinner6036e442015-03-08 01:58:04 +010014066
14067 if (!iterator->dirp) {
14068 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014069#ifdef HAVE_FDOPENDIR
14070 if (fd != -1) {
14071 Py_BEGIN_ALLOW_THREADS
14072 close(fd);
14073 Py_END_ALLOW_THREADS
14074 }
14075#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014076 goto error;
14077 }
14078#endif
14079
14080 return (PyObject *)iterator;
14081
14082error:
14083 Py_DECREF(iterator);
14084 return NULL;
14085}
14086
Ethan Furman410ef8e2016-06-04 12:06:26 -070014087/*
14088 Return the file system path representation of the object.
14089
14090 If the object is str or bytes, then allow it to pass through with
14091 an incremented refcount. If the object defines __fspath__(), then
14092 return the result of that method. All other types raise a TypeError.
14093*/
14094PyObject *
14095PyOS_FSPath(PyObject *path)
14096{
Brett Cannon3f9183b2016-08-26 14:44:48 -070014097 /* For error message reasons, this function is manually inlined in
14098 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070014099 PyObject *func = NULL;
14100 PyObject *path_repr = NULL;
14101
14102 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
14103 Py_INCREF(path);
14104 return path;
14105 }
14106
14107 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
14108 if (NULL == func) {
14109 return PyErr_Format(PyExc_TypeError,
14110 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014111 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080014112 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070014113 }
14114
Victor Stinnerf17c3de2016-12-06 18:46:19 +010014115 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070014116 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070014117 if (NULL == path_repr) {
14118 return NULL;
14119 }
14120
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014121 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
14122 PyErr_Format(PyExc_TypeError,
14123 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080014124 "not %.200s", _PyType_Name(Py_TYPE(path)),
14125 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014126 Py_DECREF(path_repr);
14127 return NULL;
14128 }
14129
Ethan Furman410ef8e2016-06-04 12:06:26 -070014130 return path_repr;
14131}
14132
14133/*[clinic input]
14134os.fspath
14135
14136 path: object
14137
14138Return the file system path representation of the object.
14139
Brett Cannonb4f43e92016-06-09 14:32:08 -070014140If the object is str or bytes, then allow it to pass through as-is. If the
14141object defines __fspath__(), then return the result of that method. All other
14142types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070014143[clinic start generated code]*/
14144
14145static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030014146os_fspath_impl(PyObject *module, PyObject *path)
14147/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070014148{
14149 return PyOS_FSPath(path);
14150}
Victor Stinner6036e442015-03-08 01:58:04 +010014151
Victor Stinner9b1f4742016-09-06 16:18:52 -070014152#ifdef HAVE_GETRANDOM_SYSCALL
14153/*[clinic input]
14154os.getrandom
14155
14156 size: Py_ssize_t
14157 flags: int=0
14158
14159Obtain a series of random bytes.
14160[clinic start generated code]*/
14161
14162static PyObject *
14163os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
14164/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
14165{
Victor Stinner9b1f4742016-09-06 16:18:52 -070014166 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014167 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014168
14169 if (size < 0) {
14170 errno = EINVAL;
14171 return posix_error();
14172 }
14173
Victor Stinnerec2319c2016-09-20 23:00:59 +020014174 bytes = PyBytes_FromStringAndSize(NULL, size);
14175 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014176 PyErr_NoMemory();
14177 return NULL;
14178 }
14179
14180 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014181 n = syscall(SYS_getrandom,
14182 PyBytes_AS_STRING(bytes),
14183 PyBytes_GET_SIZE(bytes),
14184 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070014185 if (n < 0 && errno == EINTR) {
14186 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014187 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014188 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020014189
14190 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070014191 continue;
14192 }
14193 break;
14194 }
14195
14196 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014197 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020014198 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014199 }
14200
Victor Stinnerec2319c2016-09-20 23:00:59 +020014201 if (n != size) {
14202 _PyBytes_Resize(&bytes, n);
14203 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070014204
14205 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014206
14207error:
14208 Py_DECREF(bytes);
14209 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014210}
14211#endif /* HAVE_GETRANDOM_SYSCALL */
14212
Steve Dower2438cdf2019-03-29 16:37:16 -070014213#ifdef MS_WINDOWS
14214/* bpo-36085: Helper functions for managing DLL search directories
14215 * on win32
14216 */
14217
14218typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
14219typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
14220
14221/*[clinic input]
14222os._add_dll_directory
14223
14224 path: path_t
14225
14226Add a path to the DLL search path.
14227
14228This search path is used when resolving dependencies for imported
14229extension modules (the module itself is resolved through sys.path),
14230and also by ctypes.
14231
14232Returns an opaque value that may be passed to os.remove_dll_directory
14233to remove this directory from the search path.
14234[clinic start generated code]*/
14235
14236static PyObject *
14237os__add_dll_directory_impl(PyObject *module, path_t *path)
14238/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
14239{
14240 HMODULE hKernel32;
14241 PAddDllDirectory AddDllDirectory;
14242 DLL_DIRECTORY_COOKIE cookie = 0;
14243 DWORD err = 0;
14244
Saiyang Gou7514f4f2020-02-12 23:47:42 -080014245 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
14246 return NULL;
14247 }
14248
Steve Dower2438cdf2019-03-29 16:37:16 -070014249 /* For Windows 7, we have to load this. As this will be a fairly
14250 infrequent operation, just do it each time. Kernel32 is always
14251 loaded. */
14252 Py_BEGIN_ALLOW_THREADS
14253 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14254 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
14255 hKernel32, "AddDllDirectory")) ||
14256 !(cookie = (*AddDllDirectory)(path->wide))) {
14257 err = GetLastError();
14258 }
14259 Py_END_ALLOW_THREADS
14260
14261 if (err) {
14262 return win32_error_object_err("add_dll_directory",
14263 path->object, err);
14264 }
14265
14266 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
14267}
14268
14269/*[clinic input]
14270os._remove_dll_directory
14271
14272 cookie: object
14273
14274Removes a path from the DLL search path.
14275
14276The parameter is an opaque value that was returned from
14277os.add_dll_directory. You can only remove directories that you added
14278yourself.
14279[clinic start generated code]*/
14280
14281static PyObject *
14282os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
14283/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
14284{
14285 HMODULE hKernel32;
14286 PRemoveDllDirectory RemoveDllDirectory;
14287 DLL_DIRECTORY_COOKIE cookieValue;
14288 DWORD err = 0;
14289
14290 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
14291 PyErr_SetString(PyExc_TypeError,
14292 "Provided cookie was not returned from os.add_dll_directory");
14293 return NULL;
14294 }
14295
14296 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
14297 cookie, "DLL directory cookie");
14298
14299 /* For Windows 7, we have to load this. As this will be a fairly
14300 infrequent operation, just do it each time. Kernel32 is always
14301 loaded. */
14302 Py_BEGIN_ALLOW_THREADS
14303 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14304 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
14305 hKernel32, "RemoveDllDirectory")) ||
14306 !(*RemoveDllDirectory)(cookieValue)) {
14307 err = GetLastError();
14308 }
14309 Py_END_ALLOW_THREADS
14310
14311 if (err) {
14312 return win32_error_object_err("remove_dll_directory",
14313 NULL, err);
14314 }
14315
14316 if (PyCapsule_SetName(cookie, NULL)) {
14317 return NULL;
14318 }
14319
14320 Py_RETURN_NONE;
14321}
14322
14323#endif
Larry Hastings31826802013-10-19 00:09:25 -070014324
Victor Stinner65a796e2020-04-01 18:49:29 +020014325
14326/* Only check if WIFEXITED is available: expect that it comes
14327 with WEXITSTATUS, WIFSIGNALED, etc.
14328
14329 os.waitstatus_to_exitcode() is implemented in C and not in Python, so
14330 subprocess can safely call it during late Python finalization without
14331 risking that used os attributes were set to None by _PyImport_Cleanup(). */
14332#if defined(WIFEXITED) || defined(MS_WINDOWS)
14333/*[clinic input]
14334os.waitstatus_to_exitcode
14335
Victor Stinner9bee32b2020-04-22 16:30:35 +020014336 status as status_obj: object
Victor Stinner65a796e2020-04-01 18:49:29 +020014337
14338Convert a wait status to an exit code.
14339
14340On Unix:
14341
14342* If WIFEXITED(status) is true, return WEXITSTATUS(status).
14343* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
14344* Otherwise, raise a ValueError.
14345
14346On Windows, return status shifted right by 8 bits.
14347
14348On Unix, if the process is being traced or if waitpid() was called with
14349WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
14350This function must not be called if WIFSTOPPED(status) is true.
14351[clinic start generated code]*/
14352
14353static PyObject *
Victor Stinner9bee32b2020-04-22 16:30:35 +020014354os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
14355/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
Victor Stinner65a796e2020-04-01 18:49:29 +020014356{
Victor Stinner9bee32b2020-04-22 16:30:35 +020014357 if (PyFloat_Check(status_obj)) {
14358 PyErr_SetString(PyExc_TypeError,
14359 "integer argument expected, got float" );
14360 return NULL;
14361 }
Victor Stinner65a796e2020-04-01 18:49:29 +020014362#ifndef MS_WINDOWS
Victor Stinner9bee32b2020-04-22 16:30:35 +020014363 int status = _PyLong_AsInt(status_obj);
14364 if (status == -1 && PyErr_Occurred()) {
14365 return NULL;
14366 }
14367
Victor Stinner65a796e2020-04-01 18:49:29 +020014368 WAIT_TYPE wait_status;
14369 WAIT_STATUS_INT(wait_status) = status;
14370 int exitcode;
14371 if (WIFEXITED(wait_status)) {
14372 exitcode = WEXITSTATUS(wait_status);
14373 /* Sanity check to provide warranty on the function behavior.
14374 It should not occur in practice */
14375 if (exitcode < 0) {
14376 PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
14377 return NULL;
14378 }
14379 }
14380 else if (WIFSIGNALED(wait_status)) {
14381 int signum = WTERMSIG(wait_status);
14382 /* Sanity check to provide warranty on the function behavior.
14383 It should not occurs in practice */
14384 if (signum <= 0) {
14385 PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
14386 return NULL;
14387 }
14388 exitcode = -signum;
14389 } else if (WIFSTOPPED(wait_status)) {
14390 /* Status only received if the process is being traced
14391 or if waitpid() was called with WUNTRACED option. */
14392 int signum = WSTOPSIG(wait_status);
14393 PyErr_Format(PyExc_ValueError,
14394 "process stopped by delivery of signal %i",
14395 signum);
14396 return NULL;
14397 }
14398 else {
14399 PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
14400 return NULL;
14401 }
14402 return PyLong_FromLong(exitcode);
14403#else
14404 /* Windows implementation: see os.waitpid() implementation
14405 which uses _cwait(). */
Victor Stinner9bee32b2020-04-22 16:30:35 +020014406 unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
14407 if (status == (unsigned long long)-1 && PyErr_Occurred()) {
14408 return NULL;
14409 }
14410
14411 unsigned long long exitcode = (status >> 8);
14412 /* ExitProcess() accepts an UINT type:
14413 reject exit code which doesn't fit in an UINT */
14414 if (exitcode > UINT_MAX) {
14415 PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
14416 return NULL;
14417 }
14418 return PyLong_FromUnsignedLong((unsigned long)exitcode);
Victor Stinner65a796e2020-04-01 18:49:29 +020014419#endif
14420}
14421#endif
14422
14423
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014424static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070014425
14426 OS_STAT_METHODDEF
14427 OS_ACCESS_METHODDEF
14428 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014429 OS_CHDIR_METHODDEF
14430 OS_CHFLAGS_METHODDEF
14431 OS_CHMOD_METHODDEF
14432 OS_FCHMOD_METHODDEF
14433 OS_LCHMOD_METHODDEF
14434 OS_CHOWN_METHODDEF
14435 OS_FCHOWN_METHODDEF
14436 OS_LCHOWN_METHODDEF
14437 OS_LCHFLAGS_METHODDEF
14438 OS_CHROOT_METHODDEF
14439 OS_CTERMID_METHODDEF
14440 OS_GETCWD_METHODDEF
14441 OS_GETCWDB_METHODDEF
14442 OS_LINK_METHODDEF
14443 OS_LISTDIR_METHODDEF
14444 OS_LSTAT_METHODDEF
14445 OS_MKDIR_METHODDEF
14446 OS_NICE_METHODDEF
14447 OS_GETPRIORITY_METHODDEF
14448 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014449 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030014450 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014451 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010014452 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014453 OS_RENAME_METHODDEF
14454 OS_REPLACE_METHODDEF
14455 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014456 OS_SYMLINK_METHODDEF
14457 OS_SYSTEM_METHODDEF
14458 OS_UMASK_METHODDEF
14459 OS_UNAME_METHODDEF
14460 OS_UNLINK_METHODDEF
14461 OS_REMOVE_METHODDEF
14462 OS_UTIME_METHODDEF
14463 OS_TIMES_METHODDEF
14464 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014465 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014466 OS_EXECV_METHODDEF
14467 OS_EXECVE_METHODDEF
14468 OS_SPAWNV_METHODDEF
14469 OS_SPAWNVE_METHODDEF
14470 OS_FORK1_METHODDEF
14471 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020014472 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014473 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14474 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14475 OS_SCHED_GETPARAM_METHODDEF
14476 OS_SCHED_GETSCHEDULER_METHODDEF
14477 OS_SCHED_RR_GET_INTERVAL_METHODDEF
14478 OS_SCHED_SETPARAM_METHODDEF
14479 OS_SCHED_SETSCHEDULER_METHODDEF
14480 OS_SCHED_YIELD_METHODDEF
14481 OS_SCHED_SETAFFINITY_METHODDEF
14482 OS_SCHED_GETAFFINITY_METHODDEF
14483 OS_OPENPTY_METHODDEF
14484 OS_FORKPTY_METHODDEF
14485 OS_GETEGID_METHODDEF
14486 OS_GETEUID_METHODDEF
14487 OS_GETGID_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014488 OS_GETGROUPLIST_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014489 OS_GETGROUPS_METHODDEF
14490 OS_GETPID_METHODDEF
14491 OS_GETPGRP_METHODDEF
14492 OS_GETPPID_METHODDEF
14493 OS_GETUID_METHODDEF
14494 OS_GETLOGIN_METHODDEF
14495 OS_KILL_METHODDEF
14496 OS_KILLPG_METHODDEF
14497 OS_PLOCK_METHODDEF
Steve Dowercc16be82016-09-08 10:35:16 -070014498 OS_STARTFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014499 OS_SETUID_METHODDEF
14500 OS_SETEUID_METHODDEF
14501 OS_SETREUID_METHODDEF
14502 OS_SETGID_METHODDEF
14503 OS_SETEGID_METHODDEF
14504 OS_SETREGID_METHODDEF
14505 OS_SETGROUPS_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014506 OS_INITGROUPS_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014507 OS_GETPGID_METHODDEF
14508 OS_SETPGRP_METHODDEF
14509 OS_WAIT_METHODDEF
14510 OS_WAIT3_METHODDEF
14511 OS_WAIT4_METHODDEF
14512 OS_WAITID_METHODDEF
14513 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080014514 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014515 OS_GETSID_METHODDEF
14516 OS_SETSID_METHODDEF
14517 OS_SETPGID_METHODDEF
14518 OS_TCGETPGRP_METHODDEF
14519 OS_TCSETPGRP_METHODDEF
14520 OS_OPEN_METHODDEF
14521 OS_CLOSE_METHODDEF
14522 OS_CLOSERANGE_METHODDEF
14523 OS_DEVICE_ENCODING_METHODDEF
14524 OS_DUP_METHODDEF
14525 OS_DUP2_METHODDEF
14526 OS_LOCKF_METHODDEF
14527 OS_LSEEK_METHODDEF
14528 OS_READ_METHODDEF
14529 OS_READV_METHODDEF
14530 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014531 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014532 OS_WRITE_METHODDEF
14533 OS_WRITEV_METHODDEF
14534 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014535 OS_PWRITEV_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014536 OS_SENDFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014537 OS_FSTAT_METHODDEF
14538 OS_ISATTY_METHODDEF
14539 OS_PIPE_METHODDEF
14540 OS_PIPE2_METHODDEF
14541 OS_MKFIFO_METHODDEF
14542 OS_MKNOD_METHODDEF
14543 OS_MAJOR_METHODDEF
14544 OS_MINOR_METHODDEF
14545 OS_MAKEDEV_METHODDEF
14546 OS_FTRUNCATE_METHODDEF
14547 OS_TRUNCATE_METHODDEF
14548 OS_POSIX_FALLOCATE_METHODDEF
14549 OS_POSIX_FADVISE_METHODDEF
14550 OS_PUTENV_METHODDEF
14551 OS_UNSETENV_METHODDEF
14552 OS_STRERROR_METHODDEF
14553 OS_FCHDIR_METHODDEF
14554 OS_FSYNC_METHODDEF
14555 OS_SYNC_METHODDEF
14556 OS_FDATASYNC_METHODDEF
14557 OS_WCOREDUMP_METHODDEF
14558 OS_WIFCONTINUED_METHODDEF
14559 OS_WIFSTOPPED_METHODDEF
14560 OS_WIFSIGNALED_METHODDEF
14561 OS_WIFEXITED_METHODDEF
14562 OS_WEXITSTATUS_METHODDEF
14563 OS_WTERMSIG_METHODDEF
14564 OS_WSTOPSIG_METHODDEF
14565 OS_FSTATVFS_METHODDEF
14566 OS_STATVFS_METHODDEF
14567 OS_CONFSTR_METHODDEF
14568 OS_SYSCONF_METHODDEF
14569 OS_FPATHCONF_METHODDEF
14570 OS_PATHCONF_METHODDEF
14571 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030014572 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014573 OS__GETDISKUSAGE_METHODDEF
14574 OS__GETFINALPATHNAME_METHODDEF
14575 OS__GETVOLUMEPATHNAME_METHODDEF
14576 OS_GETLOADAVG_METHODDEF
14577 OS_URANDOM_METHODDEF
14578 OS_SETRESUID_METHODDEF
14579 OS_SETRESGID_METHODDEF
14580 OS_GETRESUID_METHODDEF
14581 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000014582
Larry Hastings2f936352014-08-05 14:04:04 +100014583 OS_GETXATTR_METHODDEF
14584 OS_SETXATTR_METHODDEF
14585 OS_REMOVEXATTR_METHODDEF
14586 OS_LISTXATTR_METHODDEF
14587
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014588 OS_GET_TERMINAL_SIZE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014589 OS_CPU_COUNT_METHODDEF
14590 OS_GET_INHERITABLE_METHODDEF
14591 OS_SET_INHERITABLE_METHODDEF
14592 OS_GET_HANDLE_INHERITABLE_METHODDEF
14593 OS_SET_HANDLE_INHERITABLE_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014594 OS_GET_BLOCKING_METHODDEF
14595 OS_SET_BLOCKING_METHODDEF
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014596 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070014597 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070014598 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014599 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070014600 OS__ADD_DLL_DIRECTORY_METHODDEF
14601 OS__REMOVE_DLL_DIRECTORY_METHODDEF
Victor Stinner65a796e2020-04-01 18:49:29 +020014602 OS_WAITSTATUS_TO_EXITCODE_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014603 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014604};
14605
Barry Warsaw4a342091996-12-19 23:50:02 +000014606static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014607all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000014608{
Guido van Rossum94f6f721999-01-06 18:42:14 +000014609#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014610 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014611#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014612#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014613 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014614#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014615#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014616 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014617#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014618#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014619 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014620#endif
Fred Drakec9680921999-12-13 16:37:25 +000014621#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014622 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000014623#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014624#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014625 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014626#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014627#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014628 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014629#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014630#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014631 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014632#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014633#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014634 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014635#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014636#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014637 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014638#endif
14639#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014640 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014641#endif
14642#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014643 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014644#endif
14645#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014646 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014647#endif
14648#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014649 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014650#endif
14651#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014652 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014653#endif
14654#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014655 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014656#endif
14657#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014658 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014659#endif
14660#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014661 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014662#endif
14663#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014664 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014665#endif
14666#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014667 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014668#endif
14669#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014670 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014671#endif
14672#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014673 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014674#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014675#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014676 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014677#endif
14678#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014679 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014680#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014681#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014682 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014683#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014684#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014685 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014686#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014687#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014688#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014689 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014690#endif
14691#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014692 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014693#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014694#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014695#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014696 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014697#endif
14698#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014699 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014700#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014701#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014702 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014703#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014704#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014705 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014706#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014707#ifdef O_TMPFILE
14708 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14709#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014710#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014711 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014712#endif
14713#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014714 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014715#endif
14716#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014717 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014718#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014719#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014720 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014721#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014722#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014723 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014724#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014725
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014726
Jesus Cea94363612012-06-22 18:32:07 +020014727#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014728 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014729#endif
14730#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014731 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014732#endif
14733
Tim Peters5aa91602002-01-30 05:46:57 +000014734/* MS Windows */
14735#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014736 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014737 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014738#endif
14739#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000014740 /* Optimize for short life (keep in memory). */
14741 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014742 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014743#endif
14744#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000014745 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014746 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014747#endif
14748#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000014749 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014750 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014751#endif
14752#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014753 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014754 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014755#endif
14756
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014757/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014758#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014759 /* Send a SIGIO signal whenever input or output
14760 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014761 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014762#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014763#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014764 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014765 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014766#endif
14767#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000014768 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014769 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014770#endif
14771#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000014772 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014773 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014774#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014775#ifdef O_NOLINKS
14776 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014777 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014778#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014779#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014780 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014781 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014782#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000014783
Victor Stinner8c62be82010-05-06 00:08:46 +000014784 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014785#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014786 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014787#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014788#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014789 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014790#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014791#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014792 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014793#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014794#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014795 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014796#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014797#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014798 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014799#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014800#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014801 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014802#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014803#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014804 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014805#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014806#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014807 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014808#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014809#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014810 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014811#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014812#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014813 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014814#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014815#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014816 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014817#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014818#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014819 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014820#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014821#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014822 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014823#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014824#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014825 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014826#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014827#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014828 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014829#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014830#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014831 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014832#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014833#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014834 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014835#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014836
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000014837 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014838#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014839 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014840#endif /* ST_RDONLY */
14841#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014842 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014843#endif /* ST_NOSUID */
14844
doko@ubuntu.comca616a22013-12-08 15:23:07 +010014845 /* GNU extensions */
14846#ifdef ST_NODEV
14847 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
14848#endif /* ST_NODEV */
14849#ifdef ST_NOEXEC
14850 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
14851#endif /* ST_NOEXEC */
14852#ifdef ST_SYNCHRONOUS
14853 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
14854#endif /* ST_SYNCHRONOUS */
14855#ifdef ST_MANDLOCK
14856 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
14857#endif /* ST_MANDLOCK */
14858#ifdef ST_WRITE
14859 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
14860#endif /* ST_WRITE */
14861#ifdef ST_APPEND
14862 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
14863#endif /* ST_APPEND */
14864#ifdef ST_NOATIME
14865 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
14866#endif /* ST_NOATIME */
14867#ifdef ST_NODIRATIME
14868 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
14869#endif /* ST_NODIRATIME */
14870#ifdef ST_RELATIME
14871 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
14872#endif /* ST_RELATIME */
14873
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014874 /* FreeBSD sendfile() constants */
14875#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014876 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014877#endif
14878#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014879 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014880#endif
14881#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014882 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014883#endif
14884
Ross Lagerwall7807c352011-03-17 20:20:30 +020014885 /* constants for posix_fadvise */
14886#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014887 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014888#endif
14889#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014890 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014891#endif
14892#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014893 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014894#endif
14895#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014896 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014897#endif
14898#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014899 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014900#endif
14901#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014902 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014903#endif
14904
14905 /* constants for waitid */
14906#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014907 if (PyModule_AddIntMacro(m, P_PID)) return -1;
14908 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
14909 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080014910#ifdef P_PIDFD
14911 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
14912#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014913#endif
14914#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014915 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014916#endif
14917#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014918 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014919#endif
14920#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014921 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014922#endif
14923#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014924 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014925#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014926#ifdef CLD_KILLED
14927 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
14928#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014929#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014930 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014931#endif
14932#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014933 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014934#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014935#ifdef CLD_STOPPED
14936 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
14937#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014938#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014939 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014940#endif
14941
14942 /* constants for lockf */
14943#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014944 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014945#endif
14946#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014947 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014948#endif
14949#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014950 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014951#endif
14952#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014953 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014954#endif
14955
Pablo Galindo4defba32018-01-27 16:16:37 +000014956#ifdef RWF_DSYNC
14957 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14958#endif
14959#ifdef RWF_HIPRI
14960 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14961#endif
14962#ifdef RWF_SYNC
14963 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14964#endif
14965#ifdef RWF_NOWAIT
14966 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14967#endif
14968
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014969/* constants for posix_spawn */
14970#ifdef HAVE_POSIX_SPAWN
14971 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14972 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14973 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14974#endif
14975
pxinwrf2d7ac72019-05-21 18:46:37 +080014976#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014977 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14978 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014979 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014980#endif
14981#ifdef HAVE_SPAWNV
14982 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014983 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014984#endif
14985
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014986#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014987#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014988 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014989#endif
14990#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014991 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014992#endif
14993#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014994 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014995#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014996#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014997 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014998#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014999#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015000 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015001#endif
15002#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015003 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015004#endif
15005#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015006 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015007#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015008#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015009 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015010#endif
15011#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015012 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015013#endif
15014#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015015 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015016#endif
15017#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015018 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015019#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015020#endif
15021
Benjamin Peterson9428d532011-09-14 11:45:52 -040015022#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015023 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
15024 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
15025 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015026#endif
15027
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015028#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015029 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015030#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015031#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015032 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015033#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015034#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015035 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015036#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015037#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015038 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015039#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015040#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015041 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015042#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015043#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015044 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015045#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015046#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015047 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015048#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010015049#if HAVE_DECL_RTLD_MEMBER
15050 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
15051#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020015052
Victor Stinner9b1f4742016-09-06 16:18:52 -070015053#ifdef HAVE_GETRANDOM_SYSCALL
15054 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
15055 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
15056#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015057#ifdef HAVE_MEMFD_CREATE
15058 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
15059 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
15060#ifdef MFD_HUGETLB
15061 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015062#endif
15063#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015064 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015065#endif
15066#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015067 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015068#endif
15069#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015070 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015071#endif
15072#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015073 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015074#endif
15075#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015076 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015077#endif
15078#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015079 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015080#endif
15081#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015082 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015083#endif
15084#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015085 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015086#endif
15087#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015088 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015089#endif
15090#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015091 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015092#endif
15093#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015094 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015095#endif
15096#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015097 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015098#endif
15099#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015100 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015101#endif
15102#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015103 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
15104#endif
15105#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070015106
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020015107#if defined(__APPLE__)
15108 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
15109#endif
15110
Steve Dower2438cdf2019-03-29 16:37:16 -070015111#ifdef MS_WINDOWS
15112 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
15113 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
15114 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
15115 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
15116 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
15117#endif
15118
Victor Stinner8c62be82010-05-06 00:08:46 +000015119 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000015120}
15121
15122
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015123
15124#define PROBE(name, test) \
15125 static int name(void) \
15126 { \
15127 if (test) { \
15128 return 1; \
15129 } else { \
15130 return 0; \
15131 } \
15132 }
15133
15134#ifdef HAVE_FSTATAT
15135PROBE(probe_fstatat, HAVE_FSTATAT_RUNTIME)
15136#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070015137
15138#ifdef HAVE_FACCESSAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015139PROBE(probe_faccessat, HAVE_FACCESSAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015140#endif
15141
15142#ifdef HAVE_FCHMODAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015143PROBE(probe_fchmodat, HAVE_FCHMODAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015144#endif
15145
Larry Hastings00964ed2013-08-12 13:49:30 -040015146#ifdef HAVE_FCHOWNAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015147PROBE(probe_fchownat, HAVE_FCHOWNAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015148#endif
15149
15150#ifdef HAVE_LINKAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015151PROBE(probe_linkat, HAVE_LINKAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015152#endif
15153
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015154#ifdef HAVE_FDOPENDIR
15155PROBE(probe_fdopendir, HAVE_FDOPENDIR_RUNTIME)
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015156#endif
15157
Larry Hastings9cf065c2012-06-22 16:30:09 -070015158#ifdef HAVE_MKDIRAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015159PROBE(probe_mkdirat, HAVE_MKDIRAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015160#endif
15161
15162#ifdef HAVE_RENAMEAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015163PROBE(probe_renameat, HAVE_RENAMEAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015164#endif
15165
15166#ifdef HAVE_UNLINKAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015167PROBE(probe_unlinkat, HAVE_UNLINKAT_RUNTIME)
15168#endif
15169
15170#ifdef HAVE_OPENAT
15171PROBE(probe_openat, HAVE_OPENAT_RUNTIME)
15172#endif
15173
15174#ifdef HAVE_READLINKAT
15175PROBE(probe_readlinkat, HAVE_READLINKAT_RUNTIME)
15176#endif
15177
15178#ifdef HAVE_SYMLINKAT
15179PROBE(probe_symlinkat, HAVE_SYMLINKAT_RUNTIME)
15180#endif
15181
15182#ifdef HAVE_FUTIMENS
15183PROBE(probe_futimens, HAVE_FUTIMENS_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015184#endif
15185
15186#ifdef HAVE_UTIMENSAT
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015187PROBE(probe_utimensat, HAVE_UTIMENSAT_RUNTIME)
15188#endif
15189
15190
15191
15192
15193static const struct have_function {
15194 const char * const label;
15195 int (*probe)(void);
15196} have_functions[] = {
15197
15198#ifdef HAVE_FACCESSAT
15199 { "HAVE_FACCESSAT", probe_faccessat },
15200#endif
15201
15202#ifdef HAVE_FCHDIR
15203 { "HAVE_FCHDIR", NULL },
15204#endif
15205
15206#ifdef HAVE_FCHMOD
15207 { "HAVE_FCHMOD", NULL },
15208#endif
15209
15210#ifdef HAVE_FCHMODAT
15211 { "HAVE_FCHMODAT", probe_fchmodat },
15212#endif
15213
15214#ifdef HAVE_FCHOWN
15215 { "HAVE_FCHOWN", NULL },
15216#endif
15217
15218#ifdef HAVE_FCHOWNAT
15219 { "HAVE_FCHOWNAT", probe_fchownat },
15220#endif
15221
15222#ifdef HAVE_FEXECVE
15223 { "HAVE_FEXECVE", NULL },
15224#endif
15225
15226#ifdef HAVE_FDOPENDIR
15227 { "HAVE_FDOPENDIR", probe_fdopendir },
15228#endif
15229
15230#ifdef HAVE_FPATHCONF
15231 { "HAVE_FPATHCONF", NULL },
15232#endif
15233
15234#ifdef HAVE_FSTATAT
15235 { "HAVE_FSTATAT", probe_fstatat },
15236#endif
15237
15238#ifdef HAVE_FSTATVFS
15239 { "HAVE_FSTATVFS", NULL },
15240#endif
15241
15242#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
15243 { "HAVE_FTRUNCATE", NULL },
15244#endif
15245
15246#ifdef HAVE_FUTIMENS
15247 { "HAVE_FUTIMENS", probe_futimens },
15248#endif
15249
15250#ifdef HAVE_FUTIMES
15251 { "HAVE_FUTIMES", NULL },
15252#endif
15253
15254#ifdef HAVE_FUTIMESAT
15255 { "HAVE_FUTIMESAT", NULL },
15256#endif
15257
15258#ifdef HAVE_LINKAT
15259 { "HAVE_LINKAT", probe_linkat },
15260#endif
15261
15262#ifdef HAVE_LCHFLAGS
15263 { "HAVE_LCHFLAGS", NULL },
15264#endif
15265
15266#ifdef HAVE_LCHMOD
15267 { "HAVE_LCHMOD", NULL },
15268#endif
15269
15270#ifdef HAVE_LCHOWN
15271 { "HAVE_LCHOWN", NULL },
15272#endif
15273
15274#ifdef HAVE_LSTAT
15275 { "HAVE_LSTAT", NULL },
15276#endif
15277
15278#ifdef HAVE_LUTIMES
15279 { "HAVE_LUTIMES", NULL },
15280#endif
15281
15282#ifdef HAVE_MEMFD_CREATE
15283 { "HAVE_MEMFD_CREATE", NULL },
15284#endif
15285
15286#ifdef HAVE_MKDIRAT
15287 { "HAVE_MKDIRAT", probe_mkdirat },
15288#endif
15289
15290#ifdef HAVE_MKFIFOAT
15291 { "HAVE_MKFIFOAT", NULL },
15292#endif
15293
15294#ifdef HAVE_MKNODAT
15295 { "HAVE_MKNODAT", NULL },
15296#endif
15297
15298#ifdef HAVE_OPENAT
15299 { "HAVE_OPENAT", probe_openat },
15300#endif
15301
15302#ifdef HAVE_READLINKAT
15303 { "HAVE_READLINKAT", probe_readlinkat },
15304#endif
15305
15306#ifdef HAVE_RENAMEAT
15307 { "HAVE_RENAMEAT", probe_renameat },
15308#endif
15309
15310#ifdef HAVE_SYMLINKAT
15311 { "HAVE_SYMLINKAT", probe_symlinkat },
15312#endif
15313
15314#ifdef HAVE_UNLINKAT
15315 { "HAVE_UNLINKAT", probe_unlinkat },
15316#endif
15317
15318#ifdef HAVE_UTIMENSAT
15319 { "HAVE_UTIMENSAT", probe_utimensat },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015320#endif
15321
15322#ifdef MS_WINDOWS
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015323 { "MS_WINDOWS", NULL },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015324#endif
15325
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015326 { NULL, NULL }
Larry Hastings9cf065c2012-06-22 16:30:09 -070015327};
15328
15329
Victor Stinner1c2fa782020-05-10 11:05:29 +020015330static int
15331posixmodule_exec(PyObject *m)
Guido van Rossumb6775db1994-08-01 11:34:53 +000015332{
Victor Stinner97f33c32020-05-14 18:05:58 +020015333 _posixstate *state = get_posix_state(m);
Tim Peters5aa91602002-01-30 05:46:57 +000015334
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015335#if defined(HAVE_PWRITEV)
15336 if (HAVE_PWRITEV_RUNTIME) {} else {
15337 PyObject* dct = PyModule_GetDict(m);
15338
15339 if (dct == NULL) {
15340 return -1;
15341 }
15342
15343 if (PyDict_DelItemString(dct, "pwritev") == -1) {
15344 PyErr_Clear();
15345 }
15346 if (PyDict_DelItemString(dct, "preadv") == -1) {
15347 PyErr_Clear();
15348 }
15349 }
15350#endif
15351
Victor Stinner8c62be82010-05-06 00:08:46 +000015352 /* Initialize environ dictionary */
Victor Stinner97f33c32020-05-14 18:05:58 +020015353 PyObject *v = convertenviron();
Victor Stinner8c62be82010-05-06 00:08:46 +000015354 Py_XINCREF(v);
15355 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015356 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015357 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000015358
Victor Stinner8c62be82010-05-06 00:08:46 +000015359 if (all_ins(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015360 return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000015361
Victor Stinner8c62be82010-05-06 00:08:46 +000015362 if (setup_confname_tables(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015363 return -1;
Fred Drakebec628d1999-12-15 18:31:10 +000015364
Victor Stinner8c62be82010-05-06 00:08:46 +000015365 Py_INCREF(PyExc_OSError);
15366 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000015367
Ross Lagerwall7807c352011-03-17 20:20:30 +020015368#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080015369 waitid_result_desc.name = MODNAME ".waitid_result";
15370 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
15371 if (WaitidResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015372 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015373 }
15374 Py_INCREF(WaitidResultType);
15375 PyModule_AddObject(m, "waitid_result", WaitidResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015376 state->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015377#endif
15378
Eddie Elizondob3966632019-11-05 07:16:14 -080015379 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
15380 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
15381 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
15382 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
15383 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
15384 if (StatResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015385 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015386 }
15387 Py_INCREF(StatResultType);
15388 PyModule_AddObject(m, "stat_result", StatResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015389 state->StatResultType = StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015390 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
15391 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015392
Eddie Elizondob3966632019-11-05 07:16:14 -080015393 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
15394 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
15395 if (StatVFSResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015396 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015397 }
15398 Py_INCREF(StatVFSResultType);
15399 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015400 state->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015401#ifdef NEED_TICKS_PER_SECOND
15402# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080015403 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015404# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080015405 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015406# else
Eddie Elizondob3966632019-11-05 07:16:14 -080015407 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015408# endif
15409#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015410
William Orr81574b82018-10-01 22:19:56 -070015411#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080015412 sched_param_desc.name = MODNAME ".sched_param";
15413 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
15414 if (SchedParamType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015415 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015416 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015417 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080015418 PyModule_AddObject(m, "sched_param", SchedParamType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015419 state->SchedParamType = SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015420 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050015421#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000015422
Eddie Elizondob3966632019-11-05 07:16:14 -080015423 /* initialize TerminalSize_info */
15424 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
15425 if (TerminalSizeType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015426 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015427 }
15428 Py_INCREF(TerminalSizeType);
15429 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015430 state->TerminalSizeType = TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015431
15432 /* initialize scandir types */
Victor Stinner1c2fa782020-05-10 11:05:29 +020015433 PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015434 if (ScandirIteratorType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015435 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015436 }
Victor Stinner97f33c32020-05-14 18:05:58 +020015437 state->ScandirIteratorType = ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015438
Victor Stinner1c2fa782020-05-10 11:05:29 +020015439 PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015440 if (DirEntryType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015441 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015442 }
15443 Py_INCREF(DirEntryType);
15444 PyModule_AddObject(m, "DirEntry", DirEntryType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015445 state->DirEntryType = DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015446
Larry Hastings605a62d2012-06-24 04:33:36 -070015447 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080015448 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015449 if (TimesResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015450 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015451 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015452 Py_INCREF(TimesResultType);
15453 PyModule_AddObject(m, "times_result", TimesResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015454 state->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015455
Eddie Elizondob3966632019-11-05 07:16:14 -080015456 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015457 if (UnameResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015458 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015459 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015460 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015461 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015462 state->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015463
Victor Stinner97f33c32020-05-14 18:05:58 +020015464 if ((state->billion = PyLong_FromLong(1000000000)) == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015465 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015466#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +020015467 state->struct_rusage = PyUnicode_InternFromString("struct_rusage");
15468 if (state->struct_rusage == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015469 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015470#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020015471 state->st_mode = PyUnicode_InternFromString("st_mode");
15472 if (state->st_mode == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015473 return -1;
Larry Hastings6fe20b32012-04-19 15:07:49 -070015474
Larry Hastings9cf065c2012-06-22 16:30:09 -070015475 /* suppress "function not used" warnings */
15476 {
15477 int ignored;
15478 fd_specified("", -1);
15479 follow_symlinks_specified("", 1);
15480 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
15481 dir_fd_converter(Py_None, &ignored);
15482 dir_fd_unavailable(Py_None, &ignored);
15483 }
15484
15485 /*
15486 * provide list of locally available functions
15487 * so os.py can populate support_* lists
15488 */
Victor Stinner97f33c32020-05-14 18:05:58 +020015489 PyObject *list = PyList_New(0);
15490 if (!list) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015491 return -1;
Victor Stinner97f33c32020-05-14 18:05:58 +020015492 }
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015493 for (const struct have_function *trace = have_functions; trace->label; trace++) {
15494 PyObject *unicode;
15495 if (trace->probe && !trace->probe()) continue;
15496 unicode = PyUnicode_DecodeASCII(trace->label, strlen(trace->label), NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015497 if (!unicode)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015498 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015499 if (PyList_Append(list, unicode))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015500 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015501 Py_DECREF(unicode);
15502 }
Ronald Oussorene8b1c032020-11-22 11:18:40 +010015503
Larry Hastings9cf065c2012-06-22 16:30:09 -070015504 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040015505
Victor Stinner1c2fa782020-05-10 11:05:29 +020015506 return 0;
15507}
15508
15509
15510static PyModuleDef_Slot posixmodile_slots[] = {
15511 {Py_mod_exec, posixmodule_exec},
15512 {0, NULL}
15513};
15514
15515static struct PyModuleDef posixmodule = {
15516 PyModuleDef_HEAD_INIT,
15517 .m_name = MODNAME,
15518 .m_doc = posix__doc__,
15519 .m_size = sizeof(_posixstate),
15520 .m_methods = posix_methods,
15521 .m_slots = posixmodile_slots,
15522 .m_traverse = _posix_traverse,
15523 .m_clear = _posix_clear,
15524 .m_free = _posix_free,
15525};
15526
15527PyMODINIT_FUNC
15528INITFUNC(void)
15529{
15530 return PyModuleDef_Init(&posixmodule);
Guido van Rossumb6775db1994-08-01 11:34:53 +000015531}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015532
15533#ifdef __cplusplus
15534}
15535#endif