blob: ecd210e4babf54b404bf58af81c9488d794515a7 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* POSIX module implementation */
2
Jesus Ceaab70e2a2012-10-05 01:48:08 +02003/* This file is also used for Windows NT/MS-Win. In that case the
4 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00007 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02008 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +00009
Thomas Wouters68bc4f92006-03-01 01:05:10 +000010#define PY_SSIZE_T_CLEAN
11
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000012#include "Python.h"
Kyle Evans79925792020-10-13 15:04:44 -050013#include "pycore_fileutils.h"
Victor Stinnercdad2722021-04-22 00:52:52 +020014#include "pycore_moduleobject.h" // _PyModule_GetState()
Victor Stinnerd5d9e812019-05-13 12:35:37 +020015#ifdef MS_WINDOWS
16 /* include <windows.h> early to avoid conflict with pycore_condvar.h:
17
18 #define WIN32_LEAN_AND_MEAN
19 #include <windows.h>
20
21 FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */
22# include <windows.h>
Steve Dower04732ca2021-04-07 01:02:07 +010023# include <pathcch.h>
Victor Stinnerd5d9e812019-05-13 12:35:37 +020024#endif
25
pxinwr3405e052020-08-07 13:21:52 +080026#ifdef __VXWORKS__
27# include "pycore_bitutils.h" // _Py_popcount32()
28#endif
Victor Stinner4a21e572020-04-15 02:35:41 +020029#include "pycore_ceval.h" // _PyEval_ReInitThreads()
30#include "pycore_import.h" // _PyImport_ReInitLock()
Victor Stinner26881c82020-06-02 15:51:37 +020031#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
Victor Stinner4a21e572020-04-15 02:35:41 +020032#include "pycore_pystate.h" // _PyInterpreterState_GET()
33#include "structmember.h" // PyMemberDef
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020034#ifndef MS_WINDOWS
Victor Stinnerd5d9e812019-05-13 12:35:37 +020035# include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010036#else
Victor Stinnerd5d9e812019-05-13 12:35:37 +020037# include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020038#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020040/* On android API level 21, 'AT_EACCESS' is not declared although
41 * HAVE_FACCESSAT is defined. */
42#ifdef __ANDROID__
Victor Stinner5eca75d2020-04-15 15:07:31 +020043# undef HAVE_FACCESSAT
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020044#endif
45
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000046#include <stdio.h> /* needed for ctermid() */
47
Ronald Oussoren41761932020-11-08 10:05:27 +010048/*
49 * A number of APIs are available on macOS from a certain macOS version.
50 * To support building with a new SDK while deploying to older versions
51 * the availability test is split into two:
52 * - HAVE_<FUNCTION>: The configure check for compile time availability
53 * - HAVE_<FUNCTION>_RUNTIME: Runtime check for availability
54 *
55 * The latter is always true when not on macOS, or when using a compiler
56 * that does not support __has_builtin (older versions of Xcode).
57 *
58 * Due to compiler restrictions there is one valid use of HAVE_<FUNCTION>_RUNTIME:
59 * if (HAVE_<FUNCTION>_RUNTIME) { ... }
60 *
61 * In mixing the test with other tests or using negations will result in compile
62 * errors.
63 */
64#if defined(__APPLE__)
65
Joshua Rootdf21f502021-01-04 21:36:58 +110066#if defined(__has_builtin)
67#if __has_builtin(__builtin_available)
68#define HAVE_BUILTIN_AVAILABLE 1
69#endif
70#endif
71
72#ifdef HAVE_BUILTIN_AVAILABLE
Ronald Oussoren41761932020-11-08 10:05:27 +010073# define HAVE_FSTATAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
74# define HAVE_FACCESSAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
75# define HAVE_FCHMODAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
76# define HAVE_FCHOWNAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
77# define HAVE_LINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
78# define HAVE_FDOPENDIR_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
79# define HAVE_MKDIRAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
80# define HAVE_RENAMEAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
81# define HAVE_UNLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
82# define HAVE_OPENAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
83# define HAVE_READLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
84# define HAVE_SYMLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
85# define HAVE_FUTIMENS_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
86# define HAVE_UTIMENSAT_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
87# define HAVE_PWRITEV_RUNTIME __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)
88
89# define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *)
90
91#else /* Xcode 8 or earlier */
92
93 /* __builtin_available is not present in these compilers, but
94 * some of the symbols might be weak linked (10.10 SDK or later
95 * deploying on 10.9.
96 *
97 * Fall back to the older style of availability checking for
98 * symbols introduced in macOS 10.10.
99 */
100
101# ifdef HAVE_FSTATAT
102# define HAVE_FSTATAT_RUNTIME (fstatat != NULL)
103# endif
104
105# ifdef HAVE_FACCESSAT
106# define HAVE_FACCESSAT_RUNTIME (faccessat != NULL)
107# endif
108
109# ifdef HAVE_FCHMODAT
110# define HAVE_FCHMODAT_RUNTIME (fchmodat != NULL)
111# endif
112
113# ifdef HAVE_FCHOWNAT
114# define HAVE_FCHOWNAT_RUNTIME (fchownat != NULL)
115# endif
116
117# ifdef HAVE_LINKAT
118# define HAVE_LINKAT_RUNTIME (linkat != NULL)
119# endif
120
121# ifdef HAVE_FDOPENDIR
122# define HAVE_FDOPENDIR_RUNTIME (fdopendir != NULL)
123# endif
124
125# ifdef HAVE_MKDIRAT
126# define HAVE_MKDIRAT_RUNTIME (mkdirat != NULL)
127# endif
128
129# ifdef HAVE_RENAMEAT
130# define HAVE_RENAMEAT_RUNTIME (renameat != NULL)
131# endif
132
133# ifdef HAVE_UNLINKAT
134# define HAVE_UNLINKAT_RUNTIME (unlinkat != NULL)
135# endif
136
137# ifdef HAVE_OPENAT
138# define HAVE_OPENAT_RUNTIME (openat != NULL)
139# endif
140
141# ifdef HAVE_READLINKAT
142# define HAVE_READLINKAT_RUNTIME (readlinkat != NULL)
143# endif
144
145# ifdef HAVE_SYMLINKAT
146# define HAVE_SYMLINKAT_RUNTIME (symlinkat != NULL)
147# endif
148
149#endif
150
151#ifdef HAVE_FUTIMESAT
152/* Some of the logic for weak linking depends on this assertion */
153# error "HAVE_FUTIMESAT unexpectedly defined"
154#endif
155
156#else
157# define HAVE_FSTATAT_RUNTIME 1
158# define HAVE_FACCESSAT_RUNTIME 1
159# define HAVE_FCHMODAT_RUNTIME 1
160# define HAVE_FCHOWNAT_RUNTIME 1
161# define HAVE_LINKAT_RUNTIME 1
162# define HAVE_FDOPENDIR_RUNTIME 1
163# define HAVE_MKDIRAT_RUNTIME 1
164# define HAVE_RENAMEAT_RUNTIME 1
165# define HAVE_UNLINKAT_RUNTIME 1
166# define HAVE_OPENAT_RUNTIME 1
167# define HAVE_READLINKAT_RUNTIME 1
168# define HAVE_SYMLINKAT_RUNTIME 1
169# define HAVE_FUTIMENS_RUNTIME 1
170# define HAVE_UTIMENSAT_RUNTIME 1
171# define HAVE_PWRITEV_RUNTIME 1
172#endif
173
174
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000175#ifdef __cplusplus
176extern "C" {
177#endif
178
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000179PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000180"This module provides access to operating system functionality that is\n\
181standardized by the C Standard and the POSIX standard (a thinly\n\
182disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000183corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184
Martin v. Löwis0073f2e2002-11-21 23:52:35 +0000185
Ross Lagerwall4d076da2011-03-18 06:56:53 +0200186#ifdef HAVE_SYS_UIO_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200187# include <sys/uio.h>
Ross Lagerwall4d076da2011-03-18 06:56:53 +0200188#endif
189
Christian Heimes75b96182017-09-05 15:53:09 +0200190#ifdef HAVE_SYS_SYSMACROS_H
191/* GNU C Library: major(), minor(), makedev() */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200192# include <sys/sysmacros.h>
Christian Heimes75b96182017-09-05 15:53:09 +0200193#endif
194
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000195#ifdef HAVE_SYS_TYPES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200196# include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000197#endif /* HAVE_SYS_TYPES_H */
198
199#ifdef HAVE_SYS_STAT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200200# include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000201#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000202
Guido van Rossum36bc6801995-06-14 22:54:23 +0000203#ifdef HAVE_SYS_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200204# include <sys/wait.h> // WNOHANG
Guido van Rossum36bc6801995-06-14 22:54:23 +0000205#endif
Benjamin Peterson5c0c3252019-11-05 21:58:31 -0800206#ifdef HAVE_LINUX_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200207# include <linux/wait.h> // P_PIDFD
Benjamin Peterson5c0c3252019-11-05 21:58:31 -0800208#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000210#ifdef HAVE_SIGNAL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200211# include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000212#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +0000213
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#ifdef HAVE_FCNTL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200215# include <fcntl.h>
216#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000218#ifdef HAVE_GRP_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200219# include <grp.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000220#endif
221
Barry Warsaw5676bd12003-01-07 20:57:09 +0000222#ifdef HAVE_SYSEXITS_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200223# include <sysexits.h>
224#endif
Barry Warsaw5676bd12003-01-07 20:57:09 +0000225
Anthony Baxter8a560de2004-10-13 15:30:56 +0000226#ifdef HAVE_SYS_LOADAVG_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200227# include <sys/loadavg.h>
Anthony Baxter8a560de2004-10-13 15:30:56 +0000228#endif
229
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000230#ifdef HAVE_SYS_SENDFILE_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200231# include <sys/sendfile.h>
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000232#endif
233
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200234#if defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200235# include <copyfile.h>
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200236#endif
237
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500238#ifdef HAVE_SCHED_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200239# include <sched.h>
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500240#endif
241
Pablo Galindoaac4d032019-05-31 19:39:47 +0100242#ifdef HAVE_COPY_FILE_RANGE
Victor Stinner5eca75d2020-04-15 15:07:31 +0200243# include <unistd.h>
Pablo Galindoaac4d032019-05-31 19:39:47 +0100244#endif
245
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500246#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200247# undef HAVE_SCHED_SETAFFINITY
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500248#endif
249
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200250#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200251# define USE_XATTRS
Benjamin Peterson9428d532011-09-14 11:45:52 -0400252#endif
253
254#ifdef USE_XATTRS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200255# include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400256#endif
257
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000258#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200259# ifdef HAVE_SYS_SOCKET_H
260# include <sys/socket.h>
261# endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000262#endif
263
Victor Stinner8b905bd2011-10-25 13:34:04 +0200264#ifdef HAVE_DLFCN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200265# include <dlfcn.h>
Victor Stinner8b905bd2011-10-25 13:34:04 +0200266#endif
267
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200268#ifdef __hpux
Victor Stinner5eca75d2020-04-15 15:07:31 +0200269# include <sys/mpctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200270#endif
271
272#if defined(__DragonFly__) || \
273 defined(__OpenBSD__) || \
274 defined(__FreeBSD__) || \
275 defined(__NetBSD__) || \
276 defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200277# include <sys/sysctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200278#endif
279
Victor Stinner9b1f4742016-09-06 16:18:52 -0700280#ifdef HAVE_LINUX_RANDOM_H
281# include <linux/random.h>
282#endif
283#ifdef HAVE_GETRANDOM_SYSCALL
284# include <sys/syscall.h>
285#endif
286
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100287#if defined(MS_WINDOWS)
288# define TERMSIZE_USE_CONIO
289#elif defined(HAVE_SYS_IOCTL_H)
290# include <sys/ioctl.h>
291# if defined(HAVE_TERMIOS_H)
292# include <termios.h>
293# endif
294# if defined(TIOCGWINSZ)
295# define TERMSIZE_USE_IOCTL
296# endif
297#endif /* MS_WINDOWS */
298
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000299/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000300/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000301#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200302# define HAVE_OPENDIR 1
303# define HAVE_SYSTEM 1
304# include <process.h>
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000305#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200306# ifdef _MSC_VER
307 /* Microsoft compiler */
308# define HAVE_GETPPID 1
309# define HAVE_GETLOGIN 1
310# define HAVE_SPAWNV 1
311# define HAVE_EXECV 1
312# define HAVE_WSPAWNV 1
313# define HAVE_WEXECV 1
314# define HAVE_PIPE 1
315# define HAVE_SYSTEM 1
316# define HAVE_CWAIT 1
317# define HAVE_FSYNC 1
318# define fsync _commit
319# else
320 /* Unix functions that the configure script doesn't check for */
321# ifndef __VXWORKS__
322# define HAVE_EXECV 1
323# define HAVE_FORK 1
324# if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
325# define HAVE_FORK1 1
326# endif
327# endif
328# define HAVE_GETEGID 1
329# define HAVE_GETEUID 1
330# define HAVE_GETGID 1
331# define HAVE_GETPPID 1
332# define HAVE_GETUID 1
333# define HAVE_KILL 1
334# define HAVE_OPENDIR 1
335# define HAVE_PIPE 1
336# define HAVE_SYSTEM 1
337# define HAVE_WAIT 1
338# define HAVE_TTYNAME 1
339# endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000340#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000341
Eddie Elizondob3966632019-11-05 07:16:14 -0800342_Py_IDENTIFIER(__fspath__);
Victor Stinnera2f7c002012-02-08 03:36:25 +0100343
Larry Hastings61272b72014-01-07 12:41:53 -0800344/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000345# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800346module os
Larry Hastings61272b72014-01-07 12:41:53 -0800347[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000348/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100349
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000350#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000351
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000352#if defined(__sgi)&&_COMPILER_VERSION>=700
353/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
354 (default) */
355extern char *ctermid_r(char *);
356#endif
357
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000358#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000359
pxinwrf2d7ac72019-05-21 18:46:37 +0800360#if defined(__VXWORKS__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200361# include <vxCpuLib.h>
362# include <rtpLib.h>
363# include <wait.h>
364# include <taskLib.h>
365# ifndef _P_WAIT
366# define _P_WAIT 0
367# define _P_NOWAIT 1
368# define _P_NOWAITO 1
369# endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800370#endif /* __VXWORKS__ */
371
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000372#ifdef HAVE_POSIX_SPAWN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200373# include <spawn.h>
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000374#endif
375
Guido van Rossumb6775db1994-08-01 11:34:53 +0000376#ifdef HAVE_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200377# include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000378#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000379
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000380#ifdef HAVE_SYS_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200381# include <sys/utime.h>
382# define HAVE_UTIME_H /* pretend we do for the rest of this file */
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000383#endif /* HAVE_SYS_UTIME_H */
384
Guido van Rossumb6775db1994-08-01 11:34:53 +0000385#ifdef HAVE_SYS_TIMES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200386# include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000387#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000388
389#ifdef HAVE_SYS_PARAM_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200390# include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000391#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000392
393#ifdef HAVE_SYS_UTSNAME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200394# include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000395#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000396
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000397#ifdef HAVE_DIRENT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200398# include <dirent.h>
399# define NAMLEN(dirent) strlen((dirent)->d_name)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000400#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200401# if defined(__WATCOMC__) && !defined(__QNX__)
402# include <direct.h>
403# define NAMLEN(dirent) strlen((dirent)->d_name)
404# else
405# define dirent direct
406# define NAMLEN(dirent) (dirent)->d_namlen
407# endif
408# ifdef HAVE_SYS_NDIR_H
409# include <sys/ndir.h>
410# endif
411# ifdef HAVE_SYS_DIR_H
412# include <sys/dir.h>
413# endif
414# ifdef HAVE_NDIR_H
415# include <ndir.h>
416# endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000417#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000418
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000419#ifdef _MSC_VER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200420# ifdef HAVE_DIRECT_H
421# include <direct.h>
422# endif
423# ifdef HAVE_IO_H
424# include <io.h>
425# endif
426# ifdef HAVE_PROCESS_H
427# include <process.h>
428# endif
429# ifndef IO_REPARSE_TAG_SYMLINK
430# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
431# endif
432# ifndef IO_REPARSE_TAG_MOUNT_POINT
433# define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
434# endif
435# include "osdefs.h" // SEP
436# include <malloc.h>
437# include <windows.h>
438# include <shellapi.h> // ShellExecute()
439# include <lmcons.h> // UNLEN
440# define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000441#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000442
Tim Petersbc2e10e2002-03-03 23:17:02 +0000443#ifndef MAXPATHLEN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200444# if defined(PATH_MAX) && PATH_MAX > 1024
445# define MAXPATHLEN PATH_MAX
446# else
447# define MAXPATHLEN 1024
448# endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000449#endif /* MAXPATHLEN */
450
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000451#ifdef UNION_WAIT
Victor Stinner5eca75d2020-04-15 15:07:31 +0200452 /* Emulate some macros on systems that have a union instead of macros */
453# ifndef WIFEXITED
454# define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
455# endif
456# ifndef WEXITSTATUS
457# define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
458# endif
459# ifndef WTERMSIG
460# define WTERMSIG(u_wait) ((u_wait).w_termsig)
461# endif
462# define WAIT_TYPE union wait
463# define WAIT_STATUS_INT(s) (s.w_status)
464#else
465 /* !UNION_WAIT */
466# define WAIT_TYPE int
467# define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000468#endif /* UNION_WAIT */
469
Greg Wardb48bc172000-03-01 21:51:56 +0000470/* Don't use the "_r" form if we don't need it (also, won't have a
471 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200472#if defined(HAVE_CTERMID_R)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200473# define USE_CTERMID_R
Greg Wardb48bc172000-03-01 21:51:56 +0000474#endif
475
Fred Drake699f3522000-06-29 21:12:41 +0000476/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000477#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000478#undef FSTAT
479#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200480#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200481# define STAT win32_stat
482# define LSTAT win32_lstat
483# define FSTAT _Py_fstat_noraise
484# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000485#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200486# define STAT stat
487# define LSTAT lstat
488# define FSTAT fstat
489# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000490#endif
491
Tim Peters11b23062003-04-23 02:39:17 +0000492#if defined(MAJOR_IN_MKDEV)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200493# include <sys/mkdev.h>
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000494#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200495# if defined(MAJOR_IN_SYSMACROS)
496# include <sys/sysmacros.h>
497# endif
498# if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
499# include <sys/mkdev.h>
500# endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000501#endif
Fred Drake699f3522000-06-29 21:12:41 +0000502
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200503#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200504# define INITFUNC PyInit_nt
505# define MODNAME "nt"
Victor Stinner6036e442015-03-08 01:58:04 +0100506#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200507# define INITFUNC PyInit_posix
508# define MODNAME "posix"
Victor Stinner6036e442015-03-08 01:58:04 +0100509#endif
510
jcea6c51d512018-01-28 14:00:08 +0100511#if defined(__sun)
512/* Something to implement in autoconf, not present in autoconf 2.69 */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200513# define HAVE_STRUCT_STAT_ST_FSTYPE 1
jcea6c51d512018-01-28 14:00:08 +0100514#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200515
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600516/* memfd_create is either defined in sys/mman.h or sys/memfd.h
517 * linux/memfd.h defines additional flags
518 */
519#ifdef HAVE_SYS_MMAN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200520# include <sys/mman.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600521#endif
522#ifdef HAVE_SYS_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200523# include <sys/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600524#endif
525#ifdef HAVE_LINUX_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200526# include <linux/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600527#endif
528
Christian Heimescd9fed62020-11-13 19:48:52 +0100529/* eventfd() */
530#ifdef HAVE_SYS_EVENTFD_H
531# include <sys/eventfd.h>
532#endif
533
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800534#ifdef _Py_MEMORY_SANITIZER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200535# include <sanitizer/msan_interface.h>
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800536#endif
537
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200538#ifdef HAVE_FORK
539static void
540run_at_forkers(PyObject *lst, int reverse)
541{
542 Py_ssize_t i;
543 PyObject *cpy;
544
545 if (lst != NULL) {
546 assert(PyList_CheckExact(lst));
547
548 /* Use a list copy in case register_at_fork() is called from
549 * one of the callbacks.
550 */
551 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
552 if (cpy == NULL)
553 PyErr_WriteUnraisable(lst);
554 else {
555 if (reverse)
556 PyList_Reverse(cpy);
557 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
558 PyObject *func, *res;
559 func = PyList_GET_ITEM(cpy, i);
Jeroen Demeyer7f41c8e2019-07-04 12:35:31 +0200560 res = _PyObject_CallNoArg(func);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200561 if (res == NULL)
562 PyErr_WriteUnraisable(func);
563 else
564 Py_DECREF(res);
565 }
566 Py_DECREF(cpy);
567 }
568 }
569}
570
571void
572PyOS_BeforeFork(void)
573{
Victor Stinner81a7be32020-04-14 15:14:01 +0200574 run_at_forkers(_PyInterpreterState_GET()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200575
576 _PyImport_AcquireLock();
577}
578
579void
580PyOS_AfterFork_Parent(void)
581{
582 if (_PyImport_ReleaseLock() <= 0)
583 Py_FatalError("failed releasing import lock after fork");
584
Victor Stinner81a7be32020-04-14 15:14:01 +0200585 run_at_forkers(_PyInterpreterState_GET()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200586}
587
588void
589PyOS_AfterFork_Child(void)
590{
Victor Stinner26881c82020-06-02 15:51:37 +0200591 PyStatus status;
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200592 _PyRuntimeState *runtime = &_PyRuntime;
Victor Stinner26881c82020-06-02 15:51:37 +0200593
594 status = _PyGILState_Reinit(runtime);
595 if (_PyStatus_EXCEPTION(status)) {
596 goto fatal_error;
597 }
598
Victor Stinner317bab02020-06-02 18:44:54 +0200599 PyThreadState *tstate = _PyThreadState_GET();
600 _Py_EnsureTstateNotNULL(tstate);
601
602 status = _PyEval_ReInitThreads(tstate);
Victor Stinner26881c82020-06-02 15:51:37 +0200603 if (_PyStatus_EXCEPTION(status)) {
604 goto fatal_error;
605 }
606
607 status = _PyImport_ReInitLock();
608 if (_PyStatus_EXCEPTION(status)) {
609 goto fatal_error;
610 }
611
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200612 _PySignal_AfterFork();
Victor Stinner26881c82020-06-02 15:51:37 +0200613
614 status = _PyRuntimeState_ReInitThreads(runtime);
615 if (_PyStatus_EXCEPTION(status)) {
616 goto fatal_error;
617 }
618
619 status = _PyInterpreterState_DeleteExceptMain(runtime);
620 if (_PyStatus_EXCEPTION(status)) {
621 goto fatal_error;
622 }
Victor Stinner317bab02020-06-02 18:44:54 +0200623 assert(_PyThreadState_GET() == tstate);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200624
Victor Stinner317bab02020-06-02 18:44:54 +0200625 run_at_forkers(tstate->interp->after_forkers_child, 0);
Victor Stinner26881c82020-06-02 15:51:37 +0200626 return;
627
628fatal_error:
629 Py_ExitStatusException(status);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200630}
631
632static int
633register_at_forker(PyObject **lst, PyObject *func)
634{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700635 if (func == NULL) /* nothing to register? do nothing. */
636 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200637 if (*lst == NULL) {
638 *lst = PyList_New(0);
639 if (*lst == NULL)
640 return -1;
641 }
642 return PyList_Append(*lst, func);
643}
Victor Stinner87255be2020-04-07 23:11:49 +0200644#endif /* HAVE_FORK */
645
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200646
647/* Legacy wrapper */
648void
649PyOS_AfterFork(void)
650{
651#ifdef HAVE_FORK
652 PyOS_AfterFork_Child();
653#endif
654}
655
656
Victor Stinner6036e442015-03-08 01:58:04 +0100657#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200658/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700659void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
660void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200661 ULONG, struct _Py_stat_struct *);
662#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700663
Larry Hastings9cf065c2012-06-22 16:30:09 -0700664
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200665#ifndef MS_WINDOWS
666PyObject *
667_PyLong_FromUid(uid_t uid)
668{
669 if (uid == (uid_t)-1)
670 return PyLong_FromLong(-1);
671 return PyLong_FromUnsignedLong(uid);
672}
673
674PyObject *
675_PyLong_FromGid(gid_t gid)
676{
677 if (gid == (gid_t)-1)
678 return PyLong_FromLong(-1);
679 return PyLong_FromUnsignedLong(gid);
680}
681
682int
Jakub Kulík0159e5e2020-12-29 13:58:27 +0100683_Py_Uid_Converter(PyObject *obj, uid_t *p)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200684{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700685 uid_t uid;
686 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200687 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200688 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700689 unsigned long uresult;
690
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300691 index = _PyNumber_Index(obj);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700692 if (index == NULL) {
693 PyErr_Format(PyExc_TypeError,
694 "uid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800695 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200696 return 0;
697 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700698
699 /*
700 * Handling uid_t is complicated for two reasons:
701 * * Although uid_t is (always?) unsigned, it still
702 * accepts -1.
703 * * We don't know its size in advance--it may be
704 * bigger than an int, or it may be smaller than
705 * a long.
706 *
707 * So a bit of defensive programming is in order.
708 * Start with interpreting the value passed
709 * in as a signed long and see if it works.
710 */
711
712 result = PyLong_AsLongAndOverflow(index, &overflow);
713
714 if (!overflow) {
715 uid = (uid_t)result;
716
717 if (result == -1) {
718 if (PyErr_Occurred())
719 goto fail;
720 /* It's a legitimate -1, we're done. */
721 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200722 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700723
724 /* Any other negative number is disallowed. */
725 if (result < 0)
726 goto underflow;
727
728 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200729 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700730 (long)uid != result)
731 goto underflow;
732 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200733 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700734
735 if (overflow < 0)
736 goto underflow;
737
738 /*
739 * Okay, the value overflowed a signed long. If it
740 * fits in an *unsigned* long, it may still be okay,
741 * as uid_t may be unsigned long on this platform.
742 */
743 uresult = PyLong_AsUnsignedLong(index);
744 if (PyErr_Occurred()) {
745 if (PyErr_ExceptionMatches(PyExc_OverflowError))
746 goto overflow;
747 goto fail;
748 }
749
750 uid = (uid_t)uresult;
751
752 /*
753 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
754 * but this value would get interpreted as (uid_t)-1 by chown
755 * and its siblings. That's not what the user meant! So we
756 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100757 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700758 */
759 if (uid == (uid_t)-1)
760 goto overflow;
761
762 /* Ensure the value wasn't truncated. */
763 if (sizeof(uid_t) < sizeof(long) &&
764 (unsigned long)uid != uresult)
765 goto overflow;
766 /* fallthrough */
767
768success:
769 Py_DECREF(index);
Jakub Kulík0159e5e2020-12-29 13:58:27 +0100770 *p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200771 return 1;
772
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700773underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200774 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700775 "uid is less than minimum");
776 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200777
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700778overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200779 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700780 "uid is greater than maximum");
781 /* fallthrough */
782
783fail:
784 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200785 return 0;
786}
787
788int
Jakub Kulík0159e5e2020-12-29 13:58:27 +0100789_Py_Gid_Converter(PyObject *obj, gid_t *p)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200790{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700791 gid_t gid;
792 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200793 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200794 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700795 unsigned long uresult;
796
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300797 index = _PyNumber_Index(obj);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700798 if (index == NULL) {
799 PyErr_Format(PyExc_TypeError,
800 "gid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800801 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200802 return 0;
803 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700804
805 /*
806 * Handling gid_t is complicated for two reasons:
807 * * Although gid_t is (always?) unsigned, it still
808 * accepts -1.
809 * * We don't know its size in advance--it may be
810 * bigger than an int, or it may be smaller than
811 * a long.
812 *
813 * So a bit of defensive programming is in order.
814 * Start with interpreting the value passed
815 * in as a signed long and see if it works.
816 */
817
818 result = PyLong_AsLongAndOverflow(index, &overflow);
819
820 if (!overflow) {
821 gid = (gid_t)result;
822
823 if (result == -1) {
824 if (PyErr_Occurred())
825 goto fail;
826 /* It's a legitimate -1, we're done. */
827 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200828 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700829
830 /* Any other negative number is disallowed. */
831 if (result < 0) {
832 goto underflow;
833 }
834
835 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200836 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700837 (long)gid != result)
838 goto underflow;
839 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200840 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700841
842 if (overflow < 0)
843 goto underflow;
844
845 /*
846 * Okay, the value overflowed a signed long. If it
847 * fits in an *unsigned* long, it may still be okay,
848 * as gid_t may be unsigned long on this platform.
849 */
850 uresult = PyLong_AsUnsignedLong(index);
851 if (PyErr_Occurred()) {
852 if (PyErr_ExceptionMatches(PyExc_OverflowError))
853 goto overflow;
854 goto fail;
855 }
856
857 gid = (gid_t)uresult;
858
859 /*
860 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
861 * but this value would get interpreted as (gid_t)-1 by chown
862 * and its siblings. That's not what the user meant! So we
863 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100864 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700865 */
866 if (gid == (gid_t)-1)
867 goto overflow;
868
869 /* Ensure the value wasn't truncated. */
870 if (sizeof(gid_t) < sizeof(long) &&
871 (unsigned long)gid != uresult)
872 goto overflow;
873 /* fallthrough */
874
875success:
876 Py_DECREF(index);
Jakub Kulík0159e5e2020-12-29 13:58:27 +0100877 *p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200878 return 1;
879
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700880underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200881 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700882 "gid is less than minimum");
883 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200884
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700885overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200886 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700887 "gid is greater than maximum");
888 /* fallthrough */
889
890fail:
891 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200892 return 0;
893}
894#endif /* MS_WINDOWS */
895
896
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700897#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800898
899
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200900#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
901static int
902_Py_Dev_Converter(PyObject *obj, void *p)
903{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200904 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200905 if (PyErr_Occurred())
906 return 0;
907 return 1;
908}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800909#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200910
911
Larry Hastings9cf065c2012-06-22 16:30:09 -0700912#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400913/*
914 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
915 * without the int cast, the value gets interpreted as uint (4291925331),
916 * which doesn't play nicely with all the initializer lines in this file that
917 * look like this:
918 * int dir_fd = DEFAULT_DIR_FD;
919 */
920#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700921#else
922#define DEFAULT_DIR_FD (-100)
923#endif
924
925static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300926_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200927{
928 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700929 long long_value;
930
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300931 PyObject *index = _PyNumber_Index(o);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700932 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933 return 0;
934 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700935
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300936 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700937 long_value = PyLong_AsLongAndOverflow(index, &overflow);
938 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300939 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200940 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700942 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943 return 0;
944 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200945 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700946 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700947 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700948 return 0;
949 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700950
Larry Hastings9cf065c2012-06-22 16:30:09 -0700951 *p = (int)long_value;
952 return 1;
953}
954
955static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200956dir_fd_converter(PyObject *o, void *p)
957{
958 if (o == Py_None) {
959 *(int *)p = DEFAULT_DIR_FD;
960 return 1;
961 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300962 else if (PyIndex_Check(o)) {
963 return _fd_converter(o, (int *)p);
964 }
965 else {
966 PyErr_Format(PyExc_TypeError,
967 "argument should be integer or None, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800968 _PyType_Name(Py_TYPE(o)));
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300969 return 0;
970 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700971}
972
Eddie Elizondob3966632019-11-05 07:16:14 -0800973typedef struct {
974 PyObject *billion;
Eddie Elizondob3966632019-11-05 07:16:14 -0800975 PyObject *DirEntryType;
976 PyObject *ScandirIteratorType;
977#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
978 PyObject *SchedParamType;
979#endif
980 PyObject *StatResultType;
981 PyObject *StatVFSResultType;
982 PyObject *TerminalSizeType;
983 PyObject *TimesResultType;
984 PyObject *UnameResultType;
985#if defined(HAVE_WAITID) && !defined(__APPLE__)
986 PyObject *WaitidResultType;
987#endif
988#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
989 PyObject *struct_rusage;
990#endif
991 PyObject *st_mode;
992} _posixstate;
993
Eddie Elizondob3966632019-11-05 07:16:14 -0800994
Hai Shif707d942020-03-16 21:15:01 +0800995static inline _posixstate*
996get_posix_state(PyObject *module)
997{
Victor Stinnercdad2722021-04-22 00:52:52 +0200998 void *state = _PyModule_GetState(module);
Hai Shif707d942020-03-16 21:15:01 +0800999 assert(state != NULL);
1000 return (_posixstate *)state;
1001}
1002
Larry Hastings9cf065c2012-06-22 16:30:09 -07001003/*
1004 * A PyArg_ParseTuple "converter" function
1005 * that handles filesystem paths in the manner
1006 * preferred by the os module.
1007 *
1008 * path_converter accepts (Unicode) strings and their
1009 * subclasses, and bytes and their subclasses. What
1010 * it does with the argument depends on the platform:
1011 *
1012 * * On Windows, if we get a (Unicode) string we
1013 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -07001014 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -07001015 *
1016 * * On all other platforms, strings are encoded
1017 * to bytes using PyUnicode_FSConverter, then we
1018 * extract the char * from the bytes object and
1019 * return that.
1020 *
1021 * path_converter also optionally accepts signed
1022 * integers (representing open file descriptors) instead
1023 * of path strings.
1024 *
1025 * Input fields:
1026 * path.nullable
1027 * If nonzero, the path is permitted to be None.
1028 * path.allow_fd
1029 * If nonzero, the path is permitted to be a file handle
1030 * (a signed int) instead of a string.
1031 * path.function_name
1032 * If non-NULL, path_converter will use that as the name
1033 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -07001034 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001035 * path.argument_name
1036 * If non-NULL, path_converter will use that as the name
1037 * of the parameter in error messages.
1038 * (If path.argument_name is NULL it uses "path".)
1039 *
1040 * Output fields:
1041 * path.wide
1042 * Points to the path if it was expressed as Unicode
1043 * and was not encoded. (Only used on Windows.)
1044 * path.narrow
1045 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -07001046 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +00001047 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -07001048 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001049 * path.fd
1050 * Contains a file descriptor if path.accept_fd was true
1051 * and the caller provided a signed integer instead of any
1052 * sort of string.
1053 *
1054 * WARNING: if your "path" parameter is optional, and is
1055 * unspecified, path_converter will never get called.
1056 * So if you set allow_fd, you *MUST* initialize path.fd = -1
1057 * yourself!
1058 * path.length
1059 * The length of the path in characters, if specified as
1060 * a string.
1061 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +08001062 * The original object passed in (if get a PathLike object,
1063 * the result of PyOS_FSPath() is treated as the original object).
1064 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -07001065 * path.cleanup
1066 * For internal use only. May point to a temporary object.
1067 * (Pay no attention to the man behind the curtain.)
1068 *
1069 * At most one of path.wide or path.narrow will be non-NULL.
1070 * If path was None and path.nullable was set,
1071 * or if path was an integer and path.allow_fd was set,
1072 * both path.wide and path.narrow will be NULL
1073 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +02001074 *
Larry Hastings9cf065c2012-06-22 16:30:09 -07001075 * path_converter takes care to not write to the path_t
1076 * unless it's successful. However it must reset the
1077 * "cleanup" field each time it's called.
1078 *
1079 * Use as follows:
1080 * path_t path;
1081 * memset(&path, 0, sizeof(path));
1082 * PyArg_ParseTuple(args, "O&", path_converter, &path);
1083 * // ... use values from path ...
1084 * path_cleanup(&path);
1085 *
1086 * (Note that if PyArg_Parse fails you don't need to call
1087 * path_cleanup(). However it is safe to do so.)
1088 */
1089typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +01001090 const char *function_name;
1091 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001092 int nullable;
1093 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001094 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -07001095#ifdef MS_WINDOWS
1096 BOOL narrow;
1097#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001098 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001099#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001100 int fd;
1101 Py_ssize_t length;
1102 PyObject *object;
1103 PyObject *cleanup;
1104} path_t;
1105
Steve Dowercc16be82016-09-08 10:35:16 -07001106#ifdef MS_WINDOWS
1107#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
1108 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
1109#else
Larry Hastings2f936352014-08-05 14:04:04 +10001110#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
1111 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -07001112#endif
Larry Hastings31826802013-10-19 00:09:25 -07001113
Larry Hastings9cf065c2012-06-22 16:30:09 -07001114static void
Xiang Zhang04316c42017-01-08 23:26:57 +08001115path_cleanup(path_t *path)
1116{
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001117#if !USE_UNICODE_WCHAR_CACHE
1118 wchar_t *wide = (wchar_t *)path->wide;
1119 path->wide = NULL;
1120 PyMem_Free(wide);
1121#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001122 Py_CLEAR(path->object);
1123 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001124}
1125
1126static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001127path_converter(PyObject *o, void *p)
1128{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001129 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +08001130 PyObject *bytes = NULL;
1131 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001132 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001133 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001134#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +08001135 PyObject *wo = NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001136 wchar_t *wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001137#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001138
1139#define FORMAT_EXCEPTION(exc, fmt) \
1140 PyErr_Format(exc, "%s%s" fmt, \
1141 path->function_name ? path->function_name : "", \
1142 path->function_name ? ": " : "", \
1143 path->argument_name ? path->argument_name : "path")
1144
1145 /* Py_CLEANUP_SUPPORTED support */
1146 if (o == NULL) {
1147 path_cleanup(path);
1148 return 1;
1149 }
1150
Brett Cannon3f9183b2016-08-26 14:44:48 -07001151 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +08001152 path->object = path->cleanup = NULL;
1153 /* path->object owns a reference to the original object */
1154 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001155
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001156 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001157 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001158#ifdef MS_WINDOWS
1159 path->narrow = FALSE;
1160#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001161 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001162#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001163 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001164 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001165 }
1166
Brett Cannon3f9183b2016-08-26 14:44:48 -07001167 /* Only call this here so that we don't treat the return value of
1168 os.fspath() as an fd or buffer. */
1169 is_index = path->allow_fd && PyIndex_Check(o);
1170 is_buffer = PyObject_CheckBuffer(o);
1171 is_bytes = PyBytes_Check(o);
1172 is_unicode = PyUnicode_Check(o);
1173
1174 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
1175 /* Inline PyOS_FSPath() for better error messages. */
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001176 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001177
1178 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1179 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001180 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001181 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001182 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001183 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001184 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001185 goto error_exit;
1186 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001187 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001188 is_unicode = 1;
1189 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001190 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001191 is_bytes = 1;
1192 }
1193 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001194 PyErr_Format(PyExc_TypeError,
1195 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -08001196 "not %.200s", _PyType_Name(Py_TYPE(o)),
1197 _PyType_Name(Py_TYPE(res)));
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001198 Py_DECREF(res);
1199 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001200 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001201
1202 /* still owns a reference to the original object */
1203 Py_DECREF(o);
1204 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001205 }
1206
1207 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001208#ifdef MS_WINDOWS
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001209#if USE_UNICODE_WCHAR_CACHE
1210_Py_COMP_DIAG_PUSH
1211_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001212 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001213_Py_COMP_DIAG_POP
1214#else /* USE_UNICODE_WCHAR_CACHE */
1215 wide = PyUnicode_AsWideCharString(o, &length);
1216#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner59799a82013-11-13 14:17:30 +01001217 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001218 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219 }
Victor Stinner59799a82013-11-13 14:17:30 +01001220 if (length > 32767) {
1221 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001222 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001223 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001224 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001225 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001226 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001227 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001228
1229 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001230 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001231 path->fd = -1;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001232#if !USE_UNICODE_WCHAR_CACHE
1233 wide = NULL;
1234#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001235 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001236#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001237 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001238 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001239 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001240#endif
1241 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001242 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001243 bytes = o;
1244 Py_INCREF(bytes);
1245 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001246 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001247 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001248 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001249 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1250 "%s%s%s should be %s, not %.200s",
1251 path->function_name ? path->function_name : "",
1252 path->function_name ? ": " : "",
1253 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001254 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1255 "integer or None" :
1256 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1257 path->nullable ? "string, bytes, os.PathLike or None" :
1258 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001259 _PyType_Name(Py_TYPE(o)))) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001260 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001261 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001262 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001263 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001264 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001265 }
1266 }
Steve Dowercc16be82016-09-08 10:35:16 -07001267 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001268 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001269 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001270 }
1271 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001272#ifdef MS_WINDOWS
1273 path->narrow = FALSE;
1274#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001275 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001276#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001277 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001278 }
1279 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001280 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001281 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1282 path->function_name ? path->function_name : "",
1283 path->function_name ? ": " : "",
1284 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001285 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1286 "integer or None" :
1287 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1288 path->nullable ? "string, bytes, os.PathLike or None" :
1289 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001290 _PyType_Name(Py_TYPE(o)));
Xiang Zhang04316c42017-01-08 23:26:57 +08001291 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001292 }
1293
Larry Hastings9cf065c2012-06-22 16:30:09 -07001294 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001295 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001296 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001297 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001298 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001299 }
1300
Steve Dowercc16be82016-09-08 10:35:16 -07001301#ifdef MS_WINDOWS
1302 wo = PyUnicode_DecodeFSDefaultAndSize(
1303 narrow,
1304 length
1305 );
1306 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001307 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001308 }
1309
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001310#if USE_UNICODE_WCHAR_CACHE
1311_Py_COMP_DIAG_PUSH
1312_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Xiang Zhang04316c42017-01-08 23:26:57 +08001313 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001314_Py_COMP_DIAG_POP
1315#else /* USE_UNICODE_WCHAR_CACHE */
1316 wide = PyUnicode_AsWideCharString(wo, &length);
1317 Py_DECREF(wo);
1318#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowercc16be82016-09-08 10:35:16 -07001319 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001320 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001321 }
1322 if (length > 32767) {
1323 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001324 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001325 }
1326 if (wcslen(wide) != length) {
1327 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001328 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001329 }
1330 path->wide = wide;
1331 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001332 Py_DECREF(bytes);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001333#if USE_UNICODE_WCHAR_CACHE
1334 path->cleanup = wo;
1335#else /* USE_UNICODE_WCHAR_CACHE */
1336 wide = NULL;
1337#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowercc16be82016-09-08 10:35:16 -07001338#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001339 path->wide = NULL;
1340 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001341 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001342 /* Still a reference owned by path->object, don't have to
1343 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001344 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001345 }
1346 else {
1347 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001348 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001349#endif
1350 path->fd = -1;
1351
1352 success_exit:
1353 path->length = length;
1354 path->object = o;
1355 return Py_CLEANUP_SUPPORTED;
1356
1357 error_exit:
1358 Py_XDECREF(o);
1359 Py_XDECREF(bytes);
1360#ifdef MS_WINDOWS
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001361#if USE_UNICODE_WCHAR_CACHE
Xiang Zhang04316c42017-01-08 23:26:57 +08001362 Py_XDECREF(wo);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001363#else /* USE_UNICODE_WCHAR_CACHE */
1364 PyMem_Free(wide);
1365#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001366#endif
1367 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001368}
1369
1370static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001371argument_unavailable_error(const char *function_name, const char *argument_name)
1372{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001373 PyErr_Format(PyExc_NotImplementedError,
1374 "%s%s%s unavailable on this platform",
1375 (function_name != NULL) ? function_name : "",
1376 (function_name != NULL) ? ": ": "",
1377 argument_name);
1378}
1379
1380static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001381dir_fd_unavailable(PyObject *o, void *p)
1382{
1383 int dir_fd;
1384 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001385 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001386 if (dir_fd != DEFAULT_DIR_FD) {
1387 argument_unavailable_error(NULL, "dir_fd");
1388 return 0;
1389 }
1390 *(int *)p = dir_fd;
1391 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001392}
1393
1394static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001395fd_specified(const char *function_name, int fd)
1396{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001397 if (fd == -1)
1398 return 0;
1399
1400 argument_unavailable_error(function_name, "fd");
1401 return 1;
1402}
1403
1404static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001405follow_symlinks_specified(const char *function_name, int follow_symlinks)
1406{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001407 if (follow_symlinks)
1408 return 0;
1409
1410 argument_unavailable_error(function_name, "follow_symlinks");
1411 return 1;
1412}
1413
1414static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001415path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1416{
Steve Dowercc16be82016-09-08 10:35:16 -07001417 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1418#ifndef MS_WINDOWS
1419 && !path->narrow
1420#endif
1421 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001422 PyErr_Format(PyExc_ValueError,
1423 "%s: can't specify dir_fd without matching path",
1424 function_name);
1425 return 1;
1426 }
1427 return 0;
1428}
1429
1430static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001431dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1432{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001433 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1434 PyErr_Format(PyExc_ValueError,
1435 "%s: can't specify both dir_fd and fd",
1436 function_name);
1437 return 1;
1438 }
1439 return 0;
1440}
1441
1442static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001443fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1444 int follow_symlinks)
1445{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001446 if ((fd > 0) && (!follow_symlinks)) {
1447 PyErr_Format(PyExc_ValueError,
1448 "%s: cannot use fd and follow_symlinks together",
1449 function_name);
1450 return 1;
1451 }
1452 return 0;
1453}
1454
1455static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001456dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1457 int follow_symlinks)
1458{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001459 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1460 PyErr_Format(PyExc_ValueError,
1461 "%s: cannot use dir_fd and follow_symlinks together",
1462 function_name);
1463 return 1;
1464 }
1465 return 0;
1466}
1467
Larry Hastings2f936352014-08-05 14:04:04 +10001468#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001469 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001470#else
Larry Hastings2f936352014-08-05 14:04:04 +10001471 typedef off_t Py_off_t;
1472#endif
1473
1474static int
1475Py_off_t_converter(PyObject *arg, void *addr)
1476{
1477#ifdef HAVE_LARGEFILE_SUPPORT
1478 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1479#else
1480 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001481#endif
1482 if (PyErr_Occurred())
1483 return 0;
1484 return 1;
1485}
Larry Hastings2f936352014-08-05 14:04:04 +10001486
1487static PyObject *
1488PyLong_FromPy_off_t(Py_off_t offset)
1489{
1490#ifdef HAVE_LARGEFILE_SUPPORT
1491 return PyLong_FromLongLong(offset);
1492#else
1493 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001494#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001495}
1496
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001497#ifdef HAVE_SIGSET_T
1498/* Convert an iterable of integers to a sigset.
1499 Return 1 on success, return 0 and raise an exception on error. */
1500int
1501_Py_Sigset_Converter(PyObject *obj, void *addr)
1502{
1503 sigset_t *mask = (sigset_t *)addr;
1504 PyObject *iterator, *item;
1505 long signum;
1506 int overflow;
1507
Rémi Lapeyref0900192019-05-04 01:30:53 +02001508 // The extra parens suppress the unreachable-code warning with clang on MacOS
1509 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001510 /* Probably only if mask == NULL. */
1511 PyErr_SetFromErrno(PyExc_OSError);
1512 return 0;
1513 }
1514
1515 iterator = PyObject_GetIter(obj);
1516 if (iterator == NULL) {
1517 return 0;
1518 }
1519
1520 while ((item = PyIter_Next(iterator)) != NULL) {
1521 signum = PyLong_AsLongAndOverflow(item, &overflow);
1522 Py_DECREF(item);
1523 if (signum <= 0 || signum >= NSIG) {
1524 if (overflow || signum != -1 || !PyErr_Occurred()) {
1525 PyErr_Format(PyExc_ValueError,
1526 "signal number %ld out of range", signum);
1527 }
1528 goto error;
1529 }
1530 if (sigaddset(mask, (int)signum)) {
1531 if (errno != EINVAL) {
1532 /* Probably impossible */
1533 PyErr_SetFromErrno(PyExc_OSError);
1534 goto error;
1535 }
1536 /* For backwards compatibility, allow idioms such as
1537 * `range(1, NSIG)` but warn about invalid signal numbers
1538 */
1539 const char msg[] =
1540 "invalid signal number %ld, please use valid_signals()";
1541 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1542 goto error;
1543 }
1544 }
1545 }
1546 if (!PyErr_Occurred()) {
1547 Py_DECREF(iterator);
1548 return 1;
1549 }
1550
1551error:
1552 Py_DECREF(iterator);
1553 return 0;
1554}
1555#endif /* HAVE_SIGSET_T */
1556
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001557#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001558
1559static int
Brian Curtind25aef52011-06-13 15:16:04 -05001560win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001561{
Martin Panter70214ad2016-08-04 02:38:59 +00001562 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1563 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001564 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001565
1566 if (0 == DeviceIoControl(
1567 reparse_point_handle,
1568 FSCTL_GET_REPARSE_POINT,
1569 NULL, 0, /* in buffer */
1570 target_buffer, sizeof(target_buffer),
1571 &n_bytes_returned,
1572 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001573 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001574
1575 if (reparse_tag)
1576 *reparse_tag = rdb->ReparseTag;
1577
Brian Curtind25aef52011-06-13 15:16:04 -05001578 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001579}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001580
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001581#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001582
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001583/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001584#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001585/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001586** environ directly, we must obtain it with _NSGetEnviron(). See also
1587** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001588*/
1589#include <crt_externs.h>
pxinwrf2d7ac72019-05-21 18:46:37 +08001590#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001591extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001592#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001593
Barry Warsaw53699e91996-12-10 23:23:01 +00001594static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001595convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001596{
Victor Stinner8c62be82010-05-06 00:08:46 +00001597 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001598#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001599 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001600#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001601 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001602#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001603
Victor Stinner8c62be82010-05-06 00:08:46 +00001604 d = PyDict_New();
1605 if (d == NULL)
1606 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001607#ifdef MS_WINDOWS
1608 /* _wenviron must be initialized in this way if the program is started
1609 through main() instead of wmain(). */
1610 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001611 e = _wenviron;
Benoit Hudson723f71a2019-12-06 14:15:03 -05001612#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1613 /* environ is not accessible as an extern in a shared object on OSX; use
1614 _NSGetEnviron to resolve it. The value changes if you add environment
1615 variables between calls to Py_Initialize, so don't cache the value. */
1616 e = *_NSGetEnviron();
Victor Stinner8c62be82010-05-06 00:08:46 +00001617#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001618 e = environ;
1619#endif
1620 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001621 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001622 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001623 PyObject *k;
1624 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001625#ifdef MS_WINDOWS
1626 const wchar_t *p = wcschr(*e, L'=');
1627#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001628 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001629#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001630 if (p == NULL)
1631 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001632#ifdef MS_WINDOWS
1633 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1634#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001635 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001636#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001637 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001638 Py_DECREF(d);
1639 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001640 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001641#ifdef MS_WINDOWS
1642 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1643#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001644 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001645#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001646 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001647 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001648 Py_DECREF(d);
1649 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001650 }
Serhiy Storchakab510e102020-10-26 12:47:57 +02001651 if (PyDict_SetDefault(d, k, v) == NULL) {
1652 Py_DECREF(v);
1653 Py_DECREF(k);
1654 Py_DECREF(d);
1655 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001656 }
1657 Py_DECREF(k);
1658 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001659 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001660 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001661}
1662
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001663/* Set a POSIX-specific error from errno, and return NULL */
1664
Barry Warsawd58d7641998-07-23 16:14:40 +00001665static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001666posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001667{
Victor Stinner8c62be82010-05-06 00:08:46 +00001668 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001669}
Mark Hammondef8b6542001-05-13 08:04:26 +00001670
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001671#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001672static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001673win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001674{
Victor Stinner8c62be82010-05-06 00:08:46 +00001675 /* XXX We should pass the function name along in the future.
1676 (winreg.c also wants to pass the function name.)
1677 This would however require an additional param to the
1678 Windows error object, which is non-trivial.
1679 */
1680 errno = GetLastError();
1681 if (filename)
1682 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1683 else
1684 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001685}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001686
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001687static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001688win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001689{
1690 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001691 if (filename)
1692 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001693 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001694 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001695 filename);
1696 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001697 return PyErr_SetFromWindowsErr(err);
1698}
1699
1700static PyObject *
1701win32_error_object(const char* function, PyObject* filename)
1702{
1703 errno = GetLastError();
1704 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001705}
1706
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001707#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001708
Larry Hastings9cf065c2012-06-22 16:30:09 -07001709static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001710posix_path_object_error(PyObject *path)
1711{
1712 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1713}
1714
1715static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001716path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001717{
1718#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001719 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1720 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001721#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001722 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001723#endif
1724}
1725
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001726static PyObject *
1727path_object_error2(PyObject *path, PyObject *path2)
1728{
1729#ifdef MS_WINDOWS
1730 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1731 PyExc_OSError, 0, path, path2);
1732#else
1733 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1734#endif
1735}
1736
1737static PyObject *
1738path_error(path_t *path)
1739{
1740 return path_object_error(path->object);
1741}
Larry Hastings31826802013-10-19 00:09:25 -07001742
Larry Hastingsb0827312014-02-09 22:05:19 -08001743static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001744posix_path_error(path_t *path)
1745{
1746 return posix_path_object_error(path->object);
1747}
1748
1749static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001750path_error2(path_t *path, path_t *path2)
1751{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001752 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001753}
1754
1755
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001756/* POSIX generic methods */
1757
Larry Hastings2f936352014-08-05 14:04:04 +10001758static PyObject *
1759posix_fildes_fd(int fd, int (*func)(int))
1760{
1761 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001762 int async_err = 0;
1763
1764 do {
1765 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001766 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001767 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001768 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001769 Py_END_ALLOW_THREADS
1770 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1771 if (res != 0)
1772 return (!async_err) ? posix_error() : NULL;
1773 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001774}
Guido van Rossum21142a01999-01-08 21:05:37 +00001775
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001776
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001777#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001778/* This is a reimplementation of the C library's chdir function,
1779 but one that produces Win32 errors instead of DOS error codes.
1780 chdir is essentially a wrapper around SetCurrentDirectory; however,
1781 it also needs to set "magic" environment variables indicating
1782 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001783static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001784win32_wchdir(LPCWSTR path)
1785{
Victor Stinnered537822015-12-13 21:40:26 +01001786 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001787 int result;
1788 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001789
Victor Stinner8c62be82010-05-06 00:08:46 +00001790 if(!SetCurrentDirectoryW(path))
1791 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001792 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001793 if (!result)
1794 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001795 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001796 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 if (!new_path) {
1798 SetLastError(ERROR_OUTOFMEMORY);
1799 return FALSE;
1800 }
1801 result = GetCurrentDirectoryW(result, new_path);
1802 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001803 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001804 return FALSE;
1805 }
1806 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001807 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1808 wcsncmp(new_path, L"//", 2) == 0);
1809 if (!is_unc_like_path) {
1810 env[1] = new_path[0];
1811 result = SetEnvironmentVariableW(env, new_path);
1812 }
Victor Stinnered537822015-12-13 21:40:26 +01001813 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001814 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001815 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001816}
1817#endif
1818
Martin v. Löwis14694662006-02-03 12:54:16 +00001819#ifdef MS_WINDOWS
1820/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1821 - time stamps are restricted to second resolution
1822 - file modification times suffer from forth-and-back conversions between
1823 UTC and local time
1824 Therefore, we implement our own stat, based on the Win32 API directly.
1825*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001826#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001827#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001828#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001829
Victor Stinner6036e442015-03-08 01:58:04 +01001830static void
Steve Dowercc16be82016-09-08 10:35:16 -07001831find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1832 BY_HANDLE_FILE_INFORMATION *info,
1833 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001834{
1835 memset(info, 0, sizeof(*info));
1836 info->dwFileAttributes = pFileData->dwFileAttributes;
1837 info->ftCreationTime = pFileData->ftCreationTime;
1838 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1839 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1840 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1841 info->nFileSizeLow = pFileData->nFileSizeLow;
1842/* info->nNumberOfLinks = 1; */
1843 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1844 *reparse_tag = pFileData->dwReserved0;
1845 else
1846 *reparse_tag = 0;
1847}
1848
Guido van Rossumd8faa362007-04-27 19:54:29 +00001849static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001850attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001851{
Victor Stinner8c62be82010-05-06 00:08:46 +00001852 HANDLE hFindFile;
1853 WIN32_FIND_DATAW FileData;
Steve Dowerfe63a402021-04-22 20:45:02 +01001854 LPCWSTR filename = pszFile;
1855 size_t n = wcslen(pszFile);
1856 if (n && (pszFile[n - 1] == L'\\' || pszFile[n - 1] == L'/')) {
1857 // cannot use PyMem_Malloc here because we do not hold the GIL
1858 filename = (LPCWSTR)malloc((n + 1) * sizeof(filename[0]));
1859 wcsncpy_s((LPWSTR)filename, n + 1, pszFile, n);
1860 while (--n > 0 && (filename[n] == L'\\' || filename[n] == L'/')) {
1861 ((LPWSTR)filename)[n] = L'\0';
1862 }
Steve Dowere07d8092021-04-23 00:30:37 +01001863 if (!n || (n == 1 && filename[1] == L':')) {
1864 // Nothing left to query
Steve Dowerfe63a402021-04-22 20:45:02 +01001865 free((void *)filename);
1866 return FALSE;
1867 }
1868 }
1869 hFindFile = FindFirstFileW(filename, &FileData);
1870 if (pszFile != filename) {
1871 free((void *)filename);
1872 }
1873 if (hFindFile == INVALID_HANDLE_VALUE) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001874 return FALSE;
Steve Dowerfe63a402021-04-22 20:45:02 +01001875 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001876 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001877 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001878 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001879}
1880
Brian Curtind25aef52011-06-13 15:16:04 -05001881static int
Steve Dowercc16be82016-09-08 10:35:16 -07001882win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001883 BOOL traverse)
1884{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001885 HANDLE hFile;
1886 BY_HANDLE_FILE_INFORMATION fileInfo;
1887 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1888 DWORD fileType, error;
1889 BOOL isUnhandledTag = FALSE;
1890 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001891
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001892 DWORD access = FILE_READ_ATTRIBUTES;
1893 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1894 if (!traverse) {
1895 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1896 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001897
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001898 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001899 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001900 /* Either the path doesn't exist, or the caller lacks access. */
1901 error = GetLastError();
1902 switch (error) {
1903 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1904 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1905 /* Try reading the parent directory. */
1906 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1907 /* Cannot read the parent directory. */
1908 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001909 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001910 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001911 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1912 if (traverse ||
1913 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1914 /* The stat call has to traverse but cannot, so fail. */
1915 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001916 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001917 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001918 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001919 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001920
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001921 case ERROR_INVALID_PARAMETER:
1922 /* \\.\con requires read or write access. */
1923 hFile = CreateFileW(path, access | GENERIC_READ,
1924 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1925 OPEN_EXISTING, flags, NULL);
1926 if (hFile == INVALID_HANDLE_VALUE) {
1927 SetLastError(error);
1928 return -1;
1929 }
1930 break;
1931
1932 case ERROR_CANT_ACCESS_FILE:
1933 /* bpo37834: open unhandled reparse points if traverse fails. */
1934 if (traverse) {
1935 traverse = FALSE;
1936 isUnhandledTag = TRUE;
1937 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1938 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1939 }
1940 if (hFile == INVALID_HANDLE_VALUE) {
1941 SetLastError(error);
1942 return -1;
1943 }
1944 break;
1945
1946 default:
1947 return -1;
1948 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001949 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001950
1951 if (hFile != INVALID_HANDLE_VALUE) {
1952 /* Handle types other than files on disk. */
1953 fileType = GetFileType(hFile);
1954 if (fileType != FILE_TYPE_DISK) {
1955 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1956 retval = -1;
1957 goto cleanup;
1958 }
1959 DWORD fileAttributes = GetFileAttributesW(path);
1960 memset(result, 0, sizeof(*result));
1961 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1962 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1963 /* \\.\pipe\ or \\.\mailslot\ */
1964 result->st_mode = _S_IFDIR;
1965 } else if (fileType == FILE_TYPE_CHAR) {
1966 /* \\.\nul */
1967 result->st_mode = _S_IFCHR;
1968 } else if (fileType == FILE_TYPE_PIPE) {
1969 /* \\.\pipe\spam */
1970 result->st_mode = _S_IFIFO;
1971 }
1972 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1973 goto cleanup;
1974 }
1975
1976 /* Query the reparse tag, and traverse a non-link. */
1977 if (!traverse) {
1978 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1979 &tagInfo, sizeof(tagInfo))) {
1980 /* Allow devices that do not support FileAttributeTagInfo. */
1981 switch (GetLastError()) {
1982 case ERROR_INVALID_PARAMETER:
1983 case ERROR_INVALID_FUNCTION:
1984 case ERROR_NOT_SUPPORTED:
1985 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1986 tagInfo.ReparseTag = 0;
1987 break;
1988 default:
1989 retval = -1;
1990 goto cleanup;
1991 }
1992 } else if (tagInfo.FileAttributes &
1993 FILE_ATTRIBUTE_REPARSE_POINT) {
1994 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1995 if (isUnhandledTag) {
1996 /* Traversing previously failed for either this link
1997 or its target. */
1998 SetLastError(ERROR_CANT_ACCESS_FILE);
1999 retval = -1;
2000 goto cleanup;
2001 }
2002 /* Traverse a non-link, but not if traversing already failed
2003 for an unhandled tag. */
2004 } else if (!isUnhandledTag) {
2005 CloseHandle(hFile);
2006 return win32_xstat_impl(path, result, TRUE);
2007 }
2008 }
2009 }
2010
2011 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
2012 switch (GetLastError()) {
2013 case ERROR_INVALID_PARAMETER:
2014 case ERROR_INVALID_FUNCTION:
2015 case ERROR_NOT_SUPPORTED:
Steve Dower772ec0f2019-09-04 14:42:54 -07002016 /* Volumes and physical disks are block devices, e.g.
2017 \\.\C: and \\.\PhysicalDrive0. */
2018 memset(result, 0, sizeof(*result));
2019 result->st_mode = 0x6000; /* S_IFBLK */
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002020 goto cleanup;
2021 }
Steve Dower772ec0f2019-09-04 14:42:54 -07002022 retval = -1;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002023 goto cleanup;
2024 }
2025 }
2026
2027 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
2028
2029 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
2030 /* Fix the file execute permissions. This hack sets S_IEXEC if
2031 the filename has an extension that is commonly used by files
2032 that CreateProcessW can execute. A real implementation calls
2033 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
2034 AccessCheck to check for generic read, write, and execute
2035 access. */
2036 const wchar_t *fileExtension = wcsrchr(path, '.');
2037 if (fileExtension) {
2038 if (_wcsicmp(fileExtension, L".exe") == 0 ||
2039 _wcsicmp(fileExtension, L".bat") == 0 ||
2040 _wcsicmp(fileExtension, L".cmd") == 0 ||
2041 _wcsicmp(fileExtension, L".com") == 0) {
2042 result->st_mode |= 0111;
2043 }
2044 }
2045 }
2046
2047cleanup:
2048 if (hFile != INVALID_HANDLE_VALUE) {
Steve Dower772ec0f2019-09-04 14:42:54 -07002049 /* Preserve last error if we are failing */
2050 error = retval ? GetLastError() : 0;
2051 if (!CloseHandle(hFile)) {
2052 retval = -1;
2053 } else if (retval) {
2054 /* Restore last error */
2055 SetLastError(error);
2056 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002057 }
2058
2059 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00002060}
2061
2062static int
Steve Dowercc16be82016-09-08 10:35:16 -07002063win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00002064{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002065 /* Protocol violation: we explicitly clear errno, instead of
2066 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05002067 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002068 errno = 0;
2069 return code;
2070}
Brian Curtind25aef52011-06-13 15:16:04 -05002071/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00002072
2073 In Posix, stat automatically traverses symlinks and returns the stat
2074 structure for the target. In Windows, the equivalent GetFileAttributes by
2075 default does not traverse symlinks and instead returns attributes for
2076 the symlink.
2077
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002078 Instead, we will open the file (which *does* traverse symlinks by default)
2079 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00002080
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002081static int
Steve Dowercc16be82016-09-08 10:35:16 -07002082win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00002083{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002084 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00002085}
2086
Victor Stinner8c62be82010-05-06 00:08:46 +00002087static int
Steve Dowercc16be82016-09-08 10:35:16 -07002088win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00002089{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002090 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00002091}
2092
Martin v. Löwis14694662006-02-03 12:54:16 +00002093#endif /* MS_WINDOWS */
2094
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002095PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002096"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002097This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002098 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002099or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
2100\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002101Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
2102or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002103\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002104See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002105
2106static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002107 {"st_mode", "protection bits"},
2108 {"st_ino", "inode"},
2109 {"st_dev", "device"},
2110 {"st_nlink", "number of hard links"},
2111 {"st_uid", "user ID of owner"},
2112 {"st_gid", "group ID of owner"},
2113 {"st_size", "total size, in bytes"},
2114 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
2115 {NULL, "integer time of last access"},
2116 {NULL, "integer time of last modification"},
2117 {NULL, "integer time of last change"},
2118 {"st_atime", "time of last access"},
2119 {"st_mtime", "time of last modification"},
2120 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07002121 {"st_atime_ns", "time of last access in nanoseconds"},
2122 {"st_mtime_ns", "time of last modification in nanoseconds"},
2123 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002124#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002125 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002126#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002127#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002128 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002129#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002130#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002131 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002132#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002133#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002134 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002135#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002136#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002137 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002138#endif
2139#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002141#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002142#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2143 {"st_file_attributes", "Windows file attribute bits"},
2144#endif
jcea6c51d512018-01-28 14:00:08 +01002145#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2146 {"st_fstype", "Type of filesystem"},
2147#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002148#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2149 {"st_reparse_tag", "Windows reparse tag"},
2150#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002151 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002152};
2153
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002154#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002155#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002156#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002157#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002158#endif
2159
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002160#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002161#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2162#else
2163#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2164#endif
2165
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002166#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002167#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2168#else
2169#define ST_RDEV_IDX ST_BLOCKS_IDX
2170#endif
2171
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002172#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2173#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2174#else
2175#define ST_FLAGS_IDX ST_RDEV_IDX
2176#endif
2177
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002178#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002179#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002180#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002181#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002182#endif
2183
2184#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2185#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2186#else
2187#define ST_BIRTHTIME_IDX ST_GEN_IDX
2188#endif
2189
Zachary Ware63f277b2014-06-19 09:46:37 -05002190#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2191#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
2192#else
2193#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2194#endif
2195
jcea6c51d512018-01-28 14:00:08 +01002196#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2197#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2198#else
2199#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2200#endif
2201
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002202#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2203#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2204#else
2205#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2206#endif
2207
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002208static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002209 "stat_result", /* name */
2210 stat_result__doc__, /* doc */
2211 stat_result_fields,
2212 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002213};
2214
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002215PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002216"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2217This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002218 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002219or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002220\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002221See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002222
2223static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002224 {"f_bsize", },
2225 {"f_frsize", },
2226 {"f_blocks", },
2227 {"f_bfree", },
2228 {"f_bavail", },
2229 {"f_files", },
2230 {"f_ffree", },
2231 {"f_favail", },
2232 {"f_flag", },
2233 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002234 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002235 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002236};
2237
2238static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002239 "statvfs_result", /* name */
2240 statvfs_result__doc__, /* doc */
2241 statvfs_result_fields,
2242 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002243};
2244
Ross Lagerwall7807c352011-03-17 20:20:30 +02002245#if defined(HAVE_WAITID) && !defined(__APPLE__)
2246PyDoc_STRVAR(waitid_result__doc__,
2247"waitid_result: Result from waitid.\n\n\
2248This object may be accessed either as a tuple of\n\
2249 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2250or via the attributes si_pid, si_uid, and so on.\n\
2251\n\
2252See os.waitid for more information.");
2253
2254static PyStructSequence_Field waitid_result_fields[] = {
2255 {"si_pid", },
2256 {"si_uid", },
2257 {"si_signo", },
2258 {"si_status", },
2259 {"si_code", },
2260 {0}
2261};
2262
2263static PyStructSequence_Desc waitid_result_desc = {
2264 "waitid_result", /* name */
2265 waitid_result__doc__, /* doc */
2266 waitid_result_fields,
2267 5
2268};
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002269#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002270static newfunc structseq_new;
2271
2272static PyObject *
2273statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2274{
Victor Stinner8c62be82010-05-06 00:08:46 +00002275 PyStructSequence *result;
2276 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002277
Victor Stinner8c62be82010-05-06 00:08:46 +00002278 result = (PyStructSequence*)structseq_new(type, args, kwds);
2279 if (!result)
2280 return NULL;
2281 /* If we have been initialized from a tuple,
2282 st_?time might be set to None. Initialize it
2283 from the int slots. */
2284 for (i = 7; i <= 9; i++) {
2285 if (result->ob_item[i+3] == Py_None) {
2286 Py_DECREF(Py_None);
2287 Py_INCREF(result->ob_item[i]);
2288 result->ob_item[i+3] = result->ob_item[i];
2289 }
2290 }
2291 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002292}
2293
Eddie Elizondob3966632019-11-05 07:16:14 -08002294static int
2295_posix_clear(PyObject *module)
2296{
Victor Stinner97f33c32020-05-14 18:05:58 +02002297 _posixstate *state = get_posix_state(module);
2298 Py_CLEAR(state->billion);
2299 Py_CLEAR(state->DirEntryType);
2300 Py_CLEAR(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002301#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002302 Py_CLEAR(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002303#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002304 Py_CLEAR(state->StatResultType);
2305 Py_CLEAR(state->StatVFSResultType);
2306 Py_CLEAR(state->TerminalSizeType);
2307 Py_CLEAR(state->TimesResultType);
2308 Py_CLEAR(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002309#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002310 Py_CLEAR(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002311#endif
2312#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002313 Py_CLEAR(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002314#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002315 Py_CLEAR(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002316 return 0;
2317}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002318
Eddie Elizondob3966632019-11-05 07:16:14 -08002319static int
2320_posix_traverse(PyObject *module, visitproc visit, void *arg)
2321{
Victor Stinner97f33c32020-05-14 18:05:58 +02002322 _posixstate *state = get_posix_state(module);
2323 Py_VISIT(state->billion);
2324 Py_VISIT(state->DirEntryType);
2325 Py_VISIT(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002326#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002327 Py_VISIT(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002328#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002329 Py_VISIT(state->StatResultType);
2330 Py_VISIT(state->StatVFSResultType);
2331 Py_VISIT(state->TerminalSizeType);
2332 Py_VISIT(state->TimesResultType);
2333 Py_VISIT(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002334#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002335 Py_VISIT(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002336#endif
2337#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002338 Py_VISIT(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002339#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002340 Py_VISIT(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002341 return 0;
2342}
2343
2344static void
2345_posix_free(void *module)
2346{
2347 _posix_clear((PyObject *)module);
2348}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002349
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002350static void
Victor Stinner1c2fa782020-05-10 11:05:29 +02002351fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002352{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002353 PyObject *s = _PyLong_FromTime_t(sec);
2354 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2355 PyObject *s_in_ns = NULL;
2356 PyObject *ns_total = NULL;
2357 PyObject *float_s = NULL;
2358
2359 if (!(s && ns_fractional))
2360 goto exit;
2361
Victor Stinner1c2fa782020-05-10 11:05:29 +02002362 s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002363 if (!s_in_ns)
2364 goto exit;
2365
2366 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2367 if (!ns_total)
2368 goto exit;
2369
Victor Stinner01b5aab2017-10-24 02:02:00 -07002370 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2371 if (!float_s) {
2372 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002373 }
2374
2375 PyStructSequence_SET_ITEM(v, index, s);
2376 PyStructSequence_SET_ITEM(v, index+3, float_s);
2377 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2378 s = NULL;
2379 float_s = NULL;
2380 ns_total = NULL;
2381exit:
2382 Py_XDECREF(s);
2383 Py_XDECREF(ns_fractional);
2384 Py_XDECREF(s_in_ns);
2385 Py_XDECREF(ns_total);
2386 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002387}
2388
Tim Peters5aa91602002-01-30 05:46:57 +00002389/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002390 (used by posix_stat() and posix_fstat()) */
2391static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +02002392_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002393{
Victor Stinner8c62be82010-05-06 00:08:46 +00002394 unsigned long ansec, mnsec, cnsec;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002395 PyObject *StatResultType = get_posix_state(module)->StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08002396 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002397 if (v == NULL)
2398 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002399
Victor Stinner8c62be82010-05-06 00:08:46 +00002400 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002401 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002402 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002403#ifdef MS_WINDOWS
2404 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002405#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002406 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002407#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002408 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002409#if defined(MS_WINDOWS)
2410 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2411 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2412#else
2413 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2414 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2415#endif
xdegaye50e86032017-05-22 11:15:08 +02002416 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2417 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002418
Martin v. Löwis14694662006-02-03 12:54:16 +00002419#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002420 ansec = st->st_atim.tv_nsec;
2421 mnsec = st->st_mtim.tv_nsec;
2422 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002423#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002424 ansec = st->st_atimespec.tv_nsec;
2425 mnsec = st->st_mtimespec.tv_nsec;
2426 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002427#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002428 ansec = st->st_atime_nsec;
2429 mnsec = st->st_mtime_nsec;
2430 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002431#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002432 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002433#endif
Victor Stinner1c2fa782020-05-10 11:05:29 +02002434 fill_time(module, v, 7, st->st_atime, ansec);
2435 fill_time(module, v, 8, st->st_mtime, mnsec);
2436 fill_time(module, v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002437
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002438#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002439 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2440 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002441#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002442#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002443 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2444 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002445#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002446#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002447 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2448 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002449#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002450#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002451 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2452 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002453#endif
2454#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002455 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002456 PyObject *val;
2457 unsigned long bsec,bnsec;
2458 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002459#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002460 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002461#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002462 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002463#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002464 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002465 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2466 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002467 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002468#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002469#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002470 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2471 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002472#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002473#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2474 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2475 PyLong_FromUnsignedLong(st->st_file_attributes));
2476#endif
jcea6c51d512018-01-28 14:00:08 +01002477#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2478 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2479 PyUnicode_FromString(st->st_fstype));
2480#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002481#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2482 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2483 PyLong_FromUnsignedLong(st->st_reparse_tag));
2484#endif
Fred Drake699f3522000-06-29 21:12:41 +00002485
Victor Stinner8c62be82010-05-06 00:08:46 +00002486 if (PyErr_Occurred()) {
2487 Py_DECREF(v);
2488 return NULL;
2489 }
Fred Drake699f3522000-06-29 21:12:41 +00002490
Victor Stinner8c62be82010-05-06 00:08:46 +00002491 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002492}
2493
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002494/* POSIX methods */
2495
Guido van Rossum94f6f721999-01-06 18:42:14 +00002496
2497static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02002498posix_do_stat(PyObject *module, const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002499 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002500{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002501 STRUCT_STAT st;
2502 int result;
2503
Ronald Oussoren41761932020-11-08 10:05:27 +01002504#ifdef HAVE_FSTATAT
2505 int fstatat_unavailable = 0;
2506#endif
2507
Larry Hastings9cf065c2012-06-22 16:30:09 -07002508#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2509 if (follow_symlinks_specified(function_name, follow_symlinks))
2510 return NULL;
2511#endif
2512
2513 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2514 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2515 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2516 return NULL;
2517
2518 Py_BEGIN_ALLOW_THREADS
2519 if (path->fd != -1)
2520 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002521#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002522 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002523 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002524 else
Steve Dowercc16be82016-09-08 10:35:16 -07002525 result = win32_lstat(path->wide, &st);
2526#else
2527 else
2528#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002529 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2530 result = LSTAT(path->narrow, &st);
2531 else
Steve Dowercc16be82016-09-08 10:35:16 -07002532#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002533#ifdef HAVE_FSTATAT
Ronald Oussoren41761932020-11-08 10:05:27 +01002534 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2535 if (HAVE_FSTATAT_RUNTIME) {
2536 result = fstatat(dir_fd, path->narrow, &st,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002537 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +01002538
2539 } else {
2540 fstatat_unavailable = 1;
2541 }
2542 } else
Steve Dowercc16be82016-09-08 10:35:16 -07002543#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002544 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002545#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002546 Py_END_ALLOW_THREADS
2547
Ronald Oussoren41761932020-11-08 10:05:27 +01002548#ifdef HAVE_FSTATAT
2549 if (fstatat_unavailable) {
2550 argument_unavailable_error("stat", "dir_fd");
2551 return NULL;
2552 }
2553#endif
2554
Victor Stinner292c8352012-10-30 02:17:38 +01002555 if (result != 0) {
2556 return path_error(path);
2557 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002558
Victor Stinner1c2fa782020-05-10 11:05:29 +02002559 return _pystat_fromstructstat(module, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002560}
2561
Larry Hastings2f936352014-08-05 14:04:04 +10002562/*[python input]
2563
2564for s in """
2565
2566FACCESSAT
2567FCHMODAT
2568FCHOWNAT
2569FSTATAT
2570LINKAT
2571MKDIRAT
2572MKFIFOAT
2573MKNODAT
2574OPENAT
2575READLINKAT
2576SYMLINKAT
2577UNLINKAT
2578
2579""".strip().split():
2580 s = s.strip()
2581 print("""
2582#ifdef HAVE_{s}
2583 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002584#else
Larry Hastings2f936352014-08-05 14:04:04 +10002585 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002586#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002587""".rstrip().format(s=s))
2588
2589for s in """
2590
2591FCHDIR
2592FCHMOD
2593FCHOWN
2594FDOPENDIR
2595FEXECVE
2596FPATHCONF
2597FSTATVFS
2598FTRUNCATE
2599
2600""".strip().split():
2601 s = s.strip()
2602 print("""
2603#ifdef HAVE_{s}
2604 #define PATH_HAVE_{s} 1
2605#else
2606 #define PATH_HAVE_{s} 0
2607#endif
2608
2609""".rstrip().format(s=s))
2610[python start generated code]*/
2611
2612#ifdef HAVE_FACCESSAT
2613 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2614#else
2615 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2616#endif
2617
2618#ifdef HAVE_FCHMODAT
2619 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2620#else
2621 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2622#endif
2623
2624#ifdef HAVE_FCHOWNAT
2625 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2626#else
2627 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2628#endif
2629
2630#ifdef HAVE_FSTATAT
2631 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2632#else
2633 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2634#endif
2635
2636#ifdef HAVE_LINKAT
2637 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2638#else
2639 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2640#endif
2641
2642#ifdef HAVE_MKDIRAT
2643 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2644#else
2645 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2646#endif
2647
2648#ifdef HAVE_MKFIFOAT
2649 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2650#else
2651 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2652#endif
2653
2654#ifdef HAVE_MKNODAT
2655 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2656#else
2657 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2658#endif
2659
2660#ifdef HAVE_OPENAT
2661 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2662#else
2663 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2664#endif
2665
2666#ifdef HAVE_READLINKAT
2667 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2668#else
2669 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2670#endif
2671
2672#ifdef HAVE_SYMLINKAT
2673 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2674#else
2675 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2676#endif
2677
2678#ifdef HAVE_UNLINKAT
2679 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2680#else
2681 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2682#endif
2683
2684#ifdef HAVE_FCHDIR
2685 #define PATH_HAVE_FCHDIR 1
2686#else
2687 #define PATH_HAVE_FCHDIR 0
2688#endif
2689
2690#ifdef HAVE_FCHMOD
2691 #define PATH_HAVE_FCHMOD 1
2692#else
2693 #define PATH_HAVE_FCHMOD 0
2694#endif
2695
2696#ifdef HAVE_FCHOWN
2697 #define PATH_HAVE_FCHOWN 1
2698#else
2699 #define PATH_HAVE_FCHOWN 0
2700#endif
2701
2702#ifdef HAVE_FDOPENDIR
2703 #define PATH_HAVE_FDOPENDIR 1
2704#else
2705 #define PATH_HAVE_FDOPENDIR 0
2706#endif
2707
2708#ifdef HAVE_FEXECVE
2709 #define PATH_HAVE_FEXECVE 1
2710#else
2711 #define PATH_HAVE_FEXECVE 0
2712#endif
2713
2714#ifdef HAVE_FPATHCONF
2715 #define PATH_HAVE_FPATHCONF 1
2716#else
2717 #define PATH_HAVE_FPATHCONF 0
2718#endif
2719
2720#ifdef HAVE_FSTATVFS
2721 #define PATH_HAVE_FSTATVFS 1
2722#else
2723 #define PATH_HAVE_FSTATVFS 0
2724#endif
2725
2726#ifdef HAVE_FTRUNCATE
2727 #define PATH_HAVE_FTRUNCATE 1
2728#else
2729 #define PATH_HAVE_FTRUNCATE 0
2730#endif
2731/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002732
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002733#ifdef MS_WINDOWS
2734 #undef PATH_HAVE_FTRUNCATE
2735 #define PATH_HAVE_FTRUNCATE 1
2736#endif
Larry Hastings31826802013-10-19 00:09:25 -07002737
Larry Hastings61272b72014-01-07 12:41:53 -08002738/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002739
2740class path_t_converter(CConverter):
2741
2742 type = "path_t"
2743 impl_by_reference = True
2744 parse_by_reference = True
2745
2746 converter = 'path_converter'
2747
2748 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002749 # right now path_t doesn't support default values.
2750 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002751 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002752 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002753
Larry Hastings2f936352014-08-05 14:04:04 +10002754 if self.c_default not in (None, 'Py_None'):
2755 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002756
2757 self.nullable = nullable
2758 self.allow_fd = allow_fd
2759
Larry Hastings7726ac92014-01-31 22:03:12 -08002760 def pre_render(self):
2761 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002762 if isinstance(value, str):
2763 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002764 return str(int(bool(value)))
2765
2766 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002767 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002768 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002769 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002770 strify(self.nullable),
2771 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002772 )
2773
2774 def cleanup(self):
2775 return "path_cleanup(&" + self.name + ");\n"
2776
2777
2778class dir_fd_converter(CConverter):
2779 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002780
Larry Hastings2f936352014-08-05 14:04:04 +10002781 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002782 if self.default in (unspecified, None):
2783 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002784 if isinstance(requires, str):
2785 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2786 else:
2787 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002788
Larry Hastings2f936352014-08-05 14:04:04 +10002789class uid_t_converter(CConverter):
2790 type = "uid_t"
2791 converter = '_Py_Uid_Converter'
2792
2793class gid_t_converter(CConverter):
2794 type = "gid_t"
2795 converter = '_Py_Gid_Converter'
2796
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002797class dev_t_converter(CConverter):
2798 type = 'dev_t'
2799 converter = '_Py_Dev_Converter'
2800
2801class dev_t_return_converter(unsigned_long_return_converter):
2802 type = 'dev_t'
2803 conversion_fn = '_PyLong_FromDev'
2804 unsigned_cast = '(dev_t)'
2805
Larry Hastings2f936352014-08-05 14:04:04 +10002806class FSConverter_converter(CConverter):
2807 type = 'PyObject *'
2808 converter = 'PyUnicode_FSConverter'
2809 def converter_init(self):
2810 if self.default is not unspecified:
2811 fail("FSConverter_converter does not support default values")
2812 self.c_default = 'NULL'
2813
2814 def cleanup(self):
2815 return "Py_XDECREF(" + self.name + ");\n"
2816
2817class pid_t_converter(CConverter):
2818 type = 'pid_t'
2819 format_unit = '" _Py_PARSE_PID "'
2820
2821class idtype_t_converter(int_converter):
2822 type = 'idtype_t'
2823
2824class id_t_converter(CConverter):
2825 type = 'id_t'
2826 format_unit = '" _Py_PARSE_PID "'
2827
Benjamin Petersonca470632016-09-06 13:47:26 -07002828class intptr_t_converter(CConverter):
2829 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002830 format_unit = '" _Py_PARSE_INTPTR "'
2831
2832class Py_off_t_converter(CConverter):
2833 type = 'Py_off_t'
2834 converter = 'Py_off_t_converter'
2835
2836class Py_off_t_return_converter(long_return_converter):
2837 type = 'Py_off_t'
2838 conversion_fn = 'PyLong_FromPy_off_t'
2839
2840class path_confname_converter(CConverter):
2841 type="int"
2842 converter="conv_path_confname"
2843
2844class confstr_confname_converter(path_confname_converter):
2845 converter='conv_confstr_confname'
2846
2847class sysconf_confname_converter(path_confname_converter):
2848 converter="conv_sysconf_confname"
2849
Larry Hastings61272b72014-01-07 12:41:53 -08002850[python start generated code]*/
Serhiy Storchaka9975cc52020-10-09 23:00:45 +03002851/*[python end generated code: output=da39a3ee5e6b4b0d input=3338733161aa7879]*/
Larry Hastings31826802013-10-19 00:09:25 -07002852
Larry Hastings61272b72014-01-07 12:41:53 -08002853/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002854
Larry Hastings2a727912014-01-16 11:32:01 -08002855os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002856
2857 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002858 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002859 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002860
2861 *
2862
Larry Hastings2f936352014-08-05 14:04:04 +10002863 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002864 If not None, it should be a file descriptor open to a directory,
2865 and path should be a relative string; path will then be relative to
2866 that directory.
2867
2868 follow_symlinks: bool = True
2869 If False, and the last element of the path is a symbolic link,
2870 stat will examine the symbolic link itself instead of the file
2871 the link points to.
2872
2873Perform a stat system call on the given path.
2874
2875dir_fd and follow_symlinks may not be implemented
2876 on your platform. If they are unavailable, using them will raise a
2877 NotImplementedError.
2878
2879It's an error to use dir_fd or follow_symlinks when specifying path as
2880 an open file descriptor.
2881
Larry Hastings61272b72014-01-07 12:41:53 -08002882[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002883
Larry Hastings31826802013-10-19 00:09:25 -07002884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002885os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002886/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002887{
Victor Stinner1c2fa782020-05-10 11:05:29 +02002888 return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002889}
2890
Larry Hastings2f936352014-08-05 14:04:04 +10002891
2892/*[clinic input]
2893os.lstat
2894
2895 path : path_t
2896
2897 *
2898
2899 dir_fd : dir_fd(requires='fstatat') = None
2900
2901Perform a stat system call on the given path, without following symbolic links.
2902
2903Like stat(), but do not follow symbolic links.
2904Equivalent to stat(path, follow_symlinks=False).
2905[clinic start generated code]*/
2906
Larry Hastings2f936352014-08-05 14:04:04 +10002907static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002908os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2909/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002910{
2911 int follow_symlinks = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002912 return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10002913}
Larry Hastings31826802013-10-19 00:09:25 -07002914
Larry Hastings2f936352014-08-05 14:04:04 +10002915
Larry Hastings61272b72014-01-07 12:41:53 -08002916/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002917os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002918
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002919 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002920 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002921
2922 mode: int
2923 Operating-system mode bitfield. Can be F_OK to test existence,
2924 or the inclusive-OR of R_OK, W_OK, and X_OK.
2925
2926 *
2927
Larry Hastings2f936352014-08-05 14:04:04 +10002928 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002929 If not None, it should be a file descriptor open to a directory,
2930 and path should be relative; path will then be relative to that
2931 directory.
2932
2933 effective_ids: bool = False
2934 If True, access will use the effective uid/gid instead of
2935 the real uid/gid.
2936
2937 follow_symlinks: bool = True
2938 If False, and the last element of the path is a symbolic link,
2939 access will examine the symbolic link itself instead of the file
2940 the link points to.
2941
2942Use the real uid/gid to test for access to a path.
2943
2944{parameters}
2945dir_fd, effective_ids, and follow_symlinks may not be implemented
2946 on your platform. If they are unavailable, using them will raise a
2947 NotImplementedError.
2948
2949Note that most operations will use the effective uid/gid, therefore this
2950 routine can be used in a suid/sgid environment to test if the invoking user
2951 has the specified access to the path.
2952
Larry Hastings61272b72014-01-07 12:41:53 -08002953[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002954
Larry Hastings2f936352014-08-05 14:04:04 +10002955static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002956os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002957 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002958/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002959{
Larry Hastings2f936352014-08-05 14:04:04 +10002960 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002961
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002962#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002963 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002964#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002965 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002966#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002967
Ronald Oussoren41761932020-11-08 10:05:27 +01002968#ifdef HAVE_FACCESSAT
2969 int faccessat_unavailable = 0;
2970#endif
2971
Larry Hastings9cf065c2012-06-22 16:30:09 -07002972#ifndef HAVE_FACCESSAT
2973 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002974 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002975
2976 if (effective_ids) {
2977 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002978 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002979 }
2980#endif
2981
2982#ifdef MS_WINDOWS
2983 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002984 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002985 Py_END_ALLOW_THREADS
2986
2987 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002988 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002989 * * we didn't get a -1, and
2990 * * write access wasn't requested,
2991 * * or the file isn't read-only,
2992 * * or it's a directory.
2993 * (Directories cannot be read-only on Windows.)
2994 */
Larry Hastings2f936352014-08-05 14:04:04 +10002995 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002996 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002997 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002998 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002999#else
3000
3001 Py_BEGIN_ALLOW_THREADS
3002#ifdef HAVE_FACCESSAT
3003 if ((dir_fd != DEFAULT_DIR_FD) ||
3004 effective_ids ||
3005 !follow_symlinks) {
Ronald Oussoren41761932020-11-08 10:05:27 +01003006
3007 if (HAVE_FACCESSAT_RUNTIME) {
3008 int flags = 0;
3009 if (!follow_symlinks)
3010 flags |= AT_SYMLINK_NOFOLLOW;
3011 if (effective_ids)
3012 flags |= AT_EACCESS;
3013 result = faccessat(dir_fd, path->narrow, mode, flags);
3014 } else {
3015 faccessat_unavailable = 1;
3016 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003017 }
3018 else
3019#endif
Larry Hastings31826802013-10-19 00:09:25 -07003020 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003021 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01003022
3023#ifdef HAVE_FACCESSAT
3024 if (faccessat_unavailable) {
3025 if (dir_fd != DEFAULT_DIR_FD) {
3026 argument_unavailable_error("access", "dir_fd");
3027 return -1;
3028 }
3029 if (follow_symlinks_specified("access", follow_symlinks))
3030 return -1;
3031
3032 if (effective_ids) {
3033 argument_unavailable_error("access", "effective_ids");
3034 return -1;
3035 }
3036 /* should be unreachable */
3037 return -1;
3038 }
3039#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003040 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003041#endif
3042
Larry Hastings9cf065c2012-06-22 16:30:09 -07003043 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003044}
3045
Guido van Rossumd371ff11999-01-25 16:12:23 +00003046#ifndef F_OK
3047#define F_OK 0
3048#endif
3049#ifndef R_OK
3050#define R_OK 4
3051#endif
3052#ifndef W_OK
3053#define W_OK 2
3054#endif
3055#ifndef X_OK
3056#define X_OK 1
3057#endif
3058
Larry Hastings31826802013-10-19 00:09:25 -07003059
Guido van Rossumd371ff11999-01-25 16:12:23 +00003060#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08003061/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003062os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07003063
3064 fd: int
3065 Integer file descriptor handle.
3066
3067 /
3068
3069Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08003070[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07003071
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003072static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003073os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003074/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07003075{
Guido van Rossum94f6f721999-01-06 18:42:14 +00003076
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02003077 long size = sysconf(_SC_TTY_NAME_MAX);
3078 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003079 return posix_error();
3080 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02003081 char *buffer = (char *)PyMem_RawMalloc(size);
3082 if (buffer == NULL) {
3083 return PyErr_NoMemory();
3084 }
3085 int ret = ttyname_r(fd, buffer, size);
3086 if (ret != 0) {
3087 PyMem_RawFree(buffer);
3088 errno = ret;
3089 return posix_error();
3090 }
3091 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
3092 PyMem_RawFree(buffer);
3093 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003094}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003095#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003096
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003097#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10003098/*[clinic input]
3099os.ctermid
3100
3101Return the name of the controlling terminal for this process.
3102[clinic start generated code]*/
3103
Larry Hastings2f936352014-08-05 14:04:04 +10003104static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003105os_ctermid_impl(PyObject *module)
3106/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003107{
Victor Stinner8c62be82010-05-06 00:08:46 +00003108 char *ret;
3109 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003110
Greg Wardb48bc172000-03-01 21:51:56 +00003111#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00003112 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003113#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003114 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003115#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003116 if (ret == NULL)
3117 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00003118 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003119}
Larry Hastings2f936352014-08-05 14:04:04 +10003120#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003121
Larry Hastings2f936352014-08-05 14:04:04 +10003122
3123/*[clinic input]
3124os.chdir
3125
3126 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
3127
3128Change the current working directory to the specified path.
3129
3130path may always be specified as a string.
3131On some platforms, path may also be specified as an open file descriptor.
3132 If this functionality is unavailable, using it raises an exception.
3133[clinic start generated code]*/
3134
Larry Hastings2f936352014-08-05 14:04:04 +10003135static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003136os_chdir_impl(PyObject *module, path_t *path)
3137/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003138{
3139 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003140
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003141 if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
3142 return NULL;
3143 }
3144
Larry Hastings9cf065c2012-06-22 16:30:09 -07003145 Py_BEGIN_ALLOW_THREADS
3146#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003147 /* on unix, success = 0, on windows, success = !0 */
3148 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003149#else
3150#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10003151 if (path->fd != -1)
3152 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003153 else
3154#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003155 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003156#endif
3157 Py_END_ALLOW_THREADS
3158
3159 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003160 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003161 }
3162
Larry Hastings2f936352014-08-05 14:04:04 +10003163 Py_RETURN_NONE;
3164}
3165
3166
3167#ifdef HAVE_FCHDIR
3168/*[clinic input]
3169os.fchdir
3170
3171 fd: fildes
3172
3173Change to the directory of the given file descriptor.
3174
3175fd must be opened on a directory, not a file.
3176Equivalent to os.chdir(fd).
3177
3178[clinic start generated code]*/
3179
Fred Drake4d1e64b2002-04-15 19:40:07 +00003180static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003181os_fchdir_impl(PyObject *module, int fd)
3182/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00003183{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003184 if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
3185 return NULL;
3186 }
Larry Hastings2f936352014-08-05 14:04:04 +10003187 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00003188}
3189#endif /* HAVE_FCHDIR */
3190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003191
Larry Hastings2f936352014-08-05 14:04:04 +10003192/*[clinic input]
3193os.chmod
3194
3195 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00003196 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10003197 On some platforms, path may also be specified as an open file descriptor.
3198 If this functionality is unavailable, using it raises an exception.
3199
3200 mode: int
3201 Operating-system mode bitfield.
3202
3203 *
3204
3205 dir_fd : dir_fd(requires='fchmodat') = None
3206 If not None, it should be a file descriptor open to a directory,
3207 and path should be relative; path will then be relative to that
3208 directory.
3209
3210 follow_symlinks: bool = True
3211 If False, and the last element of the path is a symbolic link,
3212 chmod will modify the symbolic link itself instead of the file
3213 the link points to.
3214
3215Change the access permissions of a file.
3216
3217It is an error to use dir_fd or follow_symlinks when specifying path as
3218 an open file descriptor.
3219dir_fd and follow_symlinks may not be implemented on your platform.
3220 If they are unavailable, using them will raise a NotImplementedError.
3221
3222[clinic start generated code]*/
3223
Larry Hastings2f936352014-08-05 14:04:04 +10003224static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003225os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003226 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003227/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003228{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003229 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003230
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003231#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003233#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003234
Larry Hastings9cf065c2012-06-22 16:30:09 -07003235#ifdef HAVE_FCHMODAT
3236 int fchmodat_nofollow_unsupported = 0;
Ronald Oussoren41761932020-11-08 10:05:27 +01003237 int fchmodat_unsupported = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003238#endif
3239
Larry Hastings9cf065c2012-06-22 16:30:09 -07003240#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3241 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003242 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003243#endif
3244
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003245 if (PySys_Audit("os.chmod", "Oii", path->object, mode,
3246 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3247 return NULL;
3248 }
3249
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003251 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003252 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003253 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003254 result = 0;
3255 else {
3256 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 attr &= ~FILE_ATTRIBUTE_READONLY;
3258 else
3259 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003260 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003261 }
3262 Py_END_ALLOW_THREADS
3263
3264 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003265 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003266 }
3267#else /* MS_WINDOWS */
3268 Py_BEGIN_ALLOW_THREADS
3269#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003270 if (path->fd != -1)
3271 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003272 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003273#endif /* HAVE_CHMOD */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003274#ifdef HAVE_LCHMOD
3275 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003276 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003277 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003278#endif /* HAVE_LCHMOD */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003279#ifdef HAVE_FCHMODAT
3280 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
Ronald Oussoren41761932020-11-08 10:05:27 +01003281 if (HAVE_FCHMODAT_RUNTIME) {
3282 /*
3283 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3284 * The documentation specifically shows how to use it,
3285 * and then says it isn't implemented yet.
3286 * (true on linux with glibc 2.15, and openindiana 3.x)
3287 *
3288 * Once it is supported, os.chmod will automatically
3289 * support dir_fd and follow_symlinks=False. (Hopefully.)
3290 * Until then, we need to be careful what exception we raise.
3291 */
3292 result = fchmodat(dir_fd, path->narrow, mode,
3293 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3294 /*
3295 * But wait! We can't throw the exception without allowing threads,
3296 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3297 */
3298 fchmodat_nofollow_unsupported =
3299 result &&
3300 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3301 !follow_symlinks;
3302 } else {
3303 fchmodat_unsupported = 1;
3304 fchmodat_nofollow_unsupported = 1;
3305
3306 result = -1;
3307 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 }
3309 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003310#endif /* HAVE_FHCMODAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003311 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003312 Py_END_ALLOW_THREADS
3313
3314 if (result) {
3315#ifdef HAVE_FCHMODAT
Ronald Oussoren41761932020-11-08 10:05:27 +01003316 if (fchmodat_unsupported) {
3317 if (dir_fd != DEFAULT_DIR_FD) {
3318 argument_unavailable_error("chmod", "dir_fd");
3319 return NULL;
3320 }
3321 }
3322
Larry Hastings9cf065c2012-06-22 16:30:09 -07003323 if (fchmodat_nofollow_unsupported) {
3324 if (dir_fd != DEFAULT_DIR_FD)
3325 dir_fd_and_follow_symlinks_invalid("chmod",
3326 dir_fd, follow_symlinks);
3327 else
3328 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003329 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003330 }
3331 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003332#endif /* HAVE_FCHMODAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003333 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003334 }
Ronald Oussoren41761932020-11-08 10:05:27 +01003335#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003336
Larry Hastings2f936352014-08-05 14:04:04 +10003337 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003338}
3339
Larry Hastings9cf065c2012-06-22 16:30:09 -07003340
Christian Heimes4e30a842007-11-30 22:12:06 +00003341#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003342/*[clinic input]
3343os.fchmod
3344
3345 fd: int
3346 mode: int
3347
3348Change the access permissions of the file given by file descriptor fd.
3349
3350Equivalent to os.chmod(fd, mode).
3351[clinic start generated code]*/
3352
Larry Hastings2f936352014-08-05 14:04:04 +10003353static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003354os_fchmod_impl(PyObject *module, int fd, int mode)
3355/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003356{
3357 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003358 int async_err = 0;
3359
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003360 if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
3361 return NULL;
3362 }
3363
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003364 do {
3365 Py_BEGIN_ALLOW_THREADS
3366 res = fchmod(fd, mode);
3367 Py_END_ALLOW_THREADS
3368 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3369 if (res != 0)
3370 return (!async_err) ? posix_error() : NULL;
3371
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003373}
3374#endif /* HAVE_FCHMOD */
3375
Larry Hastings2f936352014-08-05 14:04:04 +10003376
Christian Heimes4e30a842007-11-30 22:12:06 +00003377#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003378/*[clinic input]
3379os.lchmod
3380
3381 path: path_t
3382 mode: int
3383
3384Change the access permissions of a file, without following symbolic links.
3385
3386If path is a symlink, this affects the link itself rather than the target.
3387Equivalent to chmod(path, mode, follow_symlinks=False)."
3388[clinic start generated code]*/
3389
Larry Hastings2f936352014-08-05 14:04:04 +10003390static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003391os_lchmod_impl(PyObject *module, path_t *path, int mode)
3392/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003393{
Victor Stinner8c62be82010-05-06 00:08:46 +00003394 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003395 if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3396 return NULL;
3397 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003398 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003399 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003400 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003401 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003402 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003403 return NULL;
3404 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003406}
3407#endif /* HAVE_LCHMOD */
3408
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003409
Thomas Wouterscf297e42007-02-23 15:07:44 +00003410#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003411/*[clinic input]
3412os.chflags
3413
3414 path: path_t
3415 flags: unsigned_long(bitwise=True)
3416 follow_symlinks: bool=True
3417
3418Set file flags.
3419
3420If follow_symlinks is False, and the last element of the path is a symbolic
3421 link, chflags will change flags on the symbolic link itself instead of the
3422 file the link points to.
3423follow_symlinks may not be implemented on your platform. If it is
3424unavailable, using it will raise a NotImplementedError.
3425
3426[clinic start generated code]*/
3427
Larry Hastings2f936352014-08-05 14:04:04 +10003428static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003429os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003430 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003431/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003432{
3433 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434
3435#ifndef HAVE_LCHFLAGS
3436 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003437 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438#endif
3439
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003440 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3441 return NULL;
3442 }
3443
Victor Stinner8c62be82010-05-06 00:08:46 +00003444 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003445#ifdef HAVE_LCHFLAGS
3446 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003447 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003448 else
3449#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003450 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003451 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452
Larry Hastings2f936352014-08-05 14:04:04 +10003453 if (result)
3454 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455
Larry Hastings2f936352014-08-05 14:04:04 +10003456 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003457}
3458#endif /* HAVE_CHFLAGS */
3459
Larry Hastings2f936352014-08-05 14:04:04 +10003460
Thomas Wouterscf297e42007-02-23 15:07:44 +00003461#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003462/*[clinic input]
3463os.lchflags
3464
3465 path: path_t
3466 flags: unsigned_long(bitwise=True)
3467
3468Set file flags.
3469
3470This function will not follow symbolic links.
3471Equivalent to chflags(path, flags, follow_symlinks=False).
3472[clinic start generated code]*/
3473
Larry Hastings2f936352014-08-05 14:04:04 +10003474static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003475os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3476/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003477{
Victor Stinner8c62be82010-05-06 00:08:46 +00003478 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003479 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3480 return NULL;
3481 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003482 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003483 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003484 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003485 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003486 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003487 }
Victor Stinner292c8352012-10-30 02:17:38 +01003488 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003489}
3490#endif /* HAVE_LCHFLAGS */
3491
Larry Hastings2f936352014-08-05 14:04:04 +10003492
Martin v. Löwis244edc82001-10-04 22:44:26 +00003493#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003494/*[clinic input]
3495os.chroot
3496 path: path_t
3497
3498Change root directory to path.
3499
3500[clinic start generated code]*/
3501
Larry Hastings2f936352014-08-05 14:04:04 +10003502static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003503os_chroot_impl(PyObject *module, path_t *path)
3504/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003505{
3506 int res;
3507 Py_BEGIN_ALLOW_THREADS
3508 res = chroot(path->narrow);
3509 Py_END_ALLOW_THREADS
3510 if (res < 0)
3511 return path_error(path);
3512 Py_RETURN_NONE;
3513}
3514#endif /* HAVE_CHROOT */
3515
Martin v. Löwis244edc82001-10-04 22:44:26 +00003516
Guido van Rossum21142a01999-01-08 21:05:37 +00003517#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003518/*[clinic input]
3519os.fsync
3520
3521 fd: fildes
3522
3523Force write of fd to disk.
3524[clinic start generated code]*/
3525
Larry Hastings2f936352014-08-05 14:04:04 +10003526static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003527os_fsync_impl(PyObject *module, int fd)
3528/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003529{
3530 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003531}
3532#endif /* HAVE_FSYNC */
3533
Larry Hastings2f936352014-08-05 14:04:04 +10003534
Ross Lagerwall7807c352011-03-17 20:20:30 +02003535#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003536/*[clinic input]
3537os.sync
3538
3539Force write of everything to disk.
3540[clinic start generated code]*/
3541
Larry Hastings2f936352014-08-05 14:04:04 +10003542static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003543os_sync_impl(PyObject *module)
3544/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003545{
3546 Py_BEGIN_ALLOW_THREADS
3547 sync();
3548 Py_END_ALLOW_THREADS
3549 Py_RETURN_NONE;
3550}
Larry Hastings2f936352014-08-05 14:04:04 +10003551#endif /* HAVE_SYNC */
3552
Ross Lagerwall7807c352011-03-17 20:20:30 +02003553
Guido van Rossum21142a01999-01-08 21:05:37 +00003554#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003555#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003556extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3557#endif
3558
Larry Hastings2f936352014-08-05 14:04:04 +10003559/*[clinic input]
3560os.fdatasync
3561
3562 fd: fildes
3563
3564Force write of fd to disk without forcing update of metadata.
3565[clinic start generated code]*/
3566
Larry Hastings2f936352014-08-05 14:04:04 +10003567static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003568os_fdatasync_impl(PyObject *module, int fd)
3569/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003570{
3571 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003572}
3573#endif /* HAVE_FDATASYNC */
3574
3575
Fredrik Lundh10723342000-07-10 16:38:09 +00003576#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003577/*[clinic input]
3578os.chown
3579
3580 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003581 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003582
3583 uid: uid_t
3584
3585 gid: gid_t
3586
3587 *
3588
3589 dir_fd : dir_fd(requires='fchownat') = None
3590 If not None, it should be a file descriptor open to a directory,
3591 and path should be relative; path will then be relative to that
3592 directory.
3593
3594 follow_symlinks: bool = True
3595 If False, and the last element of the path is a symbolic link,
3596 stat will examine the symbolic link itself instead of the file
3597 the link points to.
3598
3599Change the owner and group id of path to the numeric uid and gid.\
3600
3601path may always be specified as a string.
3602On some platforms, path may also be specified as an open file descriptor.
3603 If this functionality is unavailable, using it raises an exception.
3604If dir_fd is not None, it should be a file descriptor open to a directory,
3605 and path should be relative; path will then be relative to that directory.
3606If follow_symlinks is False, and the last element of the path is a symbolic
3607 link, chown will modify the symbolic link itself instead of the file the
3608 link points to.
3609It is an error to use dir_fd or follow_symlinks when specifying path as
3610 an open file descriptor.
3611dir_fd and follow_symlinks may not be implemented on your platform.
3612 If they are unavailable, using them will raise a NotImplementedError.
3613
3614[clinic start generated code]*/
3615
Larry Hastings2f936352014-08-05 14:04:04 +10003616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003617os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003618 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003619/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003620{
3621 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003622
Ronald Oussoren41761932020-11-08 10:05:27 +01003623#if defined(HAVE_FCHOWNAT)
3624 int fchownat_unsupported = 0;
3625#endif
3626
Larry Hastings9cf065c2012-06-22 16:30:09 -07003627#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3628 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003629 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003630#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003631 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3632 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3633 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003635 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
3636 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3637 return NULL;
3638 }
3639
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003641#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003642 if (path->fd != -1)
3643 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003644 else
3645#endif
3646#ifdef HAVE_LCHOWN
3647 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003648 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003649 else
3650#endif
3651#ifdef HAVE_FCHOWNAT
Ronald Oussoren41761932020-11-08 10:05:27 +01003652 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
3653 if (HAVE_FCHOWNAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10003654 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003655 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +01003656 } else {
3657 fchownat_unsupported = 1;
3658 }
3659 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003660#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003661 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003662 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003663
Ronald Oussoren41761932020-11-08 10:05:27 +01003664#ifdef HAVE_FCHOWNAT
3665 if (fchownat_unsupported) {
3666 /* This would be incorrect if the current platform
3667 * doesn't support lchown.
3668 */
3669 argument_unavailable_error(NULL, "dir_fd");
3670 return NULL;
3671 }
3672#endif
3673
Larry Hastings2f936352014-08-05 14:04:04 +10003674 if (result)
3675 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003676
Larry Hastings2f936352014-08-05 14:04:04 +10003677 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003678}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003679#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003680
Larry Hastings2f936352014-08-05 14:04:04 +10003681
Christian Heimes4e30a842007-11-30 22:12:06 +00003682#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003683/*[clinic input]
3684os.fchown
3685
3686 fd: int
3687 uid: uid_t
3688 gid: gid_t
3689
3690Change the owner and group id of the file specified by file descriptor.
3691
3692Equivalent to os.chown(fd, uid, gid).
3693
3694[clinic start generated code]*/
3695
Larry Hastings2f936352014-08-05 14:04:04 +10003696static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003697os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3698/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003699{
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003701 int async_err = 0;
3702
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003703 if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
3704 return NULL;
3705 }
3706
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003707 do {
3708 Py_BEGIN_ALLOW_THREADS
3709 res = fchown(fd, uid, gid);
3710 Py_END_ALLOW_THREADS
3711 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3712 if (res != 0)
3713 return (!async_err) ? posix_error() : NULL;
3714
Victor Stinner8c62be82010-05-06 00:08:46 +00003715 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003716}
3717#endif /* HAVE_FCHOWN */
3718
Larry Hastings2f936352014-08-05 14:04:04 +10003719
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003720#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003721/*[clinic input]
3722os.lchown
3723
3724 path : path_t
3725 uid: uid_t
3726 gid: gid_t
3727
3728Change the owner and group id of path to the numeric uid and gid.
3729
3730This function will not follow symbolic links.
3731Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3732[clinic start generated code]*/
3733
Larry Hastings2f936352014-08-05 14:04:04 +10003734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003735os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3736/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003737{
Victor Stinner8c62be82010-05-06 00:08:46 +00003738 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003739 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
3740 return NULL;
3741 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003742 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003743 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003744 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003745 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003746 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003747 }
Larry Hastings2f936352014-08-05 14:04:04 +10003748 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003749}
3750#endif /* HAVE_LCHOWN */
3751
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003752
Barry Warsaw53699e91996-12-10 23:23:01 +00003753static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003754posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003755{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003756#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003757 wchar_t wbuf[MAXPATHLEN];
3758 wchar_t *wbuf2 = wbuf;
3759 DWORD len;
3760
3761 Py_BEGIN_ALLOW_THREADS
3762 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3763 /* If the buffer is large enough, len does not include the
3764 terminating \0. If the buffer is too small, len includes
3765 the space needed for the terminator. */
3766 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003767 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003768 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003769 }
Victor Stinner689830e2019-06-26 17:31:12 +02003770 else {
3771 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003772 }
Victor Stinner689830e2019-06-26 17:31:12 +02003773 if (wbuf2) {
3774 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003775 }
Victor Stinner689830e2019-06-26 17:31:12 +02003776 }
3777 Py_END_ALLOW_THREADS
3778
3779 if (!wbuf2) {
3780 PyErr_NoMemory();
3781 return NULL;
3782 }
3783 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003784 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003785 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003786 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003787 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003788
Victor Stinner689830e2019-06-26 17:31:12 +02003789 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3790 if (wbuf2 != wbuf) {
3791 PyMem_RawFree(wbuf2);
3792 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003793
Victor Stinner689830e2019-06-26 17:31:12 +02003794 if (use_bytes) {
3795 if (resobj == NULL) {
3796 return NULL;
3797 }
3798 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3799 }
3800
3801 return resobj;
3802#else
3803 const size_t chunk = 1024;
3804
3805 char *buf = NULL;
3806 char *cwd = NULL;
3807 size_t buflen = 0;
3808
Victor Stinner8c62be82010-05-06 00:08:46 +00003809 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003810 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003811 char *newbuf;
3812 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3813 buflen += chunk;
3814 newbuf = PyMem_RawRealloc(buf, buflen);
3815 }
3816 else {
3817 newbuf = NULL;
3818 }
3819 if (newbuf == NULL) {
3820 PyMem_RawFree(buf);
3821 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003822 break;
3823 }
Victor Stinner689830e2019-06-26 17:31:12 +02003824 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003825
Victor Stinner4403d7d2015-04-25 00:16:10 +02003826 cwd = getcwd(buf, buflen);
3827 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003828 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003829
Victor Stinner689830e2019-06-26 17:31:12 +02003830 if (buf == NULL) {
3831 return PyErr_NoMemory();
3832 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003833 if (cwd == NULL) {
3834 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003835 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003836 }
3837
Victor Stinner689830e2019-06-26 17:31:12 +02003838 PyObject *obj;
3839 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003840 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003841 }
3842 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003843 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003844 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003845 PyMem_RawFree(buf);
3846
3847 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003848#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003849}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003850
Larry Hastings2f936352014-08-05 14:04:04 +10003851
3852/*[clinic input]
3853os.getcwd
3854
3855Return a unicode string representing the current working directory.
3856[clinic start generated code]*/
3857
Larry Hastings2f936352014-08-05 14:04:04 +10003858static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003859os_getcwd_impl(PyObject *module)
3860/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003861{
3862 return posix_getcwd(0);
3863}
3864
Larry Hastings2f936352014-08-05 14:04:04 +10003865
3866/*[clinic input]
3867os.getcwdb
3868
3869Return a bytes string representing the current working directory.
3870[clinic start generated code]*/
3871
Larry Hastings2f936352014-08-05 14:04:04 +10003872static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003873os_getcwdb_impl(PyObject *module)
3874/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003875{
3876 return posix_getcwd(1);
3877}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003878
Larry Hastings2f936352014-08-05 14:04:04 +10003879
Larry Hastings9cf065c2012-06-22 16:30:09 -07003880#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3881#define HAVE_LINK 1
3882#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003883
Guido van Rossumb6775db1994-08-01 11:34:53 +00003884#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003885/*[clinic input]
3886
3887os.link
3888
3889 src : path_t
3890 dst : path_t
3891 *
3892 src_dir_fd : dir_fd = None
3893 dst_dir_fd : dir_fd = None
3894 follow_symlinks: bool = True
3895
3896Create a hard link to a file.
3897
3898If either src_dir_fd or dst_dir_fd is not None, it should be a file
3899 descriptor open to a directory, and the respective path string (src or dst)
3900 should be relative; the path will then be relative to that directory.
3901If follow_symlinks is False, and the last element of src is a symbolic
3902 link, link will create a link to the symbolic link itself instead of the
3903 file the link points to.
3904src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3905 platform. If they are unavailable, using them will raise a
3906 NotImplementedError.
3907[clinic start generated code]*/
3908
Larry Hastings2f936352014-08-05 14:04:04 +10003909static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003910os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003911 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003912/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003913{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003914#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003915 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003916#else
3917 int result;
3918#endif
Ronald Oussoren41761932020-11-08 10:05:27 +01003919#if defined(HAVE_LINKAT)
3920 int linkat_unavailable = 0;
3921#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003922
Larry Hastings9cf065c2012-06-22 16:30:09 -07003923#ifndef HAVE_LINKAT
3924 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3925 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003926 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003927 }
3928#endif
3929
Steve Dowercc16be82016-09-08 10:35:16 -07003930#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003931 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003932 PyErr_SetString(PyExc_NotImplementedError,
3933 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003934 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003935 }
Steve Dowercc16be82016-09-08 10:35:16 -07003936#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003937
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003938 if (PySys_Audit("os.link", "OOii", src->object, dst->object,
3939 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
3940 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
3941 return NULL;
3942 }
3943
Brian Curtin1b9df392010-11-24 20:24:31 +00003944#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003945 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003946 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003947 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003948
Larry Hastings2f936352014-08-05 14:04:04 +10003949 if (!result)
3950 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003951#else
3952 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003953#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003954 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3955 (dst_dir_fd != DEFAULT_DIR_FD) ||
Ronald Oussoren41761932020-11-08 10:05:27 +01003956 (!follow_symlinks)) {
3957
3958 if (HAVE_LINKAT_RUNTIME) {
3959
3960 result = linkat(src_dir_fd, src->narrow,
3961 dst_dir_fd, dst->narrow,
3962 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3963
3964 }
3965#ifdef __APPLE__
3966 else {
3967 if (src_dir_fd == DEFAULT_DIR_FD && dst_dir_fd == DEFAULT_DIR_FD) {
3968 /* See issue 41355: This matches the behaviour of !HAVE_LINKAT */
3969 result = link(src->narrow, dst->narrow);
3970 } else {
3971 linkat_unavailable = 1;
3972 }
3973 }
3974#endif
3975 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003976 else
Steve Dowercc16be82016-09-08 10:35:16 -07003977#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003978 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003979 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003980
Ronald Oussoren41761932020-11-08 10:05:27 +01003981#ifdef HAVE_LINKAT
3982 if (linkat_unavailable) {
3983 /* Either or both dir_fd arguments were specified */
3984 if (src_dir_fd != DEFAULT_DIR_FD) {
3985 argument_unavailable_error("link", "src_dir_fd");
3986 } else {
3987 argument_unavailable_error("link", "dst_dir_fd");
3988 }
3989 return NULL;
3990 }
3991#endif
3992
Larry Hastings2f936352014-08-05 14:04:04 +10003993 if (result)
3994 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003995#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003996
Larry Hastings2f936352014-08-05 14:04:04 +10003997 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003998}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999#endif
4000
Brian Curtin1b9df392010-11-24 20:24:31 +00004001
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004002#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00004003static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07004004_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00004005{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004006 PyObject *v;
4007 HANDLE hFindFile = INVALID_HANDLE_VALUE;
4008 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07004009 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004010 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01004011 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004012 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004013
Steve Dowercc16be82016-09-08 10:35:16 -07004014 WIN32_FIND_DATAW wFileData;
4015 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004016
Steve Dowercc16be82016-09-08 10:35:16 -07004017 if (!path->wide) { /* Default arg: "." */
4018 po_wchars = L".";
4019 len = 1;
4020 } else {
4021 po_wchars = path->wide;
4022 len = wcslen(path->wide);
4023 }
4024 /* The +5 is so we can append "\\*.*\0" */
4025 wnamebuf = PyMem_New(wchar_t, len + 5);
4026 if (!wnamebuf) {
4027 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07004028 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004029 }
Steve Dowercc16be82016-09-08 10:35:16 -07004030 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00004031 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07004032 wchar_t wch = wnamebuf[len-1];
4033 if (wch != SEP && wch != ALTSEP && wch != L':')
4034 wnamebuf[len++] = SEP;
4035 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00004036 }
Steve Dowercc16be82016-09-08 10:35:16 -07004037 if ((list = PyList_New(0)) == NULL) {
4038 goto exit;
4039 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00004040 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004041 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00004042 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004043 if (hFindFile == INVALID_HANDLE_VALUE) {
4044 int error = GetLastError();
4045 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004046 goto exit;
4047 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004048 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004049 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004050 }
4051 do {
4052 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07004053 if (wcscmp(wFileData.cFileName, L".") != 0 &&
4054 wcscmp(wFileData.cFileName, L"..") != 0) {
4055 v = PyUnicode_FromWideChar(wFileData.cFileName,
4056 wcslen(wFileData.cFileName));
4057 if (path->narrow && v) {
4058 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
4059 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004060 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004061 Py_DECREF(list);
4062 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004063 break;
4064 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004065 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004066 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004067 Py_DECREF(list);
4068 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004069 break;
4070 }
4071 Py_DECREF(v);
4072 }
4073 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004074 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00004075 Py_END_ALLOW_THREADS
4076 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
4077 it got to the end of the directory. */
4078 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004079 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004080 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004082 }
4083 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004084
Larry Hastings9cf065c2012-06-22 16:30:09 -07004085exit:
4086 if (hFindFile != INVALID_HANDLE_VALUE) {
4087 if (FindClose(hFindFile) == FALSE) {
4088 if (list != NULL) {
4089 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004090 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004091 }
4092 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004093 }
Victor Stinnerb6404912013-07-07 16:21:41 +02004094 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004095
Larry Hastings9cf065c2012-06-22 16:30:09 -07004096 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004097} /* end of _listdir_windows_no_opendir */
4098
4099#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
4100
4101static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07004102_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004103{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004104 PyObject *v;
4105 DIR *dirp = NULL;
4106 struct dirent *ep;
4107 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004108#ifdef HAVE_FDOPENDIR
4109 int fd = -1;
4110#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004111
Victor Stinner8c62be82010-05-06 00:08:46 +00004112 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07004114 if (path->fd != -1) {
Ronald Oussoren41761932020-11-08 10:05:27 +01004115 if (HAVE_FDOPENDIR_RUNTIME) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004116 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02004117 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01004118 if (fd == -1)
4119 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004120
Larry Hastingsfdaea062012-06-25 04:42:23 -07004121 return_str = 1;
4122
Larry Hastings9cf065c2012-06-22 16:30:09 -07004123 Py_BEGIN_ALLOW_THREADS
4124 dirp = fdopendir(fd);
4125 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01004126 } else {
4127 PyErr_SetString(PyExc_TypeError,
4128 "listdir: path should be string, bytes, os.PathLike or None, not int");
4129 return NULL;
4130 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004131 }
4132 else
4133#endif
4134 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004135 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07004136 if (path->narrow) {
4137 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03004138 /* only return bytes if they specified a bytes-like object */
4139 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07004140 }
4141 else {
4142 name = ".";
4143 return_str = 1;
4144 }
4145
Larry Hastings9cf065c2012-06-22 16:30:09 -07004146 Py_BEGIN_ALLOW_THREADS
4147 dirp = opendir(name);
4148 Py_END_ALLOW_THREADS
4149 }
4150
4151 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07004152 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004153#ifdef HAVE_FDOPENDIR
4154 if (fd != -1) {
4155 Py_BEGIN_ALLOW_THREADS
4156 close(fd);
4157 Py_END_ALLOW_THREADS
4158 }
4159#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004160 goto exit;
4161 }
4162 if ((list = PyList_New(0)) == NULL) {
4163 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 }
4165 for (;;) {
4166 errno = 0;
4167 Py_BEGIN_ALLOW_THREADS
4168 ep = readdir(dirp);
4169 Py_END_ALLOW_THREADS
4170 if (ep == NULL) {
4171 if (errno == 0) {
4172 break;
4173 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004174 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004175 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004176 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004177 }
4178 }
4179 if (ep->d_name[0] == '.' &&
4180 (NAMLEN(ep) == 1 ||
4181 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
4182 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07004183 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00004184 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
4185 else
4186 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00004187 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004188 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004189 break;
4190 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004191 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004193 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004194 break;
4195 }
4196 Py_DECREF(v);
4197 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00004198
Larry Hastings9cf065c2012-06-22 16:30:09 -07004199exit:
4200 if (dirp != NULL) {
4201 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004202#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07004203 if (fd > -1)
4204 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004205#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004206 closedir(dirp);
4207 Py_END_ALLOW_THREADS
4208 }
4209
Larry Hastings9cf065c2012-06-22 16:30:09 -07004210 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004211} /* end of _posix_listdir */
4212#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004213
Larry Hastings2f936352014-08-05 14:04:04 +10004214
4215/*[clinic input]
4216os.listdir
4217
4218 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
4219
4220Return a list containing the names of the files in the directory.
4221
BNMetricsb9427072018-11-02 15:20:19 +00004222path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10004223 the filenames returned will also be bytes; in all other circumstances
4224 the filenames returned will be str.
4225If path is None, uses the path='.'.
4226On some platforms, path may also be specified as an open file descriptor;\
4227 the file descriptor must refer to a directory.
4228 If this functionality is unavailable, using it raises NotImplementedError.
4229
4230The list is in arbitrary order. It does not include the special
4231entries '.' and '..' even if they are present in the directory.
4232
4233
4234[clinic start generated code]*/
4235
Larry Hastings2f936352014-08-05 14:04:04 +10004236static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004237os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00004238/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004239{
Steve Dower60419a72019-06-24 08:42:54 -07004240 if (PySys_Audit("os.listdir", "O",
4241 path->object ? path->object : Py_None) < 0) {
4242 return NULL;
4243 }
Larry Hastings2f936352014-08-05 14:04:04 +10004244#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4245 return _listdir_windows_no_opendir(path, NULL);
4246#else
4247 return _posix_listdir(path, NULL);
4248#endif
4249}
4250
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004251#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00004252/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004253/*[clinic input]
4254os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02004255
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004256 path: path_t
4257 /
4258
4259[clinic start generated code]*/
4260
4261static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004262os__getfullpathname_impl(PyObject *module, path_t *path)
4263/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004264{
Victor Stinner3939c322019-06-25 15:02:43 +02004265 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004266
Victor Stinner3939c322019-06-25 15:02:43 +02004267 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
4268 if (_Py_abspath(path->wide, &abspath) < 0) {
4269 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00004270 }
Victor Stinner3939c322019-06-25 15:02:43 +02004271 if (abspath == NULL) {
4272 return PyErr_NoMemory();
4273 }
4274
4275 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
4276 PyMem_RawFree(abspath);
4277 if (str == NULL) {
4278 return NULL;
4279 }
4280 if (path->narrow) {
4281 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
4282 }
4283 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10004284}
Brian Curtind40e6f72010-07-08 21:39:08 +00004285
Brian Curtind25aef52011-06-13 15:16:04 -05004286
Larry Hastings2f936352014-08-05 14:04:04 +10004287/*[clinic input]
4288os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004289
Steve Dower23ad6d02018-02-22 10:39:10 -08004290 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004291 /
4292
4293A helper function for samepath on windows.
4294[clinic start generated code]*/
4295
Larry Hastings2f936352014-08-05 14:04:04 +10004296static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004297os__getfinalpathname_impl(PyObject *module, path_t *path)
4298/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004299{
4300 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004301 wchar_t buf[MAXPATHLEN], *target_path = buf;
4302 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00004303 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004304 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004305
Steve Dower23ad6d02018-02-22 10:39:10 -08004306 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004307 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08004308 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004309 0, /* desired access */
4310 0, /* share mode */
4311 NULL, /* security attributes */
4312 OPEN_EXISTING,
4313 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4314 FILE_FLAG_BACKUP_SEMANTICS,
4315 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004316 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004317
Steve Dower23ad6d02018-02-22 10:39:10 -08004318 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004319 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004320 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004321
4322 /* We have a good handle to the target, use it to determine the
4323 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004324 while (1) {
4325 Py_BEGIN_ALLOW_THREADS
4326 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4327 buf_size, VOLUME_NAME_DOS);
4328 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004329
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004330 if (!result_length) {
4331 result = win32_error_object("GetFinalPathNameByHandleW",
4332 path->object);
4333 goto cleanup;
4334 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004335
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004336 if (result_length < buf_size) {
4337 break;
4338 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004339
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004340 wchar_t *tmp;
4341 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4342 result_length * sizeof(*tmp));
4343 if (!tmp) {
4344 result = PyErr_NoMemory();
4345 goto cleanup;
4346 }
4347
4348 buf_size = result_length;
4349 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004350 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004351
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004352 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004353 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004354 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004355 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004356
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004357cleanup:
4358 if (target_path != buf) {
4359 PyMem_Free(target_path);
4360 }
4361 CloseHandle(hFile);
4362 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004363}
Brian Curtin62857742010-09-06 17:07:27 +00004364
Tim Golden6b528062013-08-01 12:44:00 +01004365
Larry Hastings2f936352014-08-05 14:04:04 +10004366/*[clinic input]
4367os._getvolumepathname
4368
Steve Dower23ad6d02018-02-22 10:39:10 -08004369 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004370
4371A helper function for ismount on Win32.
4372[clinic start generated code]*/
4373
Larry Hastings2f936352014-08-05 14:04:04 +10004374static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004375os__getvolumepathname_impl(PyObject *module, path_t *path)
4376/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004377{
4378 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004379 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004380 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004381 BOOL ret;
4382
Tim Golden6b528062013-08-01 12:44:00 +01004383 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004384 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004385
Victor Stinner850a18e2017-10-24 16:53:32 -07004386 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004387 PyErr_SetString(PyExc_OverflowError, "path too long");
4388 return NULL;
4389 }
4390
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004391 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004392 if (mountpath == NULL)
4393 return PyErr_NoMemory();
4394
4395 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004396 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004397 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004398 Py_END_ALLOW_THREADS
4399
4400 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004401 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004402 goto exit;
4403 }
4404 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004405 if (path->narrow)
4406 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004407
4408exit:
4409 PyMem_Free(mountpath);
4410 return result;
4411}
Tim Golden6b528062013-08-01 12:44:00 +01004412
Steve Dower04732ca2021-04-07 01:02:07 +01004413
4414/*[clinic input]
4415os._path_splitroot
4416
4417 path: path_t
4418
4419Removes everything after the root on Win32.
4420[clinic start generated code]*/
4421
4422static PyObject *
4423os__path_splitroot_impl(PyObject *module, path_t *path)
4424/*[clinic end generated code: output=ab7f1a88b654581c input=dc93b1d3984cffb6]*/
4425{
4426 wchar_t *buffer;
4427 wchar_t *end;
4428 PyObject *result = NULL;
4429 HRESULT ret;
4430
4431 buffer = (wchar_t*)PyMem_Malloc(sizeof(wchar_t) * (wcslen(path->wide) + 1));
4432 if (!buffer) {
4433 return NULL;
4434 }
4435 wcscpy(buffer, path->wide);
4436 for (wchar_t *p = wcschr(buffer, L'/'); p; p = wcschr(p, L'/')) {
4437 *p = L'\\';
4438 }
4439
4440 Py_BEGIN_ALLOW_THREADS
4441 ret = PathCchSkipRoot(buffer, &end);
4442 Py_END_ALLOW_THREADS
4443 if (FAILED(ret)) {
4444 result = Py_BuildValue("sO", "", path->object);
4445 } else if (end != buffer) {
4446 size_t rootLen = (size_t)(end - buffer);
4447 result = Py_BuildValue("NN",
4448 PyUnicode_FromWideChar(path->wide, rootLen),
4449 PyUnicode_FromWideChar(path->wide + rootLen, -1)
4450 );
4451 } else {
4452 result = Py_BuildValue("Os", path->object, "");
4453 }
4454 PyMem_Free(buffer);
4455
4456 return result;
4457}
4458
4459
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004460#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004461
Larry Hastings2f936352014-08-05 14:04:04 +10004462
4463/*[clinic input]
4464os.mkdir
4465
4466 path : path_t
4467
4468 mode: int = 0o777
4469
4470 *
4471
4472 dir_fd : dir_fd(requires='mkdirat') = None
4473
4474# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4475
4476Create a directory.
4477
4478If dir_fd is not None, it should be a file descriptor open to a directory,
4479 and path should be relative; path will then be relative to that directory.
4480dir_fd may not be implemented on your platform.
4481 If it is unavailable, using it will raise a NotImplementedError.
4482
4483The mode argument is ignored on Windows.
4484[clinic start generated code]*/
4485
Larry Hastings2f936352014-08-05 14:04:04 +10004486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004487os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4488/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004489{
4490 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004491#ifdef HAVE_MKDIRAT
4492 int mkdirat_unavailable = 0;
4493#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004494
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004495 if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
4496 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4497 return NULL;
4498 }
4499
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004500#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004501 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004502 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004503 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004504
Larry Hastings2f936352014-08-05 14:04:04 +10004505 if (!result)
4506 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004507#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004508 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004509#if HAVE_MKDIRAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004510 if (dir_fd != DEFAULT_DIR_FD) {
4511 if (HAVE_MKDIRAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10004512 result = mkdirat(dir_fd, path->narrow, mode);
Ronald Oussoren41761932020-11-08 10:05:27 +01004513
4514 } else {
4515 mkdirat_unavailable = 1;
4516 }
4517 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004519#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004520 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004521#else
Larry Hastings2f936352014-08-05 14:04:04 +10004522 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004523#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004524 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01004525
4526#if HAVE_MKDIRAT
4527 if (mkdirat_unavailable) {
4528 argument_unavailable_error(NULL, "dir_fd");
4529 return NULL;
4530 }
4531#endif
4532
Larry Hastings2f936352014-08-05 14:04:04 +10004533 if (result < 0)
4534 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004535#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004536 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004537}
4538
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004539
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004540/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4541#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004542#include <sys/resource.h>
4543#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004544
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004545
4546#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004547/*[clinic input]
4548os.nice
4549
4550 increment: int
4551 /
4552
4553Add increment to the priority of process and return the new priority.
4554[clinic start generated code]*/
4555
Larry Hastings2f936352014-08-05 14:04:04 +10004556static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004557os_nice_impl(PyObject *module, int increment)
4558/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004559{
4560 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004561
Victor Stinner8c62be82010-05-06 00:08:46 +00004562 /* There are two flavours of 'nice': one that returns the new
4563 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004564 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004565 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004566
Victor Stinner8c62be82010-05-06 00:08:46 +00004567 If we are of the nice family that returns the new priority, we
4568 need to clear errno before the call, and check if errno is filled
4569 before calling posix_error() on a returnvalue of -1, because the
4570 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004571
Victor Stinner8c62be82010-05-06 00:08:46 +00004572 errno = 0;
4573 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004574#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004575 if (value == 0)
4576 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004577#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004578 if (value == -1 && errno != 0)
4579 /* either nice() or getpriority() returned an error */
4580 return posix_error();
4581 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004582}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004583#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004584
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004585
4586#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004587/*[clinic input]
4588os.getpriority
4589
4590 which: int
4591 who: int
4592
4593Return program scheduling priority.
4594[clinic start generated code]*/
4595
Larry Hastings2f936352014-08-05 14:04:04 +10004596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004597os_getpriority_impl(PyObject *module, int which, int who)
4598/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004599{
4600 int retval;
4601
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004602 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004603 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004604 if (errno != 0)
4605 return posix_error();
4606 return PyLong_FromLong((long)retval);
4607}
4608#endif /* HAVE_GETPRIORITY */
4609
4610
4611#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004612/*[clinic input]
4613os.setpriority
4614
4615 which: int
4616 who: int
4617 priority: int
4618
4619Set program scheduling priority.
4620[clinic start generated code]*/
4621
Larry Hastings2f936352014-08-05 14:04:04 +10004622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004623os_setpriority_impl(PyObject *module, int which, int who, int priority)
4624/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004625{
4626 int retval;
4627
4628 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004629 if (retval == -1)
4630 return posix_error();
4631 Py_RETURN_NONE;
4632}
4633#endif /* HAVE_SETPRIORITY */
4634
4635
Barry Warsaw53699e91996-12-10 23:23:01 +00004636static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004637internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004638{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004639 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004640 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641
Ronald Oussoren41761932020-11-08 10:05:27 +01004642#ifdef HAVE_RENAMEAT
4643 int renameat_unavailable = 0;
4644#endif
4645
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004646#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004647 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004648 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004649#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004650 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004651#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652
Larry Hastings9cf065c2012-06-22 16:30:09 -07004653 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4654 (dst_dir_fd != DEFAULT_DIR_FD);
4655#ifndef HAVE_RENAMEAT
4656 if (dir_fd_specified) {
4657 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004658 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004659 }
4660#endif
4661
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004662 if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
4663 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
4664 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
4665 return NULL;
4666 }
4667
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668#ifdef MS_WINDOWS
4669 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004670 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671 Py_END_ALLOW_THREADS
4672
Larry Hastings2f936352014-08-05 14:04:04 +10004673 if (!result)
4674 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675
4676#else
Steve Dowercc16be82016-09-08 10:35:16 -07004677 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4678 PyErr_Format(PyExc_ValueError,
4679 "%s: src and dst must be the same type", function_name);
4680 return NULL;
4681 }
4682
Larry Hastings9cf065c2012-06-22 16:30:09 -07004683 Py_BEGIN_ALLOW_THREADS
4684#ifdef HAVE_RENAMEAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004685 if (dir_fd_specified) {
4686 if (HAVE_RENAMEAT_RUNTIME) {
4687 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
4688 } else {
4689 renameat_unavailable = 1;
4690 }
4691 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004692#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004693 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004694 Py_END_ALLOW_THREADS
4695
Ronald Oussoren41761932020-11-08 10:05:27 +01004696
4697#ifdef HAVE_RENAMEAT
4698 if (renameat_unavailable) {
4699 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4700 return NULL;
4701 }
4702#endif
4703
Larry Hastings2f936352014-08-05 14:04:04 +10004704 if (result)
4705 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004707 Py_RETURN_NONE;
4708}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004709
Larry Hastings2f936352014-08-05 14:04:04 +10004710
4711/*[clinic input]
4712os.rename
4713
4714 src : path_t
4715 dst : path_t
4716 *
4717 src_dir_fd : dir_fd = None
4718 dst_dir_fd : dir_fd = None
4719
4720Rename a file or directory.
4721
4722If either src_dir_fd or dst_dir_fd is not None, it should be a file
4723 descriptor open to a directory, and the respective path string (src or dst)
4724 should be relative; the path will then be relative to that directory.
4725src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4726 If they are unavailable, using them will raise a NotImplementedError.
4727[clinic start generated code]*/
4728
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004729static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004730os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004731 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004732/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004733{
Larry Hastings2f936352014-08-05 14:04:04 +10004734 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004735}
4736
Larry Hastings2f936352014-08-05 14:04:04 +10004737
4738/*[clinic input]
4739os.replace = os.rename
4740
4741Rename a file or directory, overwriting the destination.
4742
4743If either src_dir_fd or dst_dir_fd is not None, it should be a file
4744 descriptor open to a directory, and the respective path string (src or dst)
4745 should be relative; the path will then be relative to that directory.
4746src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004747 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004748[clinic start generated code]*/
4749
Larry Hastings2f936352014-08-05 14:04:04 +10004750static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004751os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4752 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004753/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004754{
4755 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4756}
4757
4758
4759/*[clinic input]
4760os.rmdir
4761
4762 path: path_t
4763 *
4764 dir_fd: dir_fd(requires='unlinkat') = None
4765
4766Remove a directory.
4767
4768If dir_fd is not None, it should be a file descriptor open to a directory,
4769 and path should be relative; path will then be relative to that directory.
4770dir_fd may not be implemented on your platform.
4771 If it is unavailable, using it will raise a NotImplementedError.
4772[clinic start generated code]*/
4773
Larry Hastings2f936352014-08-05 14:04:04 +10004774static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004775os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4776/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004777{
4778 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004779#ifdef HAVE_UNLINKAT
4780 int unlinkat_unavailable = 0;
4781#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004782
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004783 if (PySys_Audit("os.rmdir", "Oi", path->object,
4784 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4785 return NULL;
4786 }
4787
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004788 Py_BEGIN_ALLOW_THREADS
4789#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004790 /* Windows, success=1, UNIX, success=0 */
4791 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004792#else
4793#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004794 if (dir_fd != DEFAULT_DIR_FD) {
4795 if (HAVE_UNLINKAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10004796 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Ronald Oussoren41761932020-11-08 10:05:27 +01004797 } else {
4798 unlinkat_unavailable = 1;
4799 result = -1;
4800 }
4801 } else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004802#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004803 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004804#endif
4805 Py_END_ALLOW_THREADS
4806
Ronald Oussoren41761932020-11-08 10:05:27 +01004807#ifdef HAVE_UNLINKAT
4808 if (unlinkat_unavailable) {
4809 argument_unavailable_error("rmdir", "dir_fd");
4810 return NULL;
4811 }
4812#endif
4813
Larry Hastings2f936352014-08-05 14:04:04 +10004814 if (result)
4815 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004816
Larry Hastings2f936352014-08-05 14:04:04 +10004817 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004818}
4819
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004820
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004821#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004822#ifdef MS_WINDOWS
4823/*[clinic input]
4824os.system -> long
4825
4826 command: Py_UNICODE
4827
4828Execute the command in a subshell.
4829[clinic start generated code]*/
4830
Larry Hastings2f936352014-08-05 14:04:04 +10004831static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004832os_system_impl(PyObject *module, const Py_UNICODE *command)
4833/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004834{
4835 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004836
Steve Dowerfbe3c762019-10-18 00:52:15 -07004837 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004838 return -1;
4839 }
4840
Victor Stinner8c62be82010-05-06 00:08:46 +00004841 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004842 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004843 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004844 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004845 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004846 return result;
4847}
4848#else /* MS_WINDOWS */
4849/*[clinic input]
4850os.system -> long
4851
4852 command: FSConverter
4853
4854Execute the command in a subshell.
4855[clinic start generated code]*/
4856
Larry Hastings2f936352014-08-05 14:04:04 +10004857static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004858os_system_impl(PyObject *module, PyObject *command)
4859/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004860{
4861 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004862 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004863
Steve Dowerfbe3c762019-10-18 00:52:15 -07004864 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004865 return -1;
4866 }
4867
Larry Hastings2f936352014-08-05 14:04:04 +10004868 Py_BEGIN_ALLOW_THREADS
4869 result = system(bytes);
4870 Py_END_ALLOW_THREADS
4871 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004872}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004873#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004874#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004875
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004876
Larry Hastings2f936352014-08-05 14:04:04 +10004877/*[clinic input]
4878os.umask
4879
4880 mask: int
4881 /
4882
4883Set the current numeric umask and return the previous umask.
4884[clinic start generated code]*/
4885
Larry Hastings2f936352014-08-05 14:04:04 +10004886static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004887os_umask_impl(PyObject *module, int mask)
4888/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004889{
4890 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004891 if (i < 0)
4892 return posix_error();
4893 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004894}
4895
Brian Curtind40e6f72010-07-08 21:39:08 +00004896#ifdef MS_WINDOWS
4897
4898/* override the default DeleteFileW behavior so that directory
4899symlinks can be removed with this function, the same as with
4900Unix symlinks */
4901BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4902{
4903 WIN32_FILE_ATTRIBUTE_DATA info;
4904 WIN32_FIND_DATAW find_data;
4905 HANDLE find_data_handle;
4906 int is_directory = 0;
4907 int is_link = 0;
4908
4909 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4910 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004911
Brian Curtind40e6f72010-07-08 21:39:08 +00004912 /* Get WIN32_FIND_DATA structure for the path to determine if
4913 it is a symlink */
4914 if(is_directory &&
4915 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4916 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4917
4918 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004919 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4920 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4921 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4922 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004923 FindClose(find_data_handle);
4924 }
4925 }
4926 }
4927
4928 if (is_directory && is_link)
4929 return RemoveDirectoryW(lpFileName);
4930
4931 return DeleteFileW(lpFileName);
4932}
4933#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004934
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004935
Larry Hastings2f936352014-08-05 14:04:04 +10004936/*[clinic input]
4937os.unlink
4938
4939 path: path_t
4940 *
4941 dir_fd: dir_fd(requires='unlinkat')=None
4942
4943Remove a file (same as remove()).
4944
4945If dir_fd is not None, it should be a file descriptor open to a directory,
4946 and path should be relative; path will then be relative to that directory.
4947dir_fd may not be implemented on your platform.
4948 If it is unavailable, using it will raise a NotImplementedError.
4949
4950[clinic start generated code]*/
4951
Larry Hastings2f936352014-08-05 14:04:04 +10004952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004953os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4954/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004955{
4956 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004957#ifdef HAVE_UNLINKAT
4958 int unlinkat_unavailable = 0;
4959#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004960
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004961 if (PySys_Audit("os.remove", "Oi", path->object,
4962 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4963 return NULL;
4964 }
4965
Larry Hastings9cf065c2012-06-22 16:30:09 -07004966 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004967 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004969 /* Windows, success=1, UNIX, success=0 */
4970 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004971#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004972#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004973 if (dir_fd != DEFAULT_DIR_FD) {
4974 if (HAVE_UNLINKAT_RUNTIME) {
4975
Larry Hastings2f936352014-08-05 14:04:04 +10004976 result = unlinkat(dir_fd, path->narrow, 0);
Ronald Oussoren41761932020-11-08 10:05:27 +01004977 } else {
4978 unlinkat_unavailable = 1;
4979 }
4980 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004981#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004982 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004983#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004984 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985 Py_END_ALLOW_THREADS
4986
Ronald Oussoren41761932020-11-08 10:05:27 +01004987#ifdef HAVE_UNLINKAT
4988 if (unlinkat_unavailable) {
4989 argument_unavailable_error(NULL, "dir_fd");
4990 return NULL;
4991 }
4992#endif
4993
Larry Hastings2f936352014-08-05 14:04:04 +10004994 if (result)
4995 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004996
Larry Hastings2f936352014-08-05 14:04:04 +10004997 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004998}
4999
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005000
Larry Hastings2f936352014-08-05 14:04:04 +10005001/*[clinic input]
5002os.remove = os.unlink
5003
5004Remove a file (same as unlink()).
5005
5006If dir_fd is not None, it should be a file descriptor open to a directory,
5007 and path should be relative; path will then be relative to that directory.
5008dir_fd may not be implemented on your platform.
5009 If it is unavailable, using it will raise a NotImplementedError.
5010[clinic start generated code]*/
5011
Larry Hastings2f936352014-08-05 14:04:04 +10005012static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005013os_remove_impl(PyObject *module, path_t *path, int dir_fd)
5014/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005015{
5016 return os_unlink_impl(module, path, dir_fd);
5017}
5018
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005019
Larry Hastings605a62d2012-06-24 04:33:36 -07005020static PyStructSequence_Field uname_result_fields[] = {
5021 {"sysname", "operating system name"},
5022 {"nodename", "name of machine on network (implementation-defined)"},
5023 {"release", "operating system release"},
5024 {"version", "operating system version"},
5025 {"machine", "hardware identifier"},
5026 {NULL}
5027};
5028
5029PyDoc_STRVAR(uname_result__doc__,
5030"uname_result: Result from os.uname().\n\n\
5031This object may be accessed either as a tuple of\n\
5032 (sysname, nodename, release, version, machine),\n\
5033or via the attributes sysname, nodename, release, version, and machine.\n\
5034\n\
5035See os.uname for more information.");
5036
5037static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08005038 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07005039 uname_result__doc__, /* doc */
5040 uname_result_fields,
5041 5
5042};
5043
Larry Hastings605a62d2012-06-24 04:33:36 -07005044#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10005045/*[clinic input]
5046os.uname
5047
5048Return an object identifying the current operating system.
5049
5050The object behaves like a named tuple with the following fields:
5051 (sysname, nodename, release, version, machine)
5052
5053[clinic start generated code]*/
5054
Larry Hastings2f936352014-08-05 14:04:04 +10005055static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005056os_uname_impl(PyObject *module)
5057/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00005058{
Victor Stinner8c62be82010-05-06 00:08:46 +00005059 struct utsname u;
5060 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07005061 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00005062
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 Py_BEGIN_ALLOW_THREADS
5064 res = uname(&u);
5065 Py_END_ALLOW_THREADS
5066 if (res < 0)
5067 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07005068
Hai Shif707d942020-03-16 21:15:01 +08005069 PyObject *UnameResultType = get_posix_state(module)->UnameResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08005070 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07005071 if (value == NULL)
5072 return NULL;
5073
5074#define SET(i, field) \
5075 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02005076 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07005077 if (!o) { \
5078 Py_DECREF(value); \
5079 return NULL; \
5080 } \
5081 PyStructSequence_SET_ITEM(value, i, o); \
5082 } \
5083
5084 SET(0, u.sysname);
5085 SET(1, u.nodename);
5086 SET(2, u.release);
5087 SET(3, u.version);
5088 SET(4, u.machine);
5089
5090#undef SET
5091
5092 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00005093}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005094#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005095
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005096
Larry Hastings9cf065c2012-06-22 16:30:09 -07005097
5098typedef struct {
5099 int now;
5100 time_t atime_s;
5101 long atime_ns;
5102 time_t mtime_s;
5103 long mtime_ns;
5104} utime_t;
5105
5106/*
Victor Stinner484df002014-10-09 13:52:31 +02005107 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07005108 * they also intentionally leak the declaration of a pointer named "time"
5109 */
5110#define UTIME_TO_TIMESPEC \
5111 struct timespec ts[2]; \
5112 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005113 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005114 time = NULL; \
5115 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005116 ts[0].tv_sec = ut->atime_s; \
5117 ts[0].tv_nsec = ut->atime_ns; \
5118 ts[1].tv_sec = ut->mtime_s; \
5119 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005120 time = ts; \
5121 } \
5122
5123#define UTIME_TO_TIMEVAL \
5124 struct timeval tv[2]; \
5125 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005126 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005127 time = NULL; \
5128 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005129 tv[0].tv_sec = ut->atime_s; \
5130 tv[0].tv_usec = ut->atime_ns / 1000; \
5131 tv[1].tv_sec = ut->mtime_s; \
5132 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005133 time = tv; \
5134 } \
5135
5136#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005137 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005138 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005139 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005140 time = NULL; \
5141 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005142 u.actime = ut->atime_s; \
5143 u.modtime = ut->mtime_s; \
5144 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005145 }
5146
5147#define UTIME_TO_TIME_T \
5148 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005149 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005150 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005151 time = NULL; \
5152 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005153 timet[0] = ut->atime_s; \
5154 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005155 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005156 } \
5157
5158
Victor Stinner528a9ab2015-09-03 21:30:26 +02005159#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005160
5161static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005162utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005163{
Ronald Oussoren41761932020-11-08 10:05:27 +01005164#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5165 if (HAVE_UTIMENSAT_RUNTIME) {
5166 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5167 UTIME_TO_TIMESPEC;
5168 return utimensat(dir_fd, path, time, flags);
5169 } else {
5170 errno = ENOSYS;
5171 return -1;
5172 }
5173#elif defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005174 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5175 UTIME_TO_TIMESPEC;
5176 return utimensat(dir_fd, path, time, flags);
5177#elif defined(HAVE_FUTIMESAT)
5178 UTIME_TO_TIMEVAL;
5179 /*
5180 * follow_symlinks will never be false here;
5181 * we only allow !follow_symlinks and dir_fd together
5182 * if we have utimensat()
5183 */
5184 assert(follow_symlinks);
5185 return futimesat(dir_fd, path, time);
5186#endif
5187}
5188
Larry Hastings2f936352014-08-05 14:04:04 +10005189 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
5190#else
5191 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07005192#endif
5193
Victor Stinner528a9ab2015-09-03 21:30:26 +02005194#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005195
5196static int
Victor Stinner484df002014-10-09 13:52:31 +02005197utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005198{
5199#ifdef HAVE_FUTIMENS
Ronald Oussoren41761932020-11-08 10:05:27 +01005200
5201 if (HAVE_FUTIMENS_RUNTIME) {
5202
Larry Hastings9cf065c2012-06-22 16:30:09 -07005203 UTIME_TO_TIMESPEC;
5204 return futimens(fd, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005205
5206 } else
5207#ifndef HAVE_FUTIMES
5208 {
5209 /* Not sure if this can happen */
5210 PyErr_SetString(
5211 PyExc_RuntimeError,
5212 "neither futimens nor futimes are supported"
5213 " on this system");
5214 return -1;
5215 }
5216#endif
5217
5218#endif
5219#ifdef HAVE_FUTIMES
5220 {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005221 UTIME_TO_TIMEVAL;
5222 return futimes(fd, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005223 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005224#endif
5225}
5226
Larry Hastings2f936352014-08-05 14:04:04 +10005227 #define PATH_UTIME_HAVE_FD 1
5228#else
5229 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07005230#endif
5231
Victor Stinner5ebae872015-09-22 01:29:33 +02005232#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
5233# define UTIME_HAVE_NOFOLLOW_SYMLINKS
5234#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005235
Victor Stinner4552ced2015-09-21 22:37:15 +02005236#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005237
5238static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005239utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005240{
5241#ifdef HAVE_UTIMENSAT
Ronald Oussoren41761932020-11-08 10:05:27 +01005242 if (HAVE_UTIMENSAT_RUNTIME) {
5243 UTIME_TO_TIMESPEC;
5244 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
5245 } else
5246#ifndef HAVE_LUTIMES
5247 {
5248 /* Not sure if this can happen */
5249 PyErr_SetString(
5250 PyExc_RuntimeError,
5251 "neither utimensat nor lutimes are supported"
5252 " on this system");
5253 return -1;
5254 }
5255#endif
5256#endif
5257
5258#ifdef HAVE_LUTIMES
5259 {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005260 UTIME_TO_TIMEVAL;
5261 return lutimes(path, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005262 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005263#endif
5264}
5265
5266#endif
5267
5268#ifndef MS_WINDOWS
5269
5270static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005271utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005272{
Ronald Oussoren41761932020-11-08 10:05:27 +01005273#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5274 if (HAVE_UTIMENSAT_RUNTIME) {
5275 UTIME_TO_TIMESPEC;
5276 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5277 } else {
5278 UTIME_TO_TIMEVAL;
5279 return utimes(path, time);
5280 }
5281#elif defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005282 UTIME_TO_TIMESPEC;
5283 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5284#elif defined(HAVE_UTIMES)
5285 UTIME_TO_TIMEVAL;
5286 return utimes(path, time);
5287#elif defined(HAVE_UTIME_H)
5288 UTIME_TO_UTIMBUF;
5289 return utime(path, time);
5290#else
5291 UTIME_TO_TIME_T;
5292 return utime(path, time);
5293#endif
5294}
5295
5296#endif
5297
Larry Hastings76ad59b2012-05-03 00:30:07 -07005298static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005299split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns)
Larry Hastings76ad59b2012-05-03 00:30:07 -07005300{
5301 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04005302 PyObject *divmod;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005303 divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07005304 if (!divmod)
5305 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03005306 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
5307 PyErr_Format(PyExc_TypeError,
5308 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08005309 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03005310 goto exit;
5311 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005312 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
5313 if ((*s == -1) && PyErr_Occurred())
5314 goto exit;
5315 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04005316 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07005317 goto exit;
5318
5319 result = 1;
5320exit:
5321 Py_XDECREF(divmod);
5322 return result;
5323}
5324
Larry Hastings2f936352014-08-05 14:04:04 +10005325
5326/*[clinic input]
5327os.utime
5328
5329 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005330 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10005331 *
5332 ns: object = NULL
5333 dir_fd: dir_fd(requires='futimensat') = None
5334 follow_symlinks: bool=True
5335
Martin Panter0ff89092015-09-09 01:56:53 +00005336# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10005337
5338Set the access and modified time of path.
5339
5340path may always be specified as a string.
5341On some platforms, path may also be specified as an open file descriptor.
5342 If this functionality is unavailable, using it raises an exception.
5343
5344If times is not None, it must be a tuple (atime, mtime);
5345 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00005346If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10005347 atime_ns and mtime_ns should be expressed as integer nanoseconds
5348 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00005349If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10005350Specifying tuples for both times and ns is an error.
5351
5352If dir_fd is not None, it should be a file descriptor open to a directory,
5353 and path should be relative; path will then be relative to that directory.
5354If follow_symlinks is False, and the last element of the path is a symbolic
5355 link, utime will modify the symbolic link itself instead of the file the
5356 link points to.
5357It is an error to use dir_fd or follow_symlinks when specifying path
5358 as an open file descriptor.
5359dir_fd and follow_symlinks may not be available on your platform.
5360 If they are unavailable, using them will raise a NotImplementedError.
5361
5362[clinic start generated code]*/
5363
Larry Hastings2f936352014-08-05 14:04:04 +10005364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005365os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
5366 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005367/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005368{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005369#ifdef MS_WINDOWS
5370 HANDLE hFile;
5371 FILETIME atime, mtime;
5372#else
5373 int result;
5374#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005375
Larry Hastings2f936352014-08-05 14:04:04 +10005376 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005377
Christian Heimesb3c87242013-08-01 00:08:16 +02005378 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07005379
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005380 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005381 PyErr_SetString(PyExc_ValueError,
5382 "utime: you may specify either 'times'"
5383 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005384 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005385 }
5386
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005387 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005388 time_t a_sec, m_sec;
5389 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005390 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005391 PyErr_SetString(PyExc_TypeError,
5392 "utime: 'times' must be either"
5393 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005394 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005395 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005396 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005397 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02005398 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005399 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02005400 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005401 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005402 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005403 utime.atime_s = a_sec;
5404 utime.atime_ns = a_nsec;
5405 utime.mtime_s = m_sec;
5406 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005407 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005408 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07005409 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005410 PyErr_SetString(PyExc_TypeError,
5411 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005412 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005413 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005414 utime.now = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005415 if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005416 &utime.atime_s, &utime.atime_ns) ||
Victor Stinner1c2fa782020-05-10 11:05:29 +02005417 !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005418 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005419 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005420 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005421 }
5422 else {
5423 /* times and ns are both None/unspecified. use "now". */
5424 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005425 }
5426
Victor Stinner4552ced2015-09-21 22:37:15 +02005427#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005428 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005429 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005430#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005431
Larry Hastings2f936352014-08-05 14:04:04 +10005432 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
5433 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
5434 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005435 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005436
Larry Hastings9cf065c2012-06-22 16:30:09 -07005437#if !defined(HAVE_UTIMENSAT)
5438 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02005439 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005440 "utime: cannot use dir_fd and follow_symlinks "
5441 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005442 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005443 }
5444#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005445
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005446 if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
5447 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
5448 return NULL;
5449 }
5450
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005451#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005452 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005453 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5454 NULL, OPEN_EXISTING,
5455 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005456 Py_END_ALLOW_THREADS
5457 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10005458 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005459 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005460 }
5461
Larry Hastings9cf065c2012-06-22 16:30:09 -07005462 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005463 GetSystemTimeAsFileTime(&mtime);
5464 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005465 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005466 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08005467 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5468 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005469 }
5470 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5471 /* Avoid putting the file name into the error here,
5472 as that may confuse the user into believing that
5473 something is wrong with the file, when it also
5474 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005475 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005476 CloseHandle(hFile);
5477 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005478 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005479 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005480#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005481 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005482
Victor Stinner4552ced2015-09-21 22:37:15 +02005483#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005484 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10005485 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005486 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005487#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005488
Victor Stinner528a9ab2015-09-03 21:30:26 +02005489#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Ronald Oussoren41761932020-11-08 10:05:27 +01005490 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
Larry Hastings2f936352014-08-05 14:04:04 +10005491 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Ronald Oussoren41761932020-11-08 10:05:27 +01005492
5493 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07005494#endif
5495
Victor Stinner528a9ab2015-09-03 21:30:26 +02005496#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005497 if (path->fd != -1)
5498 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005499 else
5500#endif
5501
Larry Hastings2f936352014-08-05 14:04:04 +10005502 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005503
5504 Py_END_ALLOW_THREADS
5505
Ronald Oussoren41761932020-11-08 10:05:27 +01005506#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5507 /* See utime_dir_fd implementation */
5508 if (result == -1 && errno == ENOSYS) {
5509 argument_unavailable_error(NULL, "dir_fd");
5510 return NULL;
5511 }
5512#endif
5513
Larry Hastings9cf065c2012-06-22 16:30:09 -07005514 if (result < 0) {
5515 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005516 posix_error();
5517 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005518 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005519
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005520#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005521
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005522 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005523}
5524
Guido van Rossum3b066191991-06-04 19:40:25 +00005525/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005526
Larry Hastings2f936352014-08-05 14:04:04 +10005527
5528/*[clinic input]
5529os._exit
5530
5531 status: int
5532
5533Exit to the system with specified status, without normal exit processing.
5534[clinic start generated code]*/
5535
Larry Hastings2f936352014-08-05 14:04:04 +10005536static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005537os__exit_impl(PyObject *module, int status)
5538/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005539{
5540 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005541 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005542}
5543
Steve Dowercc16be82016-09-08 10:35:16 -07005544#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5545#define EXECV_CHAR wchar_t
5546#else
5547#define EXECV_CHAR char
5548#endif
5549
pxinwrf2d7ac72019-05-21 18:46:37 +08005550#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005551static void
Steve Dowercc16be82016-09-08 10:35:16 -07005552free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005553{
Victor Stinner8c62be82010-05-06 00:08:46 +00005554 Py_ssize_t i;
5555 for (i = 0; i < count; i++)
5556 PyMem_Free(array[i]);
Victor Stinner00d7abd2020-12-01 09:56:42 +01005557 PyMem_Free(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005558}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005559
Berker Peksag81816462016-09-15 20:19:47 +03005560static int
5561fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005562{
Victor Stinner8c62be82010-05-06 00:08:46 +00005563 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005564 PyObject *ub;
5565 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005566#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005567 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005568 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005569 *out = PyUnicode_AsWideCharString(ub, &size);
5570 if (*out)
5571 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005572#else
Berker Peksag81816462016-09-15 20:19:47 +03005573 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005574 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005575 size = PyBytes_GET_SIZE(ub);
5576 *out = PyMem_Malloc(size + 1);
5577 if (*out) {
5578 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5579 result = 1;
5580 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005581 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005582#endif
Berker Peksag81816462016-09-15 20:19:47 +03005583 Py_DECREF(ub);
5584 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005585}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005586#endif
5587
pxinwrf2d7ac72019-05-21 18:46:37 +08005588#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005589static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005590parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5591{
Victor Stinner8c62be82010-05-06 00:08:46 +00005592 Py_ssize_t i, pos, envc;
5593 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005594 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005595 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005596
Victor Stinner8c62be82010-05-06 00:08:46 +00005597 i = PyMapping_Size(env);
5598 if (i < 0)
5599 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005600 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005601 if (envlist == NULL) {
5602 PyErr_NoMemory();
5603 return NULL;
5604 }
5605 envc = 0;
5606 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005607 if (!keys)
5608 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005609 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005610 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005611 goto error;
5612 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5613 PyErr_Format(PyExc_TypeError,
5614 "env.keys() or env.values() is not a list");
5615 goto error;
5616 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005617
Victor Stinner8c62be82010-05-06 00:08:46 +00005618 for (pos = 0; pos < i; pos++) {
5619 key = PyList_GetItem(keys, pos);
5620 val = PyList_GetItem(vals, pos);
5621 if (!key || !val)
5622 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005623
Berker Peksag81816462016-09-15 20:19:47 +03005624#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5625 if (!PyUnicode_FSDecoder(key, &key2))
5626 goto error;
5627 if (!PyUnicode_FSDecoder(val, &val2)) {
5628 Py_DECREF(key2);
5629 goto error;
5630 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005631 /* Search from index 1 because on Windows starting '=' is allowed for
5632 defining hidden environment variables. */
5633 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5634 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5635 {
5636 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005637 Py_DECREF(key2);
5638 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005639 goto error;
5640 }
Berker Peksag81816462016-09-15 20:19:47 +03005641 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5642#else
5643 if (!PyUnicode_FSConverter(key, &key2))
5644 goto error;
5645 if (!PyUnicode_FSConverter(val, &val2)) {
5646 Py_DECREF(key2);
5647 goto error;
5648 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005649 if (PyBytes_GET_SIZE(key2) == 0 ||
5650 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5651 {
5652 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005653 Py_DECREF(key2);
5654 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005655 goto error;
5656 }
Berker Peksag81816462016-09-15 20:19:47 +03005657 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5658 PyBytes_AS_STRING(val2));
5659#endif
5660 Py_DECREF(key2);
5661 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005662 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005663 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005664
5665 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5666 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005667 goto error;
5668 }
Berker Peksag81816462016-09-15 20:19:47 +03005669
Steve Dowercc16be82016-09-08 10:35:16 -07005670 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005671 }
5672 Py_DECREF(vals);
5673 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005674
Victor Stinner8c62be82010-05-06 00:08:46 +00005675 envlist[envc] = 0;
5676 *envc_ptr = envc;
5677 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005678
5679error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005680 Py_XDECREF(keys);
5681 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005682 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005683 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005684}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005685
Steve Dowercc16be82016-09-08 10:35:16 -07005686static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005687parse_arglist(PyObject* argv, Py_ssize_t *argc)
5688{
5689 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005690 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005691 if (argvlist == NULL) {
5692 PyErr_NoMemory();
5693 return NULL;
5694 }
5695 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005696 PyObject* item = PySequence_ITEM(argv, i);
5697 if (item == NULL)
5698 goto fail;
5699 if (!fsconvert_strdup(item, &argvlist[i])) {
5700 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005701 goto fail;
5702 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005703 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005704 }
5705 argvlist[*argc] = NULL;
5706 return argvlist;
5707fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005708 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005709 free_string_array(argvlist, *argc);
5710 return NULL;
5711}
Steve Dowercc16be82016-09-08 10:35:16 -07005712
Ross Lagerwall7807c352011-03-17 20:20:30 +02005713#endif
5714
Larry Hastings2f936352014-08-05 14:04:04 +10005715
Ross Lagerwall7807c352011-03-17 20:20:30 +02005716#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005717/*[clinic input]
5718os.execv
5719
Steve Dowercc16be82016-09-08 10:35:16 -07005720 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005721 Path of executable file.
5722 argv: object
5723 Tuple or list of strings.
5724 /
5725
5726Execute an executable path with arguments, replacing current process.
5727[clinic start generated code]*/
5728
Larry Hastings2f936352014-08-05 14:04:04 +10005729static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005730os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5731/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005732{
Steve Dowercc16be82016-09-08 10:35:16 -07005733 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005734 Py_ssize_t argc;
5735
5736 /* execv has two arguments: (path, argv), where
5737 argv is a list or tuple of strings. */
5738
Ross Lagerwall7807c352011-03-17 20:20:30 +02005739 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5740 PyErr_SetString(PyExc_TypeError,
5741 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005742 return NULL;
5743 }
5744 argc = PySequence_Size(argv);
5745 if (argc < 1) {
5746 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005747 return NULL;
5748 }
5749
5750 argvlist = parse_arglist(argv, &argc);
5751 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005752 return NULL;
5753 }
Steve Dowerbce26262016-11-19 19:17:26 -08005754 if (!argvlist[0][0]) {
5755 PyErr_SetString(PyExc_ValueError,
5756 "execv() arg 2 first element cannot be empty");
5757 free_string_array(argvlist, argc);
5758 return NULL;
5759 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005760
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005761 if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005762 free_string_array(argvlist, argc);
5763 return NULL;
5764 }
5765
Steve Dowerbce26262016-11-19 19:17:26 -08005766 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005767#ifdef HAVE_WEXECV
5768 _wexecv(path->wide, argvlist);
5769#else
5770 execv(path->narrow, argvlist);
5771#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005772 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005773
5774 /* If we get here it's definitely an error */
5775
5776 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005777 return posix_error();
5778}
5779
Larry Hastings2f936352014-08-05 14:04:04 +10005780
5781/*[clinic input]
5782os.execve
5783
5784 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5785 Path of executable file.
5786 argv: object
5787 Tuple or list of strings.
5788 env: object
5789 Dictionary of strings mapping to strings.
5790
5791Execute an executable path with arguments, replacing current process.
5792[clinic start generated code]*/
5793
Larry Hastings2f936352014-08-05 14:04:04 +10005794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005795os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5796/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005797{
Steve Dowercc16be82016-09-08 10:35:16 -07005798 EXECV_CHAR **argvlist = NULL;
5799 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005800 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005801
Victor Stinner8c62be82010-05-06 00:08:46 +00005802 /* execve has three arguments: (path, argv, env), where
5803 argv is a list or tuple of strings and env is a dictionary
5804 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005805
Ross Lagerwall7807c352011-03-17 20:20:30 +02005806 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005807 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005808 "execve: argv must be a tuple or list");
Saiyang Gou95f60012020-02-04 16:15:00 -08005809 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005810 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005811 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005812 if (argc < 1) {
5813 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5814 return NULL;
5815 }
5816
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 if (!PyMapping_Check(env)) {
5818 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005819 "execve: environment must be a mapping object");
Saiyang Gou95f60012020-02-04 16:15:00 -08005820 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005821 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005822
Ross Lagerwall7807c352011-03-17 20:20:30 +02005823 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005824 if (argvlist == NULL) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005825 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005826 }
Steve Dowerbce26262016-11-19 19:17:26 -08005827 if (!argvlist[0][0]) {
5828 PyErr_SetString(PyExc_ValueError,
5829 "execve: argv first element cannot be empty");
Saiyang Gou95f60012020-02-04 16:15:00 -08005830 goto fail_0;
Steve Dowerbce26262016-11-19 19:17:26 -08005831 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005832
Victor Stinner8c62be82010-05-06 00:08:46 +00005833 envlist = parse_envlist(env, &envc);
5834 if (envlist == NULL)
Saiyang Gou95f60012020-02-04 16:15:00 -08005835 goto fail_0;
5836
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005837 if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005838 goto fail_1;
5839 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005840
Steve Dowerbce26262016-11-19 19:17:26 -08005841 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005842#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005843 if (path->fd > -1)
5844 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005845 else
5846#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005847#ifdef HAVE_WEXECV
5848 _wexecve(path->wide, argvlist, envlist);
5849#else
Larry Hastings2f936352014-08-05 14:04:04 +10005850 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005851#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005852 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005853
5854 /* If we get here it's definitely an error */
5855
Alexey Izbyshev83460312018-10-20 03:28:22 +03005856 posix_path_error(path);
Saiyang Gou95f60012020-02-04 16:15:00 -08005857 fail_1:
Steve Dowercc16be82016-09-08 10:35:16 -07005858 free_string_array(envlist, envc);
Saiyang Gou95f60012020-02-04 16:15:00 -08005859 fail_0:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005860 if (argvlist)
5861 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005862 return NULL;
5863}
Steve Dowercc16be82016-09-08 10:35:16 -07005864
Larry Hastings9cf065c2012-06-22 16:30:09 -07005865#endif /* HAVE_EXECV */
5866
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005867#ifdef HAVE_POSIX_SPAWN
5868
5869enum posix_spawn_file_actions_identifier {
5870 POSIX_SPAWN_OPEN,
5871 POSIX_SPAWN_CLOSE,
5872 POSIX_SPAWN_DUP2
5873};
5874
William Orr81574b82018-10-01 22:19:56 -07005875#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005876static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005877convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005878#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005879
5880static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005881parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005882 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005883 PyObject *setsigdef, PyObject *scheduler,
5884 posix_spawnattr_t *attrp)
5885{
5886 long all_flags = 0;
5887
5888 errno = posix_spawnattr_init(attrp);
5889 if (errno) {
5890 posix_error();
5891 return -1;
5892 }
5893
5894 if (setpgroup) {
5895 pid_t pgid = PyLong_AsPid(setpgroup);
5896 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5897 goto fail;
5898 }
5899 errno = posix_spawnattr_setpgroup(attrp, pgid);
5900 if (errno) {
5901 posix_error();
5902 goto fail;
5903 }
5904 all_flags |= POSIX_SPAWN_SETPGROUP;
5905 }
5906
5907 if (resetids) {
5908 all_flags |= POSIX_SPAWN_RESETIDS;
5909 }
5910
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005911 if (setsid) {
Ronald Oussoren41761932020-11-08 10:05:27 +01005912#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5913 if (HAVE_POSIX_SPAWN_SETSID_RUNTIME) {
5914#endif
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005915#ifdef POSIX_SPAWN_SETSID
5916 all_flags |= POSIX_SPAWN_SETSID;
5917#elif defined(POSIX_SPAWN_SETSID_NP)
5918 all_flags |= POSIX_SPAWN_SETSID_NP;
5919#else
5920 argument_unavailable_error(func_name, "setsid");
5921 return -1;
5922#endif
Ronald Oussoren41761932020-11-08 10:05:27 +01005923
5924#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5925 } else {
5926 argument_unavailable_error(func_name, "setsid");
5927 return -1;
5928 }
5929#endif /* HAVE_POSIX_SPAWN_SETSID_RUNTIME */
5930
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005931 }
5932
Pablo Galindo254a4662018-09-07 16:44:24 +01005933 if (setsigmask) {
5934 sigset_t set;
5935 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5936 goto fail;
5937 }
5938 errno = posix_spawnattr_setsigmask(attrp, &set);
5939 if (errno) {
5940 posix_error();
5941 goto fail;
5942 }
5943 all_flags |= POSIX_SPAWN_SETSIGMASK;
5944 }
5945
5946 if (setsigdef) {
5947 sigset_t set;
5948 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5949 goto fail;
5950 }
5951 errno = posix_spawnattr_setsigdefault(attrp, &set);
5952 if (errno) {
5953 posix_error();
5954 goto fail;
5955 }
5956 all_flags |= POSIX_SPAWN_SETSIGDEF;
5957 }
5958
5959 if (scheduler) {
5960#ifdef POSIX_SPAWN_SETSCHEDULER
5961 PyObject *py_schedpolicy;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005962 PyObject *schedparam_obj;
Pablo Galindo254a4662018-09-07 16:44:24 +01005963 struct sched_param schedparam;
5964
Victor Stinner1c2fa782020-05-10 11:05:29 +02005965 if (!PyArg_ParseTuple(scheduler, "OO"
Pablo Galindo254a4662018-09-07 16:44:24 +01005966 ";A scheduler tuple must have two elements",
Victor Stinner1c2fa782020-05-10 11:05:29 +02005967 &py_schedpolicy, &schedparam_obj)) {
5968 goto fail;
5969 }
5970 if (!convert_sched_param(module, schedparam_obj, &schedparam)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005971 goto fail;
5972 }
5973 if (py_schedpolicy != Py_None) {
5974 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5975
5976 if (schedpolicy == -1 && PyErr_Occurred()) {
5977 goto fail;
5978 }
5979 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5980 if (errno) {
5981 posix_error();
5982 goto fail;
5983 }
5984 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5985 }
5986 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5987 if (errno) {
5988 posix_error();
5989 goto fail;
5990 }
5991 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5992#else
5993 PyErr_SetString(PyExc_NotImplementedError,
5994 "The scheduler option is not supported in this system.");
5995 goto fail;
5996#endif
5997 }
5998
5999 errno = posix_spawnattr_setflags(attrp, all_flags);
6000 if (errno) {
6001 posix_error();
6002 goto fail;
6003 }
6004
6005 return 0;
6006
6007fail:
6008 (void)posix_spawnattr_destroy(attrp);
6009 return -1;
6010}
6011
6012static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03006013parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01006014 posix_spawn_file_actions_t *file_actionsp,
6015 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03006016{
6017 PyObject *seq;
6018 PyObject *file_action = NULL;
6019 PyObject *tag_obj;
6020
6021 seq = PySequence_Fast(file_actions,
6022 "file_actions must be a sequence or None");
6023 if (seq == NULL) {
6024 return -1;
6025 }
6026
6027 errno = posix_spawn_file_actions_init(file_actionsp);
6028 if (errno) {
6029 posix_error();
6030 Py_DECREF(seq);
6031 return -1;
6032 }
6033
Zackery Spytzd52a83a2019-06-26 14:54:20 -06006034 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03006035 file_action = PySequence_Fast_GET_ITEM(seq, i);
6036 Py_INCREF(file_action);
6037 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
6038 PyErr_SetString(PyExc_TypeError,
6039 "Each file_actions element must be a non-empty tuple");
6040 goto fail;
6041 }
6042 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
6043 if (tag == -1 && PyErr_Occurred()) {
6044 goto fail;
6045 }
6046
6047 /* Populate the file_actions object */
6048 switch (tag) {
6049 case POSIX_SPAWN_OPEN: {
6050 int fd, oflag;
6051 PyObject *path;
6052 unsigned long mode;
6053 if (!PyArg_ParseTuple(file_action, "OiO&ik"
6054 ";A open file_action tuple must have 5 elements",
6055 &tag_obj, &fd, PyUnicode_FSConverter, &path,
6056 &oflag, &mode))
6057 {
6058 goto fail;
6059 }
Pablo Galindocb970732018-06-19 09:19:50 +01006060 if (PyList_Append(temp_buffer, path)) {
6061 Py_DECREF(path);
6062 goto fail;
6063 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03006064 errno = posix_spawn_file_actions_addopen(file_actionsp,
6065 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01006066 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03006067 if (errno) {
6068 posix_error();
6069 goto fail;
6070 }
6071 break;
6072 }
6073 case POSIX_SPAWN_CLOSE: {
6074 int fd;
6075 if (!PyArg_ParseTuple(file_action, "Oi"
6076 ";A close file_action tuple must have 2 elements",
6077 &tag_obj, &fd))
6078 {
6079 goto fail;
6080 }
6081 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
6082 if (errno) {
6083 posix_error();
6084 goto fail;
6085 }
6086 break;
6087 }
6088 case POSIX_SPAWN_DUP2: {
6089 int fd1, fd2;
6090 if (!PyArg_ParseTuple(file_action, "Oii"
6091 ";A dup2 file_action tuple must have 3 elements",
6092 &tag_obj, &fd1, &fd2))
6093 {
6094 goto fail;
6095 }
6096 errno = posix_spawn_file_actions_adddup2(file_actionsp,
6097 fd1, fd2);
6098 if (errno) {
6099 posix_error();
6100 goto fail;
6101 }
6102 break;
6103 }
6104 default: {
6105 PyErr_SetString(PyExc_TypeError,
6106 "Unknown file_actions identifier");
6107 goto fail;
6108 }
6109 }
6110 Py_DECREF(file_action);
6111 }
Pablo Galindo254a4662018-09-07 16:44:24 +01006112
Serhiy Storchakaef347532018-05-01 16:45:04 +03006113 Py_DECREF(seq);
6114 return 0;
6115
6116fail:
6117 Py_DECREF(seq);
6118 Py_DECREF(file_action);
6119 (void)posix_spawn_file_actions_destroy(file_actionsp);
6120 return -1;
6121}
6122
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006123
6124static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006125py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
6126 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006127 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006128 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006129{
Victor Stinner325e4ba2019-02-01 15:47:24 +01006130 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006131 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006132 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006133 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006134 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01006135 posix_spawnattr_t attr;
6136 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006137 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006138 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01006139 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006140 pid_t pid;
6141 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006142
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006143 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03006144 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006145 like posix.environ. */
6146
Serhiy Storchakaef347532018-05-01 16:45:04 +03006147 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006148 PyErr_Format(PyExc_TypeError,
6149 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006150 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006151 }
6152 argc = PySequence_Size(argv);
6153 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006154 PyErr_Format(PyExc_ValueError,
6155 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006156 return NULL;
6157 }
6158
6159 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006160 PyErr_Format(PyExc_TypeError,
6161 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006162 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006163 }
6164
6165 argvlist = parse_arglist(argv, &argc);
6166 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006167 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006168 }
6169 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006170 PyErr_Format(PyExc_ValueError,
6171 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006172 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006173 }
6174
6175 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006176 if (envlist == NULL) {
6177 goto exit;
6178 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006179
Anthony Shaw948ed8c2019-05-10 12:00:06 +10006180 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01006181 /* There is a bug in old versions of glibc that makes some of the
6182 * helper functions for manipulating file actions not copy the provided
6183 * buffers. The problem is that posix_spawn_file_actions_addopen does not
6184 * copy the value of path for some old versions of glibc (<2.20).
6185 * The use of temp_buffer here is a workaround that keeps the
6186 * python objects that own the buffers alive until posix_spawn gets called.
6187 * Check https://bugs.python.org/issue33630 and
6188 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
6189 temp_buffer = PyList_New(0);
6190 if (!temp_buffer) {
6191 goto exit;
6192 }
6193 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006194 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006195 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03006196 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006197 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006198
Victor Stinner1c2fa782020-05-10 11:05:29 +02006199 if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid,
Victor Stinner325e4ba2019-02-01 15:47:24 +01006200 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01006201 goto exit;
6202 }
6203 attrp = &attr;
6204
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006205 if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006206 goto exit;
6207 }
6208
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006209 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006210#ifdef HAVE_POSIX_SPAWNP
6211 if (use_posix_spawnp) {
6212 err_code = posix_spawnp(&pid, path->narrow,
6213 file_actionsp, attrp, argvlist, envlist);
6214 }
6215 else
6216#endif /* HAVE_POSIX_SPAWNP */
6217 {
6218 err_code = posix_spawn(&pid, path->narrow,
6219 file_actionsp, attrp, argvlist, envlist);
6220 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006221 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006222
Serhiy Storchakaef347532018-05-01 16:45:04 +03006223 if (err_code) {
6224 errno = err_code;
6225 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006226 goto exit;
6227 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006228#ifdef _Py_MEMORY_SANITIZER
6229 __msan_unpoison(&pid, sizeof(pid));
6230#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006231 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006232
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006233exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03006234 if (file_actionsp) {
6235 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006236 }
Pablo Galindo254a4662018-09-07 16:44:24 +01006237 if (attrp) {
6238 (void)posix_spawnattr_destroy(attrp);
6239 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006240 if (envlist) {
6241 free_string_array(envlist, envc);
6242 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006243 if (argvlist) {
6244 free_string_array(argvlist, argc);
6245 }
Pablo Galindocb970732018-06-19 09:19:50 +01006246 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006247 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006248}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006249
6250
6251/*[clinic input]
6252
6253os.posix_spawn
6254 path: path_t
6255 Path of executable file.
6256 argv: object
6257 Tuple or list of strings.
6258 env: object
6259 Dictionary of strings mapping to strings.
6260 /
6261 *
6262 file_actions: object(c_default='NULL') = ()
6263 A sequence of file action tuples.
6264 setpgroup: object = NULL
6265 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6266 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006267 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
6268 setsid: bool(accept={int}) = False
6269 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006270 setsigmask: object(c_default='NULL') = ()
6271 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6272 setsigdef: object(c_default='NULL') = ()
6273 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6274 scheduler: object = NULL
6275 A tuple with the scheduler policy (optional) and parameters.
6276
6277Execute the program specified by path in a new process.
6278[clinic start generated code]*/
6279
6280static PyObject *
6281os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
6282 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006283 PyObject *setpgroup, int resetids, int setsid,
6284 PyObject *setsigmask, PyObject *setsigdef,
6285 PyObject *scheduler)
6286/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006287{
6288 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006289 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006290 scheduler);
6291}
6292 #endif /* HAVE_POSIX_SPAWN */
6293
6294
6295
6296#ifdef HAVE_POSIX_SPAWNP
6297/*[clinic input]
6298
6299os.posix_spawnp
6300 path: path_t
6301 Path of executable file.
6302 argv: object
6303 Tuple or list of strings.
6304 env: object
6305 Dictionary of strings mapping to strings.
6306 /
6307 *
6308 file_actions: object(c_default='NULL') = ()
6309 A sequence of file action tuples.
6310 setpgroup: object = NULL
6311 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6312 resetids: bool(accept={int}) = False
6313 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006314 setsid: bool(accept={int}) = False
6315 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006316 setsigmask: object(c_default='NULL') = ()
6317 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6318 setsigdef: object(c_default='NULL') = ()
6319 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6320 scheduler: object = NULL
6321 A tuple with the scheduler policy (optional) and parameters.
6322
6323Execute the program specified by path in a new process.
6324[clinic start generated code]*/
6325
6326static PyObject *
6327os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
6328 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006329 PyObject *setpgroup, int resetids, int setsid,
6330 PyObject *setsigmask, PyObject *setsigdef,
6331 PyObject *scheduler)
6332/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006333{
6334 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006335 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006336 scheduler);
6337}
6338#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006339
pxinwrf2d7ac72019-05-21 18:46:37 +08006340#ifdef HAVE_RTPSPAWN
6341static intptr_t
6342_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
6343 const char *envp[])
6344{
6345 RTP_ID rtpid;
6346 int status;
6347 pid_t res;
6348 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006349
pxinwrf2d7ac72019-05-21 18:46:37 +08006350 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
6351 uStackSize=0 cannot be used, the default stack size is too small for
6352 Python. */
6353 if (envp) {
6354 rtpid = rtpSpawn(rtpFileName, argv, envp,
6355 100, 0x1000000, 0, VX_FP_TASK);
6356 }
6357 else {
6358 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
6359 100, 0x1000000, 0, VX_FP_TASK);
6360 }
6361 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
6362 do {
6363 res = waitpid((pid_t)rtpid, &status, 0);
6364 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6365
6366 if (res < 0)
6367 return RTP_ID_ERROR;
6368 return ((intptr_t)status);
6369 }
6370 return ((intptr_t)rtpid);
6371}
6372#endif
6373
6374#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10006375/*[clinic input]
6376os.spawnv
6377
6378 mode: int
6379 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006380 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006381 Path of executable file.
6382 argv: object
6383 Tuple or list of strings.
6384 /
6385
6386Execute the program specified by path in a new process.
6387[clinic start generated code]*/
6388
Larry Hastings2f936352014-08-05 14:04:04 +10006389static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006390os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
6391/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006392{
Steve Dowercc16be82016-09-08 10:35:16 -07006393 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10006394 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00006395 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006396 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00006398
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 /* spawnv has three arguments: (mode, path, argv), where
6400 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006401
Victor Stinner8c62be82010-05-06 00:08:46 +00006402 if (PyList_Check(argv)) {
6403 argc = PyList_Size(argv);
6404 getitem = PyList_GetItem;
6405 }
6406 else if (PyTuple_Check(argv)) {
6407 argc = PyTuple_Size(argv);
6408 getitem = PyTuple_GetItem;
6409 }
6410 else {
6411 PyErr_SetString(PyExc_TypeError,
6412 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 return NULL;
6414 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006415 if (argc == 0) {
6416 PyErr_SetString(PyExc_ValueError,
6417 "spawnv() arg 2 cannot be empty");
6418 return NULL;
6419 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006420
Steve Dowercc16be82016-09-08 10:35:16 -07006421 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 return PyErr_NoMemory();
6424 }
6425 for (i = 0; i < argc; i++) {
6426 if (!fsconvert_strdup((*getitem)(argv, i),
6427 &argvlist[i])) {
6428 free_string_array(argvlist, i);
6429 PyErr_SetString(
6430 PyExc_TypeError,
6431 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00006432 return NULL;
6433 }
Steve Dower93ff8722016-11-19 19:03:54 -08006434 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02006435 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08006436 PyErr_SetString(
6437 PyExc_ValueError,
6438 "spawnv() arg 2 first element cannot be empty");
6439 return NULL;
6440 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006441 }
6442 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006443
pxinwrf2d7ac72019-05-21 18:46:37 +08006444#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006445 if (mode == _OLD_P_OVERLAY)
6446 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006447#endif
Tim Peters5aa91602002-01-30 05:46:57 +00006448
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006449 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
Saiyang Gou95f60012020-02-04 16:15:00 -08006450 Py_None) < 0) {
6451 free_string_array(argvlist, argc);
6452 return NULL;
6453 }
6454
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006456 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006457#ifdef HAVE_WSPAWNV
6458 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006459#elif defined(HAVE_RTPSPAWN)
6460 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07006461#else
6462 spawnval = _spawnv(mode, path->narrow, argvlist);
6463#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006464 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006465 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00006466
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00006468
Victor Stinner8c62be82010-05-06 00:08:46 +00006469 if (spawnval == -1)
6470 return posix_error();
6471 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006472 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006473}
6474
Larry Hastings2f936352014-08-05 14:04:04 +10006475/*[clinic input]
6476os.spawnve
6477
6478 mode: int
6479 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006480 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006481 Path of executable file.
6482 argv: object
6483 Tuple or list of strings.
6484 env: object
6485 Dictionary of strings mapping to strings.
6486 /
6487
6488Execute the program specified by path in a new process.
6489[clinic start generated code]*/
6490
Larry Hastings2f936352014-08-05 14:04:04 +10006491static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006492os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006493 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07006494/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006495{
Steve Dowercc16be82016-09-08 10:35:16 -07006496 EXECV_CHAR **argvlist;
6497 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006498 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006499 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006500 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006501 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006502 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006503
Victor Stinner8c62be82010-05-06 00:08:46 +00006504 /* spawnve has four arguments: (mode, path, argv, env), where
6505 argv is a list or tuple of strings and env is a dictionary
6506 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006507
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 if (PyList_Check(argv)) {
6509 argc = PyList_Size(argv);
6510 getitem = PyList_GetItem;
6511 }
6512 else if (PyTuple_Check(argv)) {
6513 argc = PyTuple_Size(argv);
6514 getitem = PyTuple_GetItem;
6515 }
6516 else {
6517 PyErr_SetString(PyExc_TypeError,
6518 "spawnve() arg 2 must be a tuple or list");
6519 goto fail_0;
6520 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006521 if (argc == 0) {
6522 PyErr_SetString(PyExc_ValueError,
6523 "spawnve() arg 2 cannot be empty");
6524 goto fail_0;
6525 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006526 if (!PyMapping_Check(env)) {
6527 PyErr_SetString(PyExc_TypeError,
6528 "spawnve() arg 3 must be a mapping object");
6529 goto fail_0;
6530 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006531
Steve Dowercc16be82016-09-08 10:35:16 -07006532 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006533 if (argvlist == NULL) {
6534 PyErr_NoMemory();
6535 goto fail_0;
6536 }
6537 for (i = 0; i < argc; i++) {
6538 if (!fsconvert_strdup((*getitem)(argv, i),
6539 &argvlist[i]))
6540 {
6541 lastarg = i;
6542 goto fail_1;
6543 }
Steve Dowerbce26262016-11-19 19:17:26 -08006544 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006545 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006546 PyErr_SetString(
6547 PyExc_ValueError,
6548 "spawnv() arg 2 first element cannot be empty");
6549 goto fail_1;
6550 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 }
6552 lastarg = argc;
6553 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006554
Victor Stinner8c62be82010-05-06 00:08:46 +00006555 envlist = parse_envlist(env, &envc);
6556 if (envlist == NULL)
6557 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006558
pxinwrf2d7ac72019-05-21 18:46:37 +08006559#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 if (mode == _OLD_P_OVERLAY)
6561 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006562#endif
Tim Peters25059d32001-12-07 20:35:43 +00006563
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006564 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006565 goto fail_2;
6566 }
6567
Victor Stinner8c62be82010-05-06 00:08:46 +00006568 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006569 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006570#ifdef HAVE_WSPAWNV
6571 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006572#elif defined(HAVE_RTPSPAWN)
6573 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6574 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006575#else
6576 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6577#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006578 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006579 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006580
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 if (spawnval == -1)
6582 (void) posix_error();
6583 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006584 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006585
Saiyang Gou95f60012020-02-04 16:15:00 -08006586 fail_2:
Victor Stinner00d7abd2020-12-01 09:56:42 +01006587 while (--envc >= 0) {
6588 PyMem_Free(envlist[envc]);
6589 }
6590 PyMem_Free(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006591 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006592 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006593 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006595}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006596
Guido van Rossuma1065681999-01-25 23:20:23 +00006597#endif /* HAVE_SPAWNV */
6598
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006599#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006600
6601/* Helper function to validate arguments.
6602 Returns 0 on success. non-zero on failure with a TypeError raised.
6603 If obj is non-NULL it must be callable. */
6604static int
6605check_null_or_callable(PyObject *obj, const char* obj_name)
6606{
6607 if (obj && !PyCallable_Check(obj)) {
6608 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006609 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006610 return -1;
6611 }
6612 return 0;
6613}
6614
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006615/*[clinic input]
6616os.register_at_fork
6617
Gregory P. Smith163468a2017-05-29 10:03:41 -07006618 *
6619 before: object=NULL
6620 A callable to be called in the parent before the fork() syscall.
6621 after_in_child: object=NULL
6622 A callable to be called in the child after fork().
6623 after_in_parent: object=NULL
6624 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006625
Gregory P. Smith163468a2017-05-29 10:03:41 -07006626Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006627
Gregory P. Smith163468a2017-05-29 10:03:41 -07006628'before' callbacks are called in reverse order.
6629'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006630
6631[clinic start generated code]*/
6632
6633static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006634os_register_at_fork_impl(PyObject *module, PyObject *before,
6635 PyObject *after_in_child, PyObject *after_in_parent)
6636/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006637{
6638 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006639
Gregory P. Smith163468a2017-05-29 10:03:41 -07006640 if (!before && !after_in_child && !after_in_parent) {
6641 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6642 return NULL;
6643 }
6644 if (check_null_or_callable(before, "before") ||
6645 check_null_or_callable(after_in_child, "after_in_child") ||
6646 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006647 return NULL;
6648 }
Victor Stinner81a7be32020-04-14 15:14:01 +02006649 interp = _PyInterpreterState_GET();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006650
Gregory P. Smith163468a2017-05-29 10:03:41 -07006651 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006652 return NULL;
6653 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006654 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006655 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006656 }
6657 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6658 return NULL;
6659 }
6660 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006661}
6662#endif /* HAVE_FORK */
6663
6664
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006665#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006666/*[clinic input]
6667os.fork1
6668
6669Fork a child process with a single multiplexed (i.e., not bound) thread.
6670
6671Return 0 to child process and PID of child to parent process.
6672[clinic start generated code]*/
6673
Larry Hastings2f936352014-08-05 14:04:04 +10006674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006675os_fork1_impl(PyObject *module)
6676/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006677{
Victor Stinner8c62be82010-05-06 00:08:46 +00006678 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006679
Victor Stinner81a7be32020-04-14 15:14:01 +02006680 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006681 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6682 return NULL;
6683 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006684 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006685 pid = fork1();
6686 if (pid == 0) {
6687 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006688 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 } else {
6690 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006691 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 }
6693 if (pid == -1)
6694 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006696}
Larry Hastings2f936352014-08-05 14:04:04 +10006697#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006698
6699
Guido van Rossumad0ee831995-03-01 10:34:45 +00006700#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006701/*[clinic input]
6702os.fork
6703
6704Fork a child process.
6705
6706Return 0 to child process and PID of child to parent process.
6707[clinic start generated code]*/
6708
Larry Hastings2f936352014-08-05 14:04:04 +10006709static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006710os_fork_impl(PyObject *module)
6711/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006712{
Victor Stinner8c62be82010-05-06 00:08:46 +00006713 pid_t pid;
Victor Stinner252346a2020-05-01 11:33:44 +02006714 PyInterpreterState *interp = _PyInterpreterState_GET();
6715 if (interp->config._isolated_interpreter) {
6716 PyErr_SetString(PyExc_RuntimeError,
6717 "fork not supported for isolated subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -07006718 return NULL;
6719 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006720 if (PySys_Audit("os.fork", NULL) < 0) {
6721 return NULL;
6722 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006723 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006724 pid = fork();
6725 if (pid == 0) {
6726 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006727 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006728 } else {
6729 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006730 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006731 }
6732 if (pid == -1)
6733 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006735}
Larry Hastings2f936352014-08-05 14:04:04 +10006736#endif /* HAVE_FORK */
6737
Guido van Rossum85e3b011991-06-03 12:42:10 +00006738
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006739#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006740#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006741/*[clinic input]
6742os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006743
Larry Hastings2f936352014-08-05 14:04:04 +10006744 policy: int
6745
6746Get the maximum scheduling priority for policy.
6747[clinic start generated code]*/
6748
Larry Hastings2f936352014-08-05 14:04:04 +10006749static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006750os_sched_get_priority_max_impl(PyObject *module, int policy)
6751/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006752{
6753 int max;
6754
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006755 max = sched_get_priority_max(policy);
6756 if (max < 0)
6757 return posix_error();
6758 return PyLong_FromLong(max);
6759}
6760
Larry Hastings2f936352014-08-05 14:04:04 +10006761
6762/*[clinic input]
6763os.sched_get_priority_min
6764
6765 policy: int
6766
6767Get the minimum scheduling priority for policy.
6768[clinic start generated code]*/
6769
Larry Hastings2f936352014-08-05 14:04:04 +10006770static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006771os_sched_get_priority_min_impl(PyObject *module, int policy)
6772/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006773{
6774 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006775 if (min < 0)
6776 return posix_error();
6777 return PyLong_FromLong(min);
6778}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006779#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6780
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006781
Larry Hastings2f936352014-08-05 14:04:04 +10006782#ifdef HAVE_SCHED_SETSCHEDULER
6783/*[clinic input]
6784os.sched_getscheduler
6785 pid: pid_t
6786 /
6787
Min ho Kimc4cacc82019-07-31 08:16:13 +10006788Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006789
6790Passing 0 for pid returns the scheduling policy for the calling process.
6791[clinic start generated code]*/
6792
Larry Hastings2f936352014-08-05 14:04:04 +10006793static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006794os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006795/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006796{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006797 int policy;
6798
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006799 policy = sched_getscheduler(pid);
6800 if (policy < 0)
6801 return posix_error();
6802 return PyLong_FromLong(policy);
6803}
Larry Hastings2f936352014-08-05 14:04:04 +10006804#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006805
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006806
William Orr81574b82018-10-01 22:19:56 -07006807#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006808/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006809class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006810
6811@classmethod
6812os.sched_param.__new__
6813
6814 sched_priority: object
6815 A scheduling parameter.
6816
Eddie Elizondob3966632019-11-05 07:16:14 -08006817Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006818[clinic start generated code]*/
6819
Larry Hastings2f936352014-08-05 14:04:04 +10006820static PyObject *
6821os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006822/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006823{
6824 PyObject *res;
6825
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006826 res = PyStructSequence_New(type);
6827 if (!res)
6828 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006829 Py_INCREF(sched_priority);
6830 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006831 return res;
6832}
6833
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006834PyDoc_VAR(os_sched_param__doc__);
6835
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006836static PyStructSequence_Field sched_param_fields[] = {
6837 {"sched_priority", "the scheduling priority"},
6838 {0}
6839};
6840
6841static PyStructSequence_Desc sched_param_desc = {
6842 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006843 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006844 sched_param_fields,
6845 1
6846};
6847
6848static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006849convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006850{
6851 long priority;
6852
Victor Stinner1c2fa782020-05-10 11:05:29 +02006853 if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006854 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6855 return 0;
6856 }
6857 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6858 if (priority == -1 && PyErr_Occurred())
6859 return 0;
6860 if (priority > INT_MAX || priority < INT_MIN) {
6861 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6862 return 0;
6863 }
6864 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6865 return 1;
6866}
William Orr81574b82018-10-01 22:19:56 -07006867#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006868
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006869
6870#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006871/*[clinic input]
6872os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006873
Larry Hastings2f936352014-08-05 14:04:04 +10006874 pid: pid_t
6875 policy: int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006876 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006877 /
6878
6879Set the scheduling policy for the process identified by pid.
6880
6881If pid is 0, the calling process is changed.
6882param is an instance of sched_param.
6883[clinic start generated code]*/
6884
Larry Hastings2f936352014-08-05 14:04:04 +10006885static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006886os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Victor Stinner1c2fa782020-05-10 11:05:29 +02006887 PyObject *param_obj)
6888/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006889{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006890 struct sched_param param;
6891 if (!convert_sched_param(module, param_obj, &param)) {
6892 return NULL;
6893 }
6894
Jesus Cea9c822272011-09-10 01:40:52 +02006895 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006896 ** sched_setscheduler() returns 0 in Linux, but the previous
6897 ** scheduling policy under Solaris/Illumos, and others.
6898 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006899 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02006900 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006901 return posix_error();
6902 Py_RETURN_NONE;
6903}
Larry Hastings2f936352014-08-05 14:04:04 +10006904#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006905
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006906
6907#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006908/*[clinic input]
6909os.sched_getparam
6910 pid: pid_t
6911 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006912
Larry Hastings2f936352014-08-05 14:04:04 +10006913Returns scheduling parameters for the process identified by pid.
6914
6915If pid is 0, returns parameters for the calling process.
6916Return value is an instance of sched_param.
6917[clinic start generated code]*/
6918
Larry Hastings2f936352014-08-05 14:04:04 +10006919static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006920os_sched_getparam_impl(PyObject *module, pid_t pid)
6921/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006922{
6923 struct sched_param param;
6924 PyObject *result;
6925 PyObject *priority;
6926
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006927 if (sched_getparam(pid, &param))
6928 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02006929 PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -08006930 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006931 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006932 return NULL;
6933 priority = PyLong_FromLong(param.sched_priority);
6934 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006935 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006936 return NULL;
6937 }
Larry Hastings2f936352014-08-05 14:04:04 +10006938 PyStructSequence_SET_ITEM(result, 0, priority);
6939 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006940}
6941
Larry Hastings2f936352014-08-05 14:04:04 +10006942
6943/*[clinic input]
6944os.sched_setparam
6945 pid: pid_t
Victor Stinner1c2fa782020-05-10 11:05:29 +02006946 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006947 /
6948
6949Set scheduling parameters for the process identified by pid.
6950
6951If pid is 0, sets parameters for the calling process.
6952param should be an instance of sched_param.
6953[clinic start generated code]*/
6954
Larry Hastings2f936352014-08-05 14:04:04 +10006955static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02006956os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
6957/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006958{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006959 struct sched_param param;
6960 if (!convert_sched_param(module, param_obj, &param)) {
6961 return NULL;
6962 }
6963
6964 if (sched_setparam(pid, &param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006965 return posix_error();
6966 Py_RETURN_NONE;
6967}
Larry Hastings2f936352014-08-05 14:04:04 +10006968#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006969
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006970
6971#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006972/*[clinic input]
6973os.sched_rr_get_interval -> double
6974 pid: pid_t
6975 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006976
Larry Hastings2f936352014-08-05 14:04:04 +10006977Return the round-robin quantum for the process identified by pid, in seconds.
6978
6979Value returned is a float.
6980[clinic start generated code]*/
6981
Larry Hastings2f936352014-08-05 14:04:04 +10006982static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006983os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6984/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006985{
6986 struct timespec interval;
6987 if (sched_rr_get_interval(pid, &interval)) {
6988 posix_error();
6989 return -1.0;
6990 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006991#ifdef _Py_MEMORY_SANITIZER
6992 __msan_unpoison(&interval, sizeof(interval));
6993#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006994 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6995}
6996#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006997
Larry Hastings2f936352014-08-05 14:04:04 +10006998
6999/*[clinic input]
7000os.sched_yield
7001
7002Voluntarily relinquish the CPU.
7003[clinic start generated code]*/
7004
Larry Hastings2f936352014-08-05 14:04:04 +10007005static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007006os_sched_yield_impl(PyObject *module)
7007/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007008{
7009 if (sched_yield())
7010 return posix_error();
7011 Py_RETURN_NONE;
7012}
7013
Benjamin Peterson2740af82011-08-02 17:41:34 -05007014#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02007015/* The minimum number of CPUs allocated in a cpu_set_t */
7016static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007017
Larry Hastings2f936352014-08-05 14:04:04 +10007018/*[clinic input]
7019os.sched_setaffinity
7020 pid: pid_t
7021 mask : object
7022 /
7023
7024Set the CPU affinity of the process identified by pid to mask.
7025
7026mask should be an iterable of integers identifying CPUs.
7027[clinic start generated code]*/
7028
Larry Hastings2f936352014-08-05 14:04:04 +10007029static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007030os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
7031/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007032{
Antoine Pitrou84869872012-08-04 16:16:35 +02007033 int ncpus;
7034 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007035 cpu_set_t *cpu_set = NULL;
7036 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007037
Larry Hastings2f936352014-08-05 14:04:04 +10007038 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02007039 if (iterator == NULL)
7040 return NULL;
7041
7042 ncpus = NCPUS_START;
7043 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10007044 cpu_set = CPU_ALLOC(ncpus);
7045 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007046 PyErr_NoMemory();
7047 goto error;
7048 }
Larry Hastings2f936352014-08-05 14:04:04 +10007049 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007050
7051 while ((item = PyIter_Next(iterator))) {
7052 long cpu;
7053 if (!PyLong_Check(item)) {
7054 PyErr_Format(PyExc_TypeError,
7055 "expected an iterator of ints, "
7056 "but iterator yielded %R",
7057 Py_TYPE(item));
7058 Py_DECREF(item);
7059 goto error;
7060 }
7061 cpu = PyLong_AsLong(item);
7062 Py_DECREF(item);
7063 if (cpu < 0) {
7064 if (!PyErr_Occurred())
7065 PyErr_SetString(PyExc_ValueError, "negative CPU number");
7066 goto error;
7067 }
7068 if (cpu > INT_MAX - 1) {
7069 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
7070 goto error;
7071 }
7072 if (cpu >= ncpus) {
7073 /* Grow CPU mask to fit the CPU number */
7074 int newncpus = ncpus;
7075 cpu_set_t *newmask;
7076 size_t newsetsize;
7077 while (newncpus <= cpu) {
7078 if (newncpus > INT_MAX / 2)
7079 newncpus = cpu + 1;
7080 else
7081 newncpus = newncpus * 2;
7082 }
7083 newmask = CPU_ALLOC(newncpus);
7084 if (newmask == NULL) {
7085 PyErr_NoMemory();
7086 goto error;
7087 }
7088 newsetsize = CPU_ALLOC_SIZE(newncpus);
7089 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10007090 memcpy(newmask, cpu_set, setsize);
7091 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007092 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007093 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02007094 ncpus = newncpus;
7095 }
Larry Hastings2f936352014-08-05 14:04:04 +10007096 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007097 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07007098 if (PyErr_Occurred()) {
7099 goto error;
7100 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007101 Py_CLEAR(iterator);
7102
Larry Hastings2f936352014-08-05 14:04:04 +10007103 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007104 posix_error();
7105 goto error;
7106 }
Larry Hastings2f936352014-08-05 14:04:04 +10007107 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007108 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02007109
7110error:
Larry Hastings2f936352014-08-05 14:04:04 +10007111 if (cpu_set)
7112 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007113 Py_XDECREF(iterator);
7114 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007115}
7116
Larry Hastings2f936352014-08-05 14:04:04 +10007117
7118/*[clinic input]
7119os.sched_getaffinity
7120 pid: pid_t
7121 /
7122
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01007123Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10007124
7125The affinity is returned as a set of CPU identifiers.
7126[clinic start generated code]*/
7127
Larry Hastings2f936352014-08-05 14:04:04 +10007128static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007129os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03007130/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007131{
Antoine Pitrou84869872012-08-04 16:16:35 +02007132 int cpu, ncpus, count;
7133 size_t setsize;
7134 cpu_set_t *mask = NULL;
7135 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007136
Antoine Pitrou84869872012-08-04 16:16:35 +02007137 ncpus = NCPUS_START;
7138 while (1) {
7139 setsize = CPU_ALLOC_SIZE(ncpus);
7140 mask = CPU_ALLOC(ncpus);
7141 if (mask == NULL)
7142 return PyErr_NoMemory();
7143 if (sched_getaffinity(pid, setsize, mask) == 0)
7144 break;
7145 CPU_FREE(mask);
7146 if (errno != EINVAL)
7147 return posix_error();
7148 if (ncpus > INT_MAX / 2) {
7149 PyErr_SetString(PyExc_OverflowError, "could not allocate "
7150 "a large enough CPU set");
7151 return NULL;
7152 }
7153 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007154 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007155
7156 res = PySet_New(NULL);
7157 if (res == NULL)
7158 goto error;
7159 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
7160 if (CPU_ISSET_S(cpu, setsize, mask)) {
7161 PyObject *cpu_num = PyLong_FromLong(cpu);
7162 --count;
7163 if (cpu_num == NULL)
7164 goto error;
7165 if (PySet_Add(res, cpu_num)) {
7166 Py_DECREF(cpu_num);
7167 goto error;
7168 }
7169 Py_DECREF(cpu_num);
7170 }
7171 }
7172 CPU_FREE(mask);
7173 return res;
7174
7175error:
7176 if (mask)
7177 CPU_FREE(mask);
7178 Py_XDECREF(res);
7179 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007180}
7181
Benjamin Peterson2740af82011-08-02 17:41:34 -05007182#endif /* HAVE_SCHED_SETAFFINITY */
7183
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007184#endif /* HAVE_SCHED_H */
7185
Larry Hastings2f936352014-08-05 14:04:04 +10007186
Neal Norwitzb59798b2003-03-21 01:43:31 +00007187/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00007188#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Victor Stinner57766632020-10-29 15:16:23 +01007189# define DEV_PTY_FILE "/dev/ptc"
7190# define HAVE_DEV_PTMX
Neal Norwitzb59798b2003-03-21 01:43:31 +00007191#else
Victor Stinner57766632020-10-29 15:16:23 +01007192# define DEV_PTY_FILE "/dev/ptmx"
Neal Norwitzb59798b2003-03-21 01:43:31 +00007193#endif
7194
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007195#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00007196#ifdef HAVE_PTY_H
7197#include <pty.h>
7198#else
7199#ifdef HAVE_LIBUTIL_H
7200#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00007201#else
7202#ifdef HAVE_UTIL_H
7203#include <util.h>
7204#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007205#endif /* HAVE_LIBUTIL_H */
7206#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00007207#ifdef HAVE_STROPTS_H
7208#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007209#endif
ngie-eign7745ec42018-02-14 11:54:28 -08007210#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007211
Larry Hastings2f936352014-08-05 14:04:04 +10007212
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007213#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10007214/*[clinic input]
7215os.openpty
7216
7217Open a pseudo-terminal.
7218
7219Return a tuple of (master_fd, slave_fd) containing open file descriptors
7220for both the master and slave ends.
7221[clinic start generated code]*/
7222
Larry Hastings2f936352014-08-05 14:04:04 +10007223static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007224os_openpty_impl(PyObject *module)
7225/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007226{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007227 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007228#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007229 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007230#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007231#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007232 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01007233#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00007234 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007235#endif
7236#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00007237
Thomas Wouters70c21a12000-07-14 14:28:33 +00007238#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007239 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007240 goto posix_error;
7241
7242 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7243 goto error;
7244 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
7245 goto error;
7246
Neal Norwitzb59798b2003-03-21 01:43:31 +00007247#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007248 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
7249 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007250 goto posix_error;
7251 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7252 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007253
Victor Stinnerdaf45552013-08-28 00:53:59 +02007254 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00007255 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01007256 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007257
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007258#else
Victor Stinner000de532013-11-25 23:19:58 +01007259 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00007260 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007261 goto posix_error;
7262
Victor Stinner8c62be82010-05-06 00:08:46 +00007263 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007264
Victor Stinner8c62be82010-05-06 00:08:46 +00007265 /* change permission of slave */
7266 if (grantpt(master_fd) < 0) {
7267 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007268 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007269 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007270
Victor Stinner8c62be82010-05-06 00:08:46 +00007271 /* unlock slave */
7272 if (unlockpt(master_fd) < 0) {
7273 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007274 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007275 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007276
Victor Stinner8c62be82010-05-06 00:08:46 +00007277 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007278
Victor Stinner8c62be82010-05-06 00:08:46 +00007279 slave_name = ptsname(master_fd); /* get name of slave */
7280 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007281 goto posix_error;
7282
7283 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01007284 if (slave_fd == -1)
7285 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01007286
7287 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7288 goto posix_error;
7289
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02007290#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00007291 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
7292 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00007293#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00007294 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00007295#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007296#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00007297#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00007298
Victor Stinner8c62be82010-05-06 00:08:46 +00007299 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00007300
Victor Stinnerdaf45552013-08-28 00:53:59 +02007301posix_error:
7302 posix_error();
7303error:
7304 if (master_fd != -1)
7305 close(master_fd);
7306 if (slave_fd != -1)
7307 close(slave_fd);
7308 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00007309}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007310#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007311
Larry Hastings2f936352014-08-05 14:04:04 +10007312
Fred Drake8cef4cf2000-06-28 16:40:38 +00007313#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10007314/*[clinic input]
7315os.forkpty
7316
7317Fork a new process with a new pseudo-terminal as controlling tty.
7318
7319Returns a tuple of (pid, master_fd).
7320Like fork(), return pid of 0 to the child process,
7321and pid of child to the parent process.
7322To both, return fd of newly opened pseudo-terminal.
7323[clinic start generated code]*/
7324
Larry Hastings2f936352014-08-05 14:04:04 +10007325static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007326os_forkpty_impl(PyObject *module)
7327/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007328{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007329 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00007330 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00007331
Victor Stinner81a7be32020-04-14 15:14:01 +02007332 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07007333 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
7334 return NULL;
7335 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007336 if (PySys_Audit("os.forkpty", NULL) < 0) {
7337 return NULL;
7338 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007339 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00007340 pid = forkpty(&master_fd, NULL, NULL, NULL);
7341 if (pid == 0) {
7342 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007343 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00007344 } else {
7345 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007346 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00007347 }
7348 if (pid == -1)
7349 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007350 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00007351}
Larry Hastings2f936352014-08-05 14:04:04 +10007352#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007353
Ross Lagerwall7807c352011-03-17 20:20:30 +02007354
Guido van Rossumad0ee831995-03-01 10:34:45 +00007355#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007356/*[clinic input]
7357os.getegid
7358
7359Return the current process's effective group id.
7360[clinic start generated code]*/
7361
Larry Hastings2f936352014-08-05 14:04:04 +10007362static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007363os_getegid_impl(PyObject *module)
7364/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007365{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007366 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007367}
Larry Hastings2f936352014-08-05 14:04:04 +10007368#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007369
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007370
Guido van Rossumad0ee831995-03-01 10:34:45 +00007371#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007372/*[clinic input]
7373os.geteuid
7374
7375Return the current process's effective user id.
7376[clinic start generated code]*/
7377
Larry Hastings2f936352014-08-05 14:04:04 +10007378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007379os_geteuid_impl(PyObject *module)
7380/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007381{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007382 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007383}
Larry Hastings2f936352014-08-05 14:04:04 +10007384#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007385
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007386
Guido van Rossumad0ee831995-03-01 10:34:45 +00007387#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007388/*[clinic input]
7389os.getgid
7390
7391Return the current process's group id.
7392[clinic start generated code]*/
7393
Larry Hastings2f936352014-08-05 14:04:04 +10007394static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007395os_getgid_impl(PyObject *module)
7396/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007397{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007398 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007399}
Larry Hastings2f936352014-08-05 14:04:04 +10007400#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007401
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007402
Berker Peksag39404992016-09-15 20:45:16 +03007403#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10007404/*[clinic input]
7405os.getpid
7406
7407Return the current process id.
7408[clinic start generated code]*/
7409
Larry Hastings2f936352014-08-05 14:04:04 +10007410static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007411os_getpid_impl(PyObject *module)
7412/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007413{
Victor Stinner8c62be82010-05-06 00:08:46 +00007414 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00007415}
Berker Peksag39404992016-09-15 20:45:16 +03007416#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007417
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007418#ifdef NGROUPS_MAX
7419#define MAX_GROUPS NGROUPS_MAX
7420#else
7421 /* defined to be 16 on Solaris7, so this should be a small number */
7422#define MAX_GROUPS 64
7423#endif
7424
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007425#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10007426
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007427#ifdef __APPLE__
7428/*[clinic input]
7429os.getgrouplist
7430
7431 user: str
7432 username to lookup
7433 group as basegid: int
7434 base group id of the user
7435 /
7436
7437Returns a list of groups to which a user belongs.
7438[clinic start generated code]*/
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007439
7440static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007441os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
7442/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
7443#else
7444/*[clinic input]
7445os.getgrouplist
7446
7447 user: str
7448 username to lookup
7449 group as basegid: gid_t
7450 base group id of the user
7451 /
7452
7453Returns a list of groups to which a user belongs.
7454[clinic start generated code]*/
7455
7456static PyObject *
7457os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
7458/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
7459#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007460{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007461 int i, ngroups;
7462 PyObject *list;
7463#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007464 int *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007465#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007466 gid_t *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007467#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007468
7469 /*
7470 * NGROUPS_MAX is defined by POSIX.1 as the maximum
7471 * number of supplimental groups a users can belong to.
7472 * We have to increment it by one because
7473 * getgrouplist() returns both the supplemental groups
7474 * and the primary group, i.e. all of the groups the
7475 * user belongs to.
7476 */
7477 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007478
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007479 while (1) {
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007480#ifdef __APPLE__
Victor Stinner8ec73702020-03-23 20:00:57 +01007481 groups = PyMem_New(int, ngroups);
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007482#else
7483 groups = PyMem_New(gid_t, ngroups);
7484#endif
Victor Stinner8ec73702020-03-23 20:00:57 +01007485 if (groups == NULL) {
7486 return PyErr_NoMemory();
7487 }
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007488
7489 int old_ngroups = ngroups;
7490 if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
7491 /* Success */
7492 break;
7493 }
7494
7495 /* getgrouplist() fails if the group list is too small */
7496 PyMem_Free(groups);
7497
7498 if (ngroups > old_ngroups) {
7499 /* If the group list is too small, the glibc implementation of
7500 getgrouplist() sets ngroups to the total number of groups and
7501 returns -1. */
7502 }
7503 else {
7504 /* Double the group list size */
7505 if (ngroups > INT_MAX / 2) {
7506 return PyErr_NoMemory();
7507 }
7508 ngroups *= 2;
7509 }
7510
7511 /* Retry getgrouplist() with a larger group list */
Victor Stinner8ec73702020-03-23 20:00:57 +01007512 }
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007513
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007514#ifdef _Py_MEMORY_SANITIZER
7515 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7516 __msan_unpoison(&ngroups, sizeof(ngroups));
7517 __msan_unpoison(groups, ngroups*sizeof(*groups));
7518#endif
7519
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007520 list = PyList_New(ngroups);
7521 if (list == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01007522 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007523 return NULL;
7524 }
7525
7526 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007527#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007528 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007529#else
7530 PyObject *o = _PyLong_FromGid(groups[i]);
7531#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007532 if (o == NULL) {
7533 Py_DECREF(list);
Victor Stinner00d7abd2020-12-01 09:56:42 +01007534 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007535 return NULL;
7536 }
7537 PyList_SET_ITEM(list, i, o);
7538 }
7539
Victor Stinner00d7abd2020-12-01 09:56:42 +01007540 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007541
7542 return list;
7543}
Larry Hastings2f936352014-08-05 14:04:04 +10007544#endif /* HAVE_GETGROUPLIST */
7545
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007546
Fred Drakec9680921999-12-13 16:37:25 +00007547#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007548/*[clinic input]
7549os.getgroups
7550
7551Return list of supplemental group IDs for the process.
7552[clinic start generated code]*/
7553
Larry Hastings2f936352014-08-05 14:04:04 +10007554static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007555os_getgroups_impl(PyObject *module)
7556/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007557{
7558 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007559 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007560
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007561 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007562 * This is a helper variable to store the intermediate result when
7563 * that happens.
7564 *
7565 * To keep the code readable the OSX behaviour is unconditional,
7566 * according to the POSIX spec this should be safe on all unix-y
7567 * systems.
7568 */
7569 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007570 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007571
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007572#ifdef __APPLE__
7573 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7574 * there are more groups than can fit in grouplist. Therefore, on OS X
7575 * always first call getgroups with length 0 to get the actual number
7576 * of groups.
7577 */
7578 n = getgroups(0, NULL);
7579 if (n < 0) {
7580 return posix_error();
7581 } else if (n <= MAX_GROUPS) {
7582 /* groups will fit in existing array */
7583 alt_grouplist = grouplist;
7584 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007585 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007586 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007587 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007588 }
7589 }
7590
7591 n = getgroups(n, alt_grouplist);
7592 if (n == -1) {
7593 if (alt_grouplist != grouplist) {
7594 PyMem_Free(alt_grouplist);
7595 }
7596 return posix_error();
7597 }
7598#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007599 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007600 if (n < 0) {
7601 if (errno == EINVAL) {
7602 n = getgroups(0, NULL);
7603 if (n == -1) {
7604 return posix_error();
7605 }
7606 if (n == 0) {
7607 /* Avoid malloc(0) */
7608 alt_grouplist = grouplist;
7609 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007610 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007611 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007612 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007613 }
7614 n = getgroups(n, alt_grouplist);
7615 if (n == -1) {
7616 PyMem_Free(alt_grouplist);
7617 return posix_error();
7618 }
7619 }
7620 } else {
7621 return posix_error();
7622 }
7623 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007624#endif
7625
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007626 result = PyList_New(n);
7627 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007628 int i;
7629 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007630 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007631 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007632 Py_DECREF(result);
7633 result = NULL;
7634 break;
Fred Drakec9680921999-12-13 16:37:25 +00007635 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007636 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007637 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007638 }
7639
7640 if (alt_grouplist != grouplist) {
7641 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007642 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007643
Fred Drakec9680921999-12-13 16:37:25 +00007644 return result;
7645}
Larry Hastings2f936352014-08-05 14:04:04 +10007646#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007647
Antoine Pitroub7572f02009-12-02 20:46:48 +00007648#ifdef HAVE_INITGROUPS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007649#ifdef __APPLE__
7650/*[clinic input]
7651os.initgroups
Antoine Pitroub7572f02009-12-02 20:46:48 +00007652
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007653 username as oname: FSConverter
7654 gid: int
7655 /
7656
7657Initialize the group access list.
7658
7659Call the system initgroups() to initialize the group access list with all of
7660the groups of which the specified username is a member, plus the specified
7661group id.
7662[clinic start generated code]*/
7663
Antoine Pitroub7572f02009-12-02 20:46:48 +00007664static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007665os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7666/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7667#else
7668/*[clinic input]
7669os.initgroups
7670
7671 username as oname: FSConverter
7672 gid: gid_t
7673 /
7674
7675Initialize the group access list.
7676
7677Call the system initgroups() to initialize the group access list with all of
7678the groups of which the specified username is a member, plus the specified
7679group id.
7680[clinic start generated code]*/
7681
7682static PyObject *
7683os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7684/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7685#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007686{
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007687 const char *username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007688
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007689 if (initgroups(username, gid) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007690 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007691
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007692 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007693}
Larry Hastings2f936352014-08-05 14:04:04 +10007694#endif /* HAVE_INITGROUPS */
7695
Antoine Pitroub7572f02009-12-02 20:46:48 +00007696
Martin v. Löwis606edc12002-06-13 21:09:11 +00007697#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007698/*[clinic input]
7699os.getpgid
7700
7701 pid: pid_t
7702
7703Call the system call getpgid(), and return the result.
7704[clinic start generated code]*/
7705
Larry Hastings2f936352014-08-05 14:04:04 +10007706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007707os_getpgid_impl(PyObject *module, pid_t pid)
7708/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007709{
7710 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 if (pgid < 0)
7712 return posix_error();
7713 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007714}
7715#endif /* HAVE_GETPGID */
7716
7717
Guido van Rossumb6775db1994-08-01 11:34:53 +00007718#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007719/*[clinic input]
7720os.getpgrp
7721
7722Return the current process group id.
7723[clinic start generated code]*/
7724
Larry Hastings2f936352014-08-05 14:04:04 +10007725static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007726os_getpgrp_impl(PyObject *module)
7727/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007728{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007729#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007730 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007731#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007732 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007733#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007734}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007735#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007736
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007737
Guido van Rossumb6775db1994-08-01 11:34:53 +00007738#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007739/*[clinic input]
7740os.setpgrp
7741
7742Make the current process the leader of its process group.
7743[clinic start generated code]*/
7744
Larry Hastings2f936352014-08-05 14:04:04 +10007745static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007746os_setpgrp_impl(PyObject *module)
7747/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007748{
Guido van Rossum64933891994-10-20 21:56:42 +00007749#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007751#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007753#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007755 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007756}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007757#endif /* HAVE_SETPGRP */
7758
Guido van Rossumad0ee831995-03-01 10:34:45 +00007759#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007760
7761#ifdef MS_WINDOWS
7762#include <tlhelp32.h>
7763
7764static PyObject*
7765win32_getppid()
7766{
7767 HANDLE snapshot;
7768 pid_t mypid;
7769 PyObject* result = NULL;
7770 BOOL have_record;
7771 PROCESSENTRY32 pe;
7772
7773 mypid = getpid(); /* This function never fails */
7774
7775 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7776 if (snapshot == INVALID_HANDLE_VALUE)
7777 return PyErr_SetFromWindowsErr(GetLastError());
7778
7779 pe.dwSize = sizeof(pe);
7780 have_record = Process32First(snapshot, &pe);
7781 while (have_record) {
7782 if (mypid == (pid_t)pe.th32ProcessID) {
7783 /* We could cache the ulong value in a static variable. */
7784 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7785 break;
7786 }
7787
7788 have_record = Process32Next(snapshot, &pe);
7789 }
7790
7791 /* If our loop exits and our pid was not found (result will be NULL)
7792 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7793 * error anyway, so let's raise it. */
7794 if (!result)
7795 result = PyErr_SetFromWindowsErr(GetLastError());
7796
7797 CloseHandle(snapshot);
7798
7799 return result;
7800}
7801#endif /*MS_WINDOWS*/
7802
Larry Hastings2f936352014-08-05 14:04:04 +10007803
7804/*[clinic input]
7805os.getppid
7806
7807Return the parent's process id.
7808
7809If the parent process has already exited, Windows machines will still
7810return its id; others systems will return the id of the 'init' process (1).
7811[clinic start generated code]*/
7812
Larry Hastings2f936352014-08-05 14:04:04 +10007813static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007814os_getppid_impl(PyObject *module)
7815/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007816{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007817#ifdef MS_WINDOWS
7818 return win32_getppid();
7819#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007821#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007822}
7823#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007824
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007825
Fred Drake12c6e2d1999-12-14 21:25:03 +00007826#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007827/*[clinic input]
7828os.getlogin
7829
7830Return the actual login name.
7831[clinic start generated code]*/
7832
Larry Hastings2f936352014-08-05 14:04:04 +10007833static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007834os_getlogin_impl(PyObject *module)
7835/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007836{
Victor Stinner8c62be82010-05-06 00:08:46 +00007837 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007838#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007839 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007840 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007841
7842 if (GetUserNameW(user_name, &num_chars)) {
7843 /* num_chars is the number of unicode chars plus null terminator */
7844 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007845 }
7846 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007847 result = PyErr_SetFromWindowsErr(GetLastError());
7848#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007849 char *name;
7850 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007851
Victor Stinner8c62be82010-05-06 00:08:46 +00007852 errno = 0;
7853 name = getlogin();
7854 if (name == NULL) {
7855 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007856 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007857 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007858 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 }
7860 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007861 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007863#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007864 return result;
7865}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007866#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007867
Larry Hastings2f936352014-08-05 14:04:04 +10007868
Guido van Rossumad0ee831995-03-01 10:34:45 +00007869#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007870/*[clinic input]
7871os.getuid
7872
7873Return the current process's user id.
7874[clinic start generated code]*/
7875
Larry Hastings2f936352014-08-05 14:04:04 +10007876static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007877os_getuid_impl(PyObject *module)
7878/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007879{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007880 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007881}
Larry Hastings2f936352014-08-05 14:04:04 +10007882#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007883
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007884
Brian Curtineb24d742010-04-12 17:16:38 +00007885#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007886#define HAVE_KILL
7887#endif /* MS_WINDOWS */
7888
7889#ifdef HAVE_KILL
7890/*[clinic input]
7891os.kill
7892
7893 pid: pid_t
7894 signal: Py_ssize_t
7895 /
7896
7897Kill a process with a signal.
7898[clinic start generated code]*/
7899
Larry Hastings2f936352014-08-05 14:04:04 +10007900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007901os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7902/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007903{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007904 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7905 return NULL;
7906 }
7907#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007908 if (kill(pid, (int)signal) == -1)
7909 return posix_error();
7910 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007911#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007912 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007913 DWORD sig = (DWORD)signal;
7914 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007915 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007916
Victor Stinner8c62be82010-05-06 00:08:46 +00007917 /* Console processes which share a common console can be sent CTRL+C or
7918 CTRL+BREAK events, provided they handle said events. */
7919 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007920 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 err = GetLastError();
7922 PyErr_SetFromWindowsErr(err);
7923 }
7924 else
7925 Py_RETURN_NONE;
7926 }
Brian Curtineb24d742010-04-12 17:16:38 +00007927
Victor Stinner8c62be82010-05-06 00:08:46 +00007928 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7929 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007930 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 if (handle == NULL) {
7932 err = GetLastError();
7933 return PyErr_SetFromWindowsErr(err);
7934 }
Brian Curtineb24d742010-04-12 17:16:38 +00007935
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 if (TerminateProcess(handle, sig) == 0) {
7937 err = GetLastError();
7938 result = PyErr_SetFromWindowsErr(err);
7939 } else {
7940 Py_INCREF(Py_None);
7941 result = Py_None;
7942 }
Brian Curtineb24d742010-04-12 17:16:38 +00007943
Victor Stinner8c62be82010-05-06 00:08:46 +00007944 CloseHandle(handle);
7945 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007946#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007947}
Larry Hastings2f936352014-08-05 14:04:04 +10007948#endif /* HAVE_KILL */
7949
7950
7951#ifdef HAVE_KILLPG
7952/*[clinic input]
7953os.killpg
7954
7955 pgid: pid_t
7956 signal: int
7957 /
7958
7959Kill a process group with a signal.
7960[clinic start generated code]*/
7961
Larry Hastings2f936352014-08-05 14:04:04 +10007962static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007963os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7964/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007965{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007966 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7967 return NULL;
7968 }
Larry Hastings2f936352014-08-05 14:04:04 +10007969 /* XXX some man pages make the `pgid` parameter an int, others
7970 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7971 take the same type. Moreover, pid_t is always at least as wide as
7972 int (else compilation of this module fails), which is safe. */
7973 if (killpg(pgid, signal) == -1)
7974 return posix_error();
7975 Py_RETURN_NONE;
7976}
7977#endif /* HAVE_KILLPG */
7978
Brian Curtineb24d742010-04-12 17:16:38 +00007979
Guido van Rossumc0125471996-06-28 18:55:32 +00007980#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007981#ifdef HAVE_SYS_LOCK_H
7982#include <sys/lock.h>
7983#endif
7984
Larry Hastings2f936352014-08-05 14:04:04 +10007985/*[clinic input]
7986os.plock
7987 op: int
7988 /
7989
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007990Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007991[clinic start generated code]*/
7992
Larry Hastings2f936352014-08-05 14:04:04 +10007993static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007994os_plock_impl(PyObject *module, int op)
7995/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007996{
Victor Stinner8c62be82010-05-06 00:08:46 +00007997 if (plock(op) == -1)
7998 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007999 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00008000}
Larry Hastings2f936352014-08-05 14:04:04 +10008001#endif /* HAVE_PLOCK */
8002
Guido van Rossumc0125471996-06-28 18:55:32 +00008003
Guido van Rossumb6775db1994-08-01 11:34:53 +00008004#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10008005/*[clinic input]
8006os.setuid
8007
8008 uid: uid_t
8009 /
8010
8011Set the current process's user id.
8012[clinic start generated code]*/
8013
Larry Hastings2f936352014-08-05 14:04:04 +10008014static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008015os_setuid_impl(PyObject *module, uid_t uid)
8016/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008017{
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 if (setuid(uid) < 0)
8019 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008020 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008021}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008022#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008023
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008024
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008025#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10008026/*[clinic input]
8027os.seteuid
8028
8029 euid: uid_t
8030 /
8031
8032Set the current process's effective user id.
8033[clinic start generated code]*/
8034
Larry Hastings2f936352014-08-05 14:04:04 +10008035static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008036os_seteuid_impl(PyObject *module, uid_t euid)
8037/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008038{
8039 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008040 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008041 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008042}
8043#endif /* HAVE_SETEUID */
8044
Larry Hastings2f936352014-08-05 14:04:04 +10008045
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008046#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10008047/*[clinic input]
8048os.setegid
8049
8050 egid: gid_t
8051 /
8052
8053Set the current process's effective group id.
8054[clinic start generated code]*/
8055
Larry Hastings2f936352014-08-05 14:04:04 +10008056static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008057os_setegid_impl(PyObject *module, gid_t egid)
8058/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008059{
8060 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008061 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008062 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008063}
8064#endif /* HAVE_SETEGID */
8065
Larry Hastings2f936352014-08-05 14:04:04 +10008066
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008067#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10008068/*[clinic input]
8069os.setreuid
8070
8071 ruid: uid_t
8072 euid: uid_t
8073 /
8074
8075Set the current process's real and effective user ids.
8076[clinic start generated code]*/
8077
Larry Hastings2f936352014-08-05 14:04:04 +10008078static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008079os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
8080/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008081{
Victor Stinner8c62be82010-05-06 00:08:46 +00008082 if (setreuid(ruid, euid) < 0) {
8083 return posix_error();
8084 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008085 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00008086 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008087}
8088#endif /* HAVE_SETREUID */
8089
Larry Hastings2f936352014-08-05 14:04:04 +10008090
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008091#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10008092/*[clinic input]
8093os.setregid
8094
8095 rgid: gid_t
8096 egid: gid_t
8097 /
8098
8099Set the current process's real and effective group ids.
8100[clinic start generated code]*/
8101
Larry Hastings2f936352014-08-05 14:04:04 +10008102static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008103os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
8104/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008105{
8106 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008107 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008108 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008109}
8110#endif /* HAVE_SETREGID */
8111
Larry Hastings2f936352014-08-05 14:04:04 +10008112
Guido van Rossumb6775db1994-08-01 11:34:53 +00008113#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10008114/*[clinic input]
8115os.setgid
8116 gid: gid_t
8117 /
8118
8119Set the current process's group id.
8120[clinic start generated code]*/
8121
Larry Hastings2f936352014-08-05 14:04:04 +10008122static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008123os_setgid_impl(PyObject *module, gid_t gid)
8124/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008125{
Victor Stinner8c62be82010-05-06 00:08:46 +00008126 if (setgid(gid) < 0)
8127 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008128 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008129}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008130#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008131
Larry Hastings2f936352014-08-05 14:04:04 +10008132
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008133#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10008134/*[clinic input]
8135os.setgroups
8136
8137 groups: object
8138 /
8139
8140Set the groups of the current process to list.
8141[clinic start generated code]*/
8142
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008143static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008144os_setgroups(PyObject *module, PyObject *groups)
8145/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008146{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008147 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00008148 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00008149
Victor Stinner8c62be82010-05-06 00:08:46 +00008150 if (!PySequence_Check(groups)) {
8151 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
8152 return NULL;
8153 }
8154 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008155 if (len < 0) {
8156 return NULL;
8157 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008158 if (len > MAX_GROUPS) {
8159 PyErr_SetString(PyExc_ValueError, "too many groups");
8160 return NULL;
8161 }
8162 for(i = 0; i < len; i++) {
8163 PyObject *elem;
8164 elem = PySequence_GetItem(groups, i);
8165 if (!elem)
8166 return NULL;
8167 if (!PyLong_Check(elem)) {
8168 PyErr_SetString(PyExc_TypeError,
8169 "groups must be integers");
8170 Py_DECREF(elem);
8171 return NULL;
8172 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008173 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008174 Py_DECREF(elem);
8175 return NULL;
8176 }
8177 }
8178 Py_DECREF(elem);
8179 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008180
Victor Stinner8c62be82010-05-06 00:08:46 +00008181 if (setgroups(len, grouplist) < 0)
8182 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008183 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008184}
8185#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008186
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008187#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
8188static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008189wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008190{
Victor Stinner8c62be82010-05-06 00:08:46 +00008191 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08008192 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008193
Victor Stinner8c62be82010-05-06 00:08:46 +00008194 if (pid == -1)
8195 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008196
Zackery Spytz682107c2019-09-09 09:48:32 -06008197 // If wait succeeded but no child was ready to report status, ru will not
8198 // have been populated.
8199 if (pid == 0) {
8200 memset(ru, 0, sizeof(*ru));
8201 }
8202
Eddie Elizondob3966632019-11-05 07:16:14 -08008203 PyObject *m = PyImport_ImportModuleNoBlock("resource");
8204 if (m == NULL)
8205 return NULL;
Victor Stinner1c2fa782020-05-10 11:05:29 +02008206 struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08008207 Py_DECREF(m);
8208 if (struct_rusage == NULL)
8209 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008210
Victor Stinner8c62be82010-05-06 00:08:46 +00008211 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
8212 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08008213 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00008214 if (!result)
8215 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008216
8217#ifndef doubletime
8218#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
8219#endif
8220
Victor Stinner8c62be82010-05-06 00:08:46 +00008221 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008222 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00008223 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008224 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008225#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00008226 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
8227 SET_INT(result, 2, ru->ru_maxrss);
8228 SET_INT(result, 3, ru->ru_ixrss);
8229 SET_INT(result, 4, ru->ru_idrss);
8230 SET_INT(result, 5, ru->ru_isrss);
8231 SET_INT(result, 6, ru->ru_minflt);
8232 SET_INT(result, 7, ru->ru_majflt);
8233 SET_INT(result, 8, ru->ru_nswap);
8234 SET_INT(result, 9, ru->ru_inblock);
8235 SET_INT(result, 10, ru->ru_oublock);
8236 SET_INT(result, 11, ru->ru_msgsnd);
8237 SET_INT(result, 12, ru->ru_msgrcv);
8238 SET_INT(result, 13, ru->ru_nsignals);
8239 SET_INT(result, 14, ru->ru_nvcsw);
8240 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008241#undef SET_INT
8242
Victor Stinner8c62be82010-05-06 00:08:46 +00008243 if (PyErr_Occurred()) {
8244 Py_DECREF(result);
8245 return NULL;
8246 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008247
Victor Stinner8c62be82010-05-06 00:08:46 +00008248 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008249}
8250#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
8251
Larry Hastings2f936352014-08-05 14:04:04 +10008252
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008253#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10008254/*[clinic input]
8255os.wait3
8256
8257 options: int
8258Wait for completion of a child process.
8259
8260Returns a tuple of information about the child process:
8261 (pid, status, rusage)
8262[clinic start generated code]*/
8263
Larry Hastings2f936352014-08-05 14:04:04 +10008264static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008265os_wait3_impl(PyObject *module, int options)
8266/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008267{
Victor Stinner8c62be82010-05-06 00:08:46 +00008268 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008269 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008270 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008271 WAIT_TYPE status;
8272 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008273
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008274 do {
8275 Py_BEGIN_ALLOW_THREADS
8276 pid = wait3(&status, options, &ru);
8277 Py_END_ALLOW_THREADS
8278 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8279 if (pid < 0)
8280 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008281
Victor Stinner1c2fa782020-05-10 11:05:29 +02008282 return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008283}
8284#endif /* HAVE_WAIT3 */
8285
Larry Hastings2f936352014-08-05 14:04:04 +10008286
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008287#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10008288/*[clinic input]
8289
8290os.wait4
8291
8292 pid: pid_t
8293 options: int
8294
8295Wait for completion of a specific child process.
8296
8297Returns a tuple of information about the child process:
8298 (pid, status, rusage)
8299[clinic start generated code]*/
8300
Larry Hastings2f936352014-08-05 14:04:04 +10008301static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008302os_wait4_impl(PyObject *module, pid_t pid, int options)
8303/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008304{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008305 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008306 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008307 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008308 WAIT_TYPE status;
8309 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008310
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008311 do {
8312 Py_BEGIN_ALLOW_THREADS
8313 res = wait4(pid, &status, options, &ru);
8314 Py_END_ALLOW_THREADS
8315 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8316 if (res < 0)
8317 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008318
Victor Stinner1c2fa782020-05-10 11:05:29 +02008319 return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008320}
8321#endif /* HAVE_WAIT4 */
8322
Larry Hastings2f936352014-08-05 14:04:04 +10008323
Ross Lagerwall7807c352011-03-17 20:20:30 +02008324#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10008325/*[clinic input]
8326os.waitid
8327
8328 idtype: idtype_t
8329 Must be one of be P_PID, P_PGID or P_ALL.
8330 id: id_t
8331 The id to wait on.
8332 options: int
8333 Constructed from the ORing of one or more of WEXITED, WSTOPPED
8334 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
8335 /
8336
8337Returns the result of waiting for a process or processes.
8338
8339Returns either waitid_result or None if WNOHANG is specified and there are
8340no children in a waitable state.
8341[clinic start generated code]*/
8342
Larry Hastings2f936352014-08-05 14:04:04 +10008343static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008344os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
8345/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008346{
8347 PyObject *result;
8348 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008349 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008350 siginfo_t si;
8351 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008352
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008353 do {
8354 Py_BEGIN_ALLOW_THREADS
8355 res = waitid(idtype, id, &si, options);
8356 Py_END_ALLOW_THREADS
8357 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8358 if (res < 0)
8359 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008360
8361 if (si.si_pid == 0)
8362 Py_RETURN_NONE;
8363
Hai Shif707d942020-03-16 21:15:01 +08008364 PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008365 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008366 if (!result)
8367 return NULL;
8368
8369 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008370 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008371 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
8372 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
8373 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
8374 if (PyErr_Occurred()) {
8375 Py_DECREF(result);
8376 return NULL;
8377 }
8378
8379 return result;
8380}
Larry Hastings2f936352014-08-05 14:04:04 +10008381#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008382
Larry Hastings2f936352014-08-05 14:04:04 +10008383
8384#if defined(HAVE_WAITPID)
8385/*[clinic input]
8386os.waitpid
8387 pid: pid_t
8388 options: int
8389 /
8390
8391Wait for completion of a given child process.
8392
8393Returns a tuple of information regarding the child process:
8394 (pid, status)
8395
8396The options argument is ignored on Windows.
8397[clinic start generated code]*/
8398
Larry Hastings2f936352014-08-05 14:04:04 +10008399static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008400os_waitpid_impl(PyObject *module, pid_t pid, int options)
8401/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008402{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008403 pid_t res;
8404 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008405 WAIT_TYPE status;
8406 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008407
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008408 do {
8409 Py_BEGIN_ALLOW_THREADS
8410 res = waitpid(pid, &status, options);
8411 Py_END_ALLOW_THREADS
8412 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8413 if (res < 0)
8414 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008415
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008416 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00008417}
Tim Petersab034fa2002-02-01 11:27:43 +00008418#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00008419/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10008420/*[clinic input]
8421os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07008422 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10008423 options: int
8424 /
8425
8426Wait for completion of a given process.
8427
8428Returns a tuple of information regarding the process:
8429 (pid, status << 8)
8430
8431The options argument is ignored on Windows.
8432[clinic start generated code]*/
8433
Larry Hastings2f936352014-08-05 14:04:04 +10008434static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07008435os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07008436/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008437{
8438 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07008439 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008440 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008441
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008442 do {
8443 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08008444 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008445 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08008446 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008447 Py_END_ALLOW_THREADS
8448 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008449 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008450 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008451
Victor Stinner9bee32b2020-04-22 16:30:35 +02008452 unsigned long long ustatus = (unsigned int)status;
8453
Victor Stinner8c62be82010-05-06 00:08:46 +00008454 /* shift the status left a byte so this is more like the POSIX waitpid */
Victor Stinner9bee32b2020-04-22 16:30:35 +02008455 return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00008456}
Larry Hastings2f936352014-08-05 14:04:04 +10008457#endif
8458
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008459
Guido van Rossumad0ee831995-03-01 10:34:45 +00008460#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10008461/*[clinic input]
8462os.wait
8463
8464Wait for completion of a child process.
8465
8466Returns a tuple of information about the child process:
8467 (pid, status)
8468[clinic start generated code]*/
8469
Larry Hastings2f936352014-08-05 14:04:04 +10008470static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008471os_wait_impl(PyObject *module)
8472/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00008473{
Victor Stinner8c62be82010-05-06 00:08:46 +00008474 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008475 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008476 WAIT_TYPE status;
8477 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00008478
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008479 do {
8480 Py_BEGIN_ALLOW_THREADS
8481 pid = wait(&status);
8482 Py_END_ALLOW_THREADS
8483 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8484 if (pid < 0)
8485 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008486
Victor Stinner8c62be82010-05-06 00:08:46 +00008487 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00008488}
Larry Hastings2f936352014-08-05 14:04:04 +10008489#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008490
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08008491#if defined(__linux__) && defined(__NR_pidfd_open)
8492/*[clinic input]
8493os.pidfd_open
8494 pid: pid_t
8495 flags: unsigned_int = 0
8496
8497Return a file descriptor referring to the process *pid*.
8498
8499The descriptor can be used to perform process management without races and
8500signals.
8501[clinic start generated code]*/
8502
8503static PyObject *
8504os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8505/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8506{
8507 int fd = syscall(__NR_pidfd_open, pid, flags);
8508 if (fd < 0) {
8509 return posix_error();
8510 }
8511 return PyLong_FromLong(fd);
8512}
8513#endif
8514
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008515
Larry Hastings9cf065c2012-06-22 16:30:09 -07008516#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008517/*[clinic input]
8518os.readlink
8519
8520 path: path_t
8521 *
8522 dir_fd: dir_fd(requires='readlinkat') = None
8523
8524Return a string representing the path to which the symbolic link points.
8525
8526If dir_fd is not None, it should be a file descriptor open to a directory,
8527and path should be relative; path will then be relative to that directory.
8528
8529dir_fd may not be implemented on your platform. If it is unavailable,
8530using it will raise a NotImplementedError.
8531[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008532
Barry Warsaw53699e91996-12-10 23:23:01 +00008533static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008534os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8535/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008536{
Berker Peksage0b5b202018-08-15 13:03:41 +03008537#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008538 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008539 ssize_t length;
Ronald Oussoren41761932020-11-08 10:05:27 +01008540#ifdef HAVE_READLINKAT
8541 int readlinkat_unavailable = 0;
8542#endif
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008543
8544 Py_BEGIN_ALLOW_THREADS
8545#ifdef HAVE_READLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01008546 if (dir_fd != DEFAULT_DIR_FD) {
8547 if (HAVE_READLINKAT_RUNTIME) {
8548 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8549 } else {
8550 readlinkat_unavailable = 1;
8551 }
8552 } else
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008553#endif
8554 length = readlink(path->narrow, buffer, MAXPATHLEN);
8555 Py_END_ALLOW_THREADS
8556
Ronald Oussoren41761932020-11-08 10:05:27 +01008557#ifdef HAVE_READLINKAT
8558 if (readlinkat_unavailable) {
8559 argument_unavailable_error(NULL, "dir_fd");
8560 return NULL;
8561 }
8562#endif
8563
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008564 if (length < 0) {
8565 return path_error(path);
8566 }
8567 buffer[length] = '\0';
8568
8569 if (PyUnicode_Check(path->object))
8570 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8571 else
8572 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008573#elif defined(MS_WINDOWS)
8574 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008575 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008576 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008577 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8578 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008579 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008580
Larry Hastings2f936352014-08-05 14:04:04 +10008581 /* First get a handle to the reparse point */
8582 Py_BEGIN_ALLOW_THREADS
8583 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008584 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008585 0,
8586 0,
8587 0,
8588 OPEN_EXISTING,
8589 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8590 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008591 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8592 /* New call DeviceIoControl to read the reparse point */
8593 io_result = DeviceIoControl(
8594 reparse_point_handle,
8595 FSCTL_GET_REPARSE_POINT,
8596 0, 0, /* in buffer */
8597 target_buffer, sizeof(target_buffer),
8598 &n_bytes_returned,
8599 0 /* we're not using OVERLAPPED_IO */
8600 );
8601 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008602 }
Larry Hastings2f936352014-08-05 14:04:04 +10008603 Py_END_ALLOW_THREADS
8604
Berker Peksage0b5b202018-08-15 13:03:41 +03008605 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008606 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008607 }
Larry Hastings2f936352014-08-05 14:04:04 +10008608
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008609 wchar_t *name = NULL;
8610 Py_ssize_t nameLen = 0;
8611 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008612 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008613 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8614 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8615 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008616 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008617 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8618 {
8619 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8620 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8621 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8622 }
8623 else
8624 {
8625 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8626 }
8627 if (name) {
8628 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8629 /* Our buffer is mutable, so this is okay */
8630 name[1] = L'\\';
8631 }
8632 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008633 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008634 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8635 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008636 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008637 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008638#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008639}
Berker Peksage0b5b202018-08-15 13:03:41 +03008640#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008641
Larry Hastings9cf065c2012-06-22 16:30:09 -07008642#if defined(MS_WINDOWS)
8643
Steve Dower6921e732018-03-05 14:26:08 -08008644/* Remove the last portion of the path - return 0 on success */
8645static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008646_dirnameW(WCHAR *path)
8647{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008648 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008649 size_t length = wcsnlen_s(path, MAX_PATH);
8650 if (length == MAX_PATH) {
8651 return -1;
8652 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008653
8654 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008655 for(ptr = path + length; ptr != path; ptr--) {
8656 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008657 break;
Steve Dower6921e732018-03-05 14:26:08 -08008658 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008659 }
8660 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008661 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008662}
8663
Minmin Gong7f21c9a2020-05-18 09:17:19 -07008664#endif
8665
8666#ifdef HAVE_SYMLINK
8667
8668#if defined(MS_WINDOWS)
8669
Victor Stinner31b3b922013-06-05 01:49:17 +02008670/* Is this path absolute? */
8671static int
8672_is_absW(const WCHAR *path)
8673{
Steve Dower6921e732018-03-05 14:26:08 -08008674 return path[0] == L'\\' || path[0] == L'/' ||
8675 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008676}
8677
Steve Dower6921e732018-03-05 14:26:08 -08008678/* join root and rest with a backslash - return 0 on success */
8679static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008680_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8681{
Victor Stinner31b3b922013-06-05 01:49:17 +02008682 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008683 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008684 }
8685
Steve Dower6921e732018-03-05 14:26:08 -08008686 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8687 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008688 }
Steve Dower6921e732018-03-05 14:26:08 -08008689
8690 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8691 return -1;
8692 }
8693
8694 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008695}
8696
Victor Stinner31b3b922013-06-05 01:49:17 +02008697/* Return True if the path at src relative to dest is a directory */
8698static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008699_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008700{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008701 WIN32_FILE_ATTRIBUTE_DATA src_info;
8702 WCHAR dest_parent[MAX_PATH];
8703 WCHAR src_resolved[MAX_PATH] = L"";
8704
8705 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008706 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8707 _dirnameW(dest_parent)) {
8708 return 0;
8709 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008710 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008711 if (_joinW(src_resolved, dest_parent, src)) {
8712 return 0;
8713 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008714 return (
8715 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8716 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8717 );
8718}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008719#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008720
Larry Hastings2f936352014-08-05 14:04:04 +10008721
8722/*[clinic input]
8723os.symlink
8724 src: path_t
8725 dst: path_t
8726 target_is_directory: bool = False
8727 *
8728 dir_fd: dir_fd(requires='symlinkat')=None
8729
8730# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8731
8732Create a symbolic link pointing to src named dst.
8733
8734target_is_directory is required on Windows if the target is to be
8735 interpreted as a directory. (On Windows, symlink requires
8736 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8737 target_is_directory is ignored on non-Windows platforms.
8738
8739If dir_fd is not None, it should be a file descriptor open to a directory,
8740 and path should be relative; path will then be relative to that directory.
8741dir_fd may not be implemented on your platform.
8742 If it is unavailable, using it will raise a NotImplementedError.
8743
8744[clinic start generated code]*/
8745
Larry Hastings2f936352014-08-05 14:04:04 +10008746static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008747os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008748 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008749/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008750{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008751#ifdef MS_WINDOWS
8752 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008753 DWORD flags = 0;
8754
8755 /* Assumed true, set to false if detected to not be available. */
8756 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008757#else
8758 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01008759#ifdef HAVE_SYMLINKAT
8760 int symlinkat_unavailable = 0;
8761#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07008762#endif
8763
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008764 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8765 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8766 return NULL;
8767 }
8768
Larry Hastings9cf065c2012-06-22 16:30:09 -07008769#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008770
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008771 if (windows_has_symlink_unprivileged_flag) {
8772 /* Allow non-admin symlinks if system allows it. */
8773 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8774 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008775
Larry Hastings9cf065c2012-06-22 16:30:09 -07008776 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008777 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008778 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8779 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8780 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8781 }
8782
8783 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008784 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008785 Py_END_ALLOW_THREADS
8786
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008787 if (windows_has_symlink_unprivileged_flag && !result &&
8788 ERROR_INVALID_PARAMETER == GetLastError()) {
8789
8790 Py_BEGIN_ALLOW_THREADS
8791 _Py_BEGIN_SUPPRESS_IPH
8792 /* This error might be caused by
8793 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8794 Try again, and update windows_has_symlink_unprivileged_flag if we
8795 are successful this time.
8796
8797 NOTE: There is a risk of a race condition here if there are other
8798 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8799 another process (or thread) changes that condition in between our
8800 calls to CreateSymbolicLink.
8801 */
8802 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8803 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8804 _Py_END_SUPPRESS_IPH
8805 Py_END_ALLOW_THREADS
8806
8807 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8808 windows_has_symlink_unprivileged_flag = FALSE;
8809 }
8810 }
8811
Larry Hastings2f936352014-08-05 14:04:04 +10008812 if (!result)
8813 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008814
8815#else
8816
Steve Dower6921e732018-03-05 14:26:08 -08008817 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8818 PyErr_SetString(PyExc_ValueError,
8819 "symlink: src and dst must be the same type");
8820 return NULL;
8821 }
8822
Larry Hastings9cf065c2012-06-22 16:30:09 -07008823 Py_BEGIN_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01008824#ifdef HAVE_SYMLINKAT
8825 if (dir_fd != DEFAULT_DIR_FD) {
8826 if (HAVE_SYMLINKAT_RUNTIME) {
8827 result = symlinkat(src->narrow, dir_fd, dst->narrow);
8828 } else {
8829 symlinkat_unavailable = 1;
8830 }
8831 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008832#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008833 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008834 Py_END_ALLOW_THREADS
8835
Ronald Oussoren41761932020-11-08 10:05:27 +01008836#ifdef HAVE_SYMLINKAT
8837 if (symlinkat_unavailable) {
8838 argument_unavailable_error(NULL, "dir_fd");
8839 return NULL;
8840 }
8841#endif
8842
Larry Hastings2f936352014-08-05 14:04:04 +10008843 if (result)
8844 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008845#endif
8846
Larry Hastings2f936352014-08-05 14:04:04 +10008847 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008848}
8849#endif /* HAVE_SYMLINK */
8850
Larry Hastings9cf065c2012-06-22 16:30:09 -07008851
Brian Curtind40e6f72010-07-08 21:39:08 +00008852
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008853
Larry Hastings605a62d2012-06-24 04:33:36 -07008854static PyStructSequence_Field times_result_fields[] = {
8855 {"user", "user time"},
8856 {"system", "system time"},
8857 {"children_user", "user time of children"},
8858 {"children_system", "system time of children"},
8859 {"elapsed", "elapsed time since an arbitrary point in the past"},
8860 {NULL}
8861};
8862
8863PyDoc_STRVAR(times_result__doc__,
8864"times_result: Result from os.times().\n\n\
8865This object may be accessed either as a tuple of\n\
8866 (user, system, children_user, children_system, elapsed),\n\
8867or via the attributes user, system, children_user, children_system,\n\
8868and elapsed.\n\
8869\n\
8870See os.times for more information.");
8871
8872static PyStructSequence_Desc times_result_desc = {
8873 "times_result", /* name */
8874 times_result__doc__, /* doc */
8875 times_result_fields,
8876 5
8877};
8878
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008879#ifdef MS_WINDOWS
8880#define HAVE_TIMES /* mandatory, for the method table */
8881#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008882
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008883#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008884
8885static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008886build_times_result(PyObject *module, double user, double system,
Larry Hastings605a62d2012-06-24 04:33:36 -07008887 double children_user, double children_system,
8888 double elapsed)
8889{
Victor Stinner1c2fa782020-05-10 11:05:29 +02008890 PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008891 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008892 if (value == NULL)
8893 return NULL;
8894
8895#define SET(i, field) \
8896 { \
8897 PyObject *o = PyFloat_FromDouble(field); \
8898 if (!o) { \
8899 Py_DECREF(value); \
8900 return NULL; \
8901 } \
8902 PyStructSequence_SET_ITEM(value, i, o); \
8903 } \
8904
8905 SET(0, user);
8906 SET(1, system);
8907 SET(2, children_user);
8908 SET(3, children_system);
8909 SET(4, elapsed);
8910
8911#undef SET
8912
8913 return value;
8914}
8915
Larry Hastings605a62d2012-06-24 04:33:36 -07008916
Larry Hastings2f936352014-08-05 14:04:04 +10008917#ifndef MS_WINDOWS
8918#define NEED_TICKS_PER_SECOND
8919static long ticks_per_second = -1;
8920#endif /* MS_WINDOWS */
8921
8922/*[clinic input]
8923os.times
8924
8925Return a collection containing process timing information.
8926
8927The object returned behaves like a named tuple with these fields:
8928 (utime, stime, cutime, cstime, elapsed_time)
8929All fields are floating point numbers.
8930[clinic start generated code]*/
8931
Larry Hastings2f936352014-08-05 14:04:04 +10008932static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008933os_times_impl(PyObject *module)
8934/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008935#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008936{
Victor Stinner8c62be82010-05-06 00:08:46 +00008937 FILETIME create, exit, kernel, user;
8938 HANDLE hProc;
8939 hProc = GetCurrentProcess();
8940 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8941 /* The fields of a FILETIME structure are the hi and lo part
8942 of a 64-bit value expressed in 100 nanosecond units.
8943 1e7 is one second in such units; 1e-7 the inverse.
8944 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8945 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02008946 return build_times_result(module,
Victor Stinner8c62be82010-05-06 00:08:46 +00008947 (double)(user.dwHighDateTime*429.4967296 +
8948 user.dwLowDateTime*1e-7),
8949 (double)(kernel.dwHighDateTime*429.4967296 +
8950 kernel.dwLowDateTime*1e-7),
8951 (double)0,
8952 (double)0,
8953 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008954}
Larry Hastings2f936352014-08-05 14:04:04 +10008955#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008956{
Larry Hastings2f936352014-08-05 14:04:04 +10008957
8958
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008959 struct tms t;
8960 clock_t c;
8961 errno = 0;
8962 c = times(&t);
8963 if (c == (clock_t) -1)
8964 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02008965 return build_times_result(module,
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008966 (double)t.tms_utime / ticks_per_second,
8967 (double)t.tms_stime / ticks_per_second,
8968 (double)t.tms_cutime / ticks_per_second,
8969 (double)t.tms_cstime / ticks_per_second,
8970 (double)c / ticks_per_second);
8971}
Larry Hastings2f936352014-08-05 14:04:04 +10008972#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008973#endif /* HAVE_TIMES */
8974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008975
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008976#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008977/*[clinic input]
8978os.getsid
8979
8980 pid: pid_t
8981 /
8982
8983Call the system call getsid(pid) and return the result.
8984[clinic start generated code]*/
8985
Larry Hastings2f936352014-08-05 14:04:04 +10008986static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008987os_getsid_impl(PyObject *module, pid_t pid)
8988/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008989{
Victor Stinner8c62be82010-05-06 00:08:46 +00008990 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 sid = getsid(pid);
8992 if (sid < 0)
8993 return posix_error();
8994 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008995}
8996#endif /* HAVE_GETSID */
8997
8998
Guido van Rossumb6775db1994-08-01 11:34:53 +00008999#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10009000/*[clinic input]
9001os.setsid
9002
9003Call the system call setsid().
9004[clinic start generated code]*/
9005
Larry Hastings2f936352014-08-05 14:04:04 +10009006static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009007os_setsid_impl(PyObject *module)
9008/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00009009{
Victor Stinner8c62be82010-05-06 00:08:46 +00009010 if (setsid() < 0)
9011 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009012 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00009013}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009014#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00009015
Larry Hastings2f936352014-08-05 14:04:04 +10009016
Guido van Rossumb6775db1994-08-01 11:34:53 +00009017#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10009018/*[clinic input]
9019os.setpgid
9020
9021 pid: pid_t
9022 pgrp: pid_t
9023 /
9024
9025Call the system call setpgid(pid, pgrp).
9026[clinic start generated code]*/
9027
Larry Hastings2f936352014-08-05 14:04:04 +10009028static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009029os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
9030/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009031{
Victor Stinner8c62be82010-05-06 00:08:46 +00009032 if (setpgid(pid, pgrp) < 0)
9033 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009034 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00009035}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009036#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00009037
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009038
Guido van Rossumb6775db1994-08-01 11:34:53 +00009039#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10009040/*[clinic input]
9041os.tcgetpgrp
9042
9043 fd: int
9044 /
9045
9046Return the process group associated with the terminal specified by fd.
9047[clinic start generated code]*/
9048
Larry Hastings2f936352014-08-05 14:04:04 +10009049static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009050os_tcgetpgrp_impl(PyObject *module, int fd)
9051/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009052{
9053 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00009054 if (pgid < 0)
9055 return posix_error();
9056 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00009057}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009058#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00009059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009060
Guido van Rossumb6775db1994-08-01 11:34:53 +00009061#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10009062/*[clinic input]
9063os.tcsetpgrp
9064
9065 fd: int
9066 pgid: pid_t
9067 /
9068
9069Set the process group associated with the terminal specified by fd.
9070[clinic start generated code]*/
9071
Larry Hastings2f936352014-08-05 14:04:04 +10009072static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009073os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
9074/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009075{
Victor Stinner8c62be82010-05-06 00:08:46 +00009076 if (tcsetpgrp(fd, pgid) < 0)
9077 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009078 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00009079}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009080#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00009081
Guido van Rossum687dd131993-05-17 08:34:16 +00009082/* Functions acting on file descriptors */
9083
Victor Stinnerdaf45552013-08-28 00:53:59 +02009084#ifdef O_CLOEXEC
9085extern int _Py_open_cloexec_works;
9086#endif
9087
Larry Hastings2f936352014-08-05 14:04:04 +10009088
9089/*[clinic input]
9090os.open -> int
9091 path: path_t
9092 flags: int
9093 mode: int = 0o777
9094 *
9095 dir_fd: dir_fd(requires='openat') = None
9096
9097# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
9098
9099Open a file for low level IO. Returns a file descriptor (integer).
9100
9101If dir_fd is not None, it should be a file descriptor open to a directory,
9102 and path should be relative; path will then be relative to that directory.
9103dir_fd may not be implemented on your platform.
9104 If it is unavailable, using it will raise a NotImplementedError.
9105[clinic start generated code]*/
9106
Larry Hastings2f936352014-08-05 14:04:04 +10009107static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009108os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
9109/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009110{
9111 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009112 int async_err = 0;
Ronald Oussoren41761932020-11-08 10:05:27 +01009113#ifdef HAVE_OPENAT
9114 int openat_unavailable = 0;
9115#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009116
Victor Stinnerdaf45552013-08-28 00:53:59 +02009117#ifdef O_CLOEXEC
9118 int *atomic_flag_works = &_Py_open_cloexec_works;
9119#elif !defined(MS_WINDOWS)
9120 int *atomic_flag_works = NULL;
9121#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00009122
Victor Stinnerdaf45552013-08-28 00:53:59 +02009123#ifdef MS_WINDOWS
9124 flags |= O_NOINHERIT;
9125#elif defined(O_CLOEXEC)
9126 flags |= O_CLOEXEC;
9127#endif
9128
Steve Dowerb82e17e2019-05-23 08:45:22 -07009129 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
9130 return -1;
9131 }
9132
Steve Dower8fc89802015-04-12 00:26:27 -04009133 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009134 do {
9135 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07009136#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009137 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009138#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07009139#ifdef HAVE_OPENAT
Ronald Oussoren41761932020-11-08 10:05:27 +01009140 if (dir_fd != DEFAULT_DIR_FD) {
9141 if (HAVE_OPENAT_RUNTIME) {
9142 fd = openat(dir_fd, path->narrow, flags, mode);
9143
9144 } else {
9145 openat_unavailable = 1;
9146 fd = -1;
9147 }
9148 } else
Steve Dower6230aaf2016-09-09 09:03:15 -07009149#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009150 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009151#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009152 Py_END_ALLOW_THREADS
9153 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009154 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00009155
Ronald Oussoren41761932020-11-08 10:05:27 +01009156#ifdef HAVE_OPENAT
9157 if (openat_unavailable) {
9158 argument_unavailable_error(NULL, "dir_fd");
9159 return -1;
9160 }
9161#endif
9162
Victor Stinnerd3ffd322015-09-15 10:11:03 +02009163 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009164 if (!async_err)
9165 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10009166 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009167 }
9168
Victor Stinnerdaf45552013-08-28 00:53:59 +02009169#ifndef MS_WINDOWS
9170 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
9171 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10009172 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009173 }
9174#endif
9175
Larry Hastings2f936352014-08-05 14:04:04 +10009176 return fd;
9177}
9178
9179
9180/*[clinic input]
9181os.close
9182
9183 fd: int
9184
9185Close a file descriptor.
9186[clinic start generated code]*/
9187
Barry Warsaw53699e91996-12-10 23:23:01 +00009188static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009189os_close_impl(PyObject *module, int fd)
9190/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009191{
Larry Hastings2f936352014-08-05 14:04:04 +10009192 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009193 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
9194 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
9195 * for more details.
9196 */
Victor Stinner8c62be82010-05-06 00:08:46 +00009197 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009198 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009199 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04009200 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009201 Py_END_ALLOW_THREADS
9202 if (res < 0)
9203 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009204 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00009205}
9206
Larry Hastings2f936352014-08-05 14:04:04 +10009207/*[clinic input]
9208os.closerange
9209
9210 fd_low: int
9211 fd_high: int
9212 /
9213
9214Closes all file descriptors in [fd_low, fd_high), ignoring errors.
9215[clinic start generated code]*/
9216
Larry Hastings2f936352014-08-05 14:04:04 +10009217static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009218os_closerange_impl(PyObject *module, int fd_low, int fd_high)
9219/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009220{
Victor Stinner8c62be82010-05-06 00:08:46 +00009221 Py_BEGIN_ALLOW_THREADS
Kyle Evansc230fde2020-10-11 13:54:11 -05009222 _Py_closerange(fd_low, fd_high - 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00009223 Py_END_ALLOW_THREADS
9224 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00009225}
9226
9227
Larry Hastings2f936352014-08-05 14:04:04 +10009228/*[clinic input]
9229os.dup -> int
9230
9231 fd: int
9232 /
9233
9234Return a duplicate of a file descriptor.
9235[clinic start generated code]*/
9236
Larry Hastings2f936352014-08-05 14:04:04 +10009237static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009238os_dup_impl(PyObject *module, int fd)
9239/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009240{
9241 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00009242}
9243
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009244
Larry Hastings2f936352014-08-05 14:04:04 +10009245/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009246os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10009247 fd: int
9248 fd2: int
9249 inheritable: bool=True
9250
9251Duplicate file descriptor.
9252[clinic start generated code]*/
9253
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009254static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009255os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009256/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009257{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01009258 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009259#if defined(HAVE_DUP3) && \
9260 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
9261 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03009262 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009263#endif
9264
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009265 if (fd < 0 || fd2 < 0) {
9266 posix_error();
9267 return -1;
9268 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009269
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009270 /* dup2() can fail with EINTR if the target FD is already open, because it
9271 * then has to be closed. See os_close_impl() for why we don't handle EINTR
9272 * upon close(), and therefore below.
9273 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02009274#ifdef MS_WINDOWS
9275 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009276 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009277 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04009278 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009279 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009280 if (res < 0) {
9281 posix_error();
9282 return -1;
9283 }
9284 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02009285
9286 /* Character files like console cannot be make non-inheritable */
9287 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9288 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009289 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009290 }
9291
9292#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
9293 Py_BEGIN_ALLOW_THREADS
9294 if (!inheritable)
9295 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
9296 else
9297 res = dup2(fd, fd2);
9298 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009299 if (res < 0) {
9300 posix_error();
9301 return -1;
9302 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009303
9304#else
9305
9306#ifdef HAVE_DUP3
9307 if (!inheritable && dup3_works != 0) {
9308 Py_BEGIN_ALLOW_THREADS
9309 res = dup3(fd, fd2, O_CLOEXEC);
9310 Py_END_ALLOW_THREADS
9311 if (res < 0) {
9312 if (dup3_works == -1)
9313 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009314 if (dup3_works) {
9315 posix_error();
9316 return -1;
9317 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009318 }
9319 }
9320
9321 if (inheritable || dup3_works == 0)
9322 {
9323#endif
9324 Py_BEGIN_ALLOW_THREADS
9325 res = dup2(fd, fd2);
9326 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009327 if (res < 0) {
9328 posix_error();
9329 return -1;
9330 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009331
9332 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9333 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009334 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009335 }
9336#ifdef HAVE_DUP3
9337 }
9338#endif
9339
9340#endif
9341
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009342 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00009343}
9344
Larry Hastings2f936352014-08-05 14:04:04 +10009345
Ross Lagerwall7807c352011-03-17 20:20:30 +02009346#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10009347/*[clinic input]
9348os.lockf
9349
9350 fd: int
9351 An open file descriptor.
9352 command: int
9353 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
9354 length: Py_off_t
9355 The number of bytes to lock, starting at the current position.
9356 /
9357
9358Apply, test or remove a POSIX lock on an open file descriptor.
9359
9360[clinic start generated code]*/
9361
Larry Hastings2f936352014-08-05 14:04:04 +10009362static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009363os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
9364/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009365{
9366 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009367
Saiyang Gou7514f4f2020-02-12 23:47:42 -08009368 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
9369 return NULL;
9370 }
9371
Ross Lagerwall7807c352011-03-17 20:20:30 +02009372 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009373 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009374 Py_END_ALLOW_THREADS
9375
9376 if (res < 0)
9377 return posix_error();
9378
9379 Py_RETURN_NONE;
9380}
Larry Hastings2f936352014-08-05 14:04:04 +10009381#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009382
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009383
Larry Hastings2f936352014-08-05 14:04:04 +10009384/*[clinic input]
9385os.lseek -> Py_off_t
9386
9387 fd: int
9388 position: Py_off_t
9389 how: int
9390 /
9391
9392Set the position of a file descriptor. Return the new position.
9393
9394Return the new cursor position in number of bytes
9395relative to the beginning of the file.
9396[clinic start generated code]*/
9397
Larry Hastings2f936352014-08-05 14:04:04 +10009398static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009399os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
9400/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009401{
9402 Py_off_t result;
9403
Guido van Rossum687dd131993-05-17 08:34:16 +00009404#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00009405 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
9406 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10009407 case 0: how = SEEK_SET; break;
9408 case 1: how = SEEK_CUR; break;
9409 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00009410 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009411#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009412
Victor Stinner8c62be82010-05-06 00:08:46 +00009413 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009414 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02009415#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009416 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009417#else
Larry Hastings2f936352014-08-05 14:04:04 +10009418 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009419#endif
Steve Dower8fc89802015-04-12 00:26:27 -04009420 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009421 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009422 if (result < 0)
9423 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00009424
Larry Hastings2f936352014-08-05 14:04:04 +10009425 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00009426}
9427
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009428
Larry Hastings2f936352014-08-05 14:04:04 +10009429/*[clinic input]
9430os.read
9431 fd: int
9432 length: Py_ssize_t
9433 /
9434
9435Read from a file descriptor. Returns a bytes object.
9436[clinic start generated code]*/
9437
Larry Hastings2f936352014-08-05 14:04:04 +10009438static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009439os_read_impl(PyObject *module, int fd, Py_ssize_t length)
9440/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009441{
Victor Stinner8c62be82010-05-06 00:08:46 +00009442 Py_ssize_t n;
9443 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10009444
9445 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009446 errno = EINVAL;
9447 return posix_error();
9448 }
Larry Hastings2f936352014-08-05 14:04:04 +10009449
Victor Stinner9a0d7a72018-11-22 15:03:40 +01009450 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10009451
9452 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00009453 if (buffer == NULL)
9454 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009455
Victor Stinner66aab0c2015-03-19 22:53:20 +01009456 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
9457 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009458 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01009459 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009460 }
Larry Hastings2f936352014-08-05 14:04:04 +10009461
9462 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10009464
Victor Stinner8c62be82010-05-06 00:08:46 +00009465 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00009466}
9467
Ross Lagerwall7807c352011-03-17 20:20:30 +02009468#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009469 || defined(__APPLE__))) \
9470 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
9471 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9472static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009473iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009474{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009475 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009476
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009477 *iov = PyMem_New(struct iovec, cnt);
9478 if (*iov == NULL) {
9479 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009480 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009481 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009482
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009483 *buf = PyMem_New(Py_buffer, cnt);
9484 if (*buf == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01009485 PyMem_Free(*iov);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009486 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009487 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009488 }
9489
9490 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009491 PyObject *item = PySequence_GetItem(seq, i);
9492 if (item == NULL)
9493 goto fail;
9494 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
9495 Py_DECREF(item);
9496 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009497 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009498 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009499 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009500 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009501 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009502 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009503
9504fail:
Victor Stinner00d7abd2020-12-01 09:56:42 +01009505 PyMem_Free(*iov);
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009506 for (j = 0; j < i; j++) {
9507 PyBuffer_Release(&(*buf)[j]);
9508 }
Victor Stinner00d7abd2020-12-01 09:56:42 +01009509 PyMem_Free(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01009510 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009511}
9512
9513static void
9514iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9515{
9516 int i;
Victor Stinner00d7abd2020-12-01 09:56:42 +01009517 PyMem_Free(iov);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009518 for (i = 0; i < cnt; i++) {
9519 PyBuffer_Release(&buf[i]);
9520 }
Victor Stinner00d7abd2020-12-01 09:56:42 +01009521 PyMem_Free(buf);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009522}
9523#endif
9524
Larry Hastings2f936352014-08-05 14:04:04 +10009525
Ross Lagerwall7807c352011-03-17 20:20:30 +02009526#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10009527/*[clinic input]
9528os.readv -> Py_ssize_t
9529
9530 fd: int
9531 buffers: object
9532 /
9533
9534Read from a file descriptor fd into an iterable of buffers.
9535
9536The buffers should be mutable buffers accepting bytes.
9537readv will transfer data into each buffer until it is full
9538and then move on to the next buffer in the sequence to hold
9539the rest of the data.
9540
9541readv returns the total number of bytes read,
9542which may be less than the total capacity of all the buffers.
9543[clinic start generated code]*/
9544
Larry Hastings2f936352014-08-05 14:04:04 +10009545static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009546os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9547/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009548{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009549 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009550 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009551 struct iovec *iov;
9552 Py_buffer *buf;
9553
Larry Hastings2f936352014-08-05 14:04:04 +10009554 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009555 PyErr_SetString(PyExc_TypeError,
9556 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009557 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009558 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009559
Larry Hastings2f936352014-08-05 14:04:04 +10009560 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009561 if (cnt < 0)
9562 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009563
9564 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9565 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009566
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009567 do {
9568 Py_BEGIN_ALLOW_THREADS
9569 n = readv(fd, iov, cnt);
9570 Py_END_ALLOW_THREADS
9571 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009572
9573 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009574 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009575 if (!async_err)
9576 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009577 return -1;
9578 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009579
Larry Hastings2f936352014-08-05 14:04:04 +10009580 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009581}
Larry Hastings2f936352014-08-05 14:04:04 +10009582#endif /* HAVE_READV */
9583
Ross Lagerwall7807c352011-03-17 20:20:30 +02009584
9585#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009586/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009587os.pread
9588
9589 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009590 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009591 offset: Py_off_t
9592 /
9593
9594Read a number of bytes from a file descriptor starting at a particular offset.
9595
9596Read length bytes from file descriptor fd, starting at offset bytes from
9597the beginning of the file. The file offset remains unchanged.
9598[clinic start generated code]*/
9599
Larry Hastings2f936352014-08-05 14:04:04 +10009600static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009601os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9602/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009603{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009604 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009605 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009606 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009607
Larry Hastings2f936352014-08-05 14:04:04 +10009608 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009609 errno = EINVAL;
9610 return posix_error();
9611 }
Larry Hastings2f936352014-08-05 14:04:04 +10009612 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009613 if (buffer == NULL)
9614 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009615
9616 do {
9617 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009618 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009619 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009620 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009621 Py_END_ALLOW_THREADS
9622 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9623
Ross Lagerwall7807c352011-03-17 20:20:30 +02009624 if (n < 0) {
9625 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009626 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009627 }
Larry Hastings2f936352014-08-05 14:04:04 +10009628 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009629 _PyBytes_Resize(&buffer, n);
9630 return buffer;
9631}
Larry Hastings2f936352014-08-05 14:04:04 +10009632#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009633
Pablo Galindo4defba32018-01-27 16:16:37 +00009634#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9635/*[clinic input]
9636os.preadv -> Py_ssize_t
9637
9638 fd: int
9639 buffers: object
9640 offset: Py_off_t
9641 flags: int = 0
9642 /
9643
9644Reads from a file descriptor into a number of mutable bytes-like objects.
9645
9646Combines the functionality of readv() and pread(). As readv(), it will
9647transfer data into each buffer until it is full and then move on to the next
9648buffer in the sequence to hold the rest of the data. Its fourth argument,
9649specifies the file offset at which the input operation is to be performed. It
9650will return the total number of bytes read (which can be less than the total
9651capacity of all the objects).
9652
9653The flags argument contains a bitwise OR of zero or more of the following flags:
9654
9655- RWF_HIPRI
9656- RWF_NOWAIT
9657
9658Using non-zero flags requires Linux 4.6 or newer.
9659[clinic start generated code]*/
9660
9661static Py_ssize_t
9662os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9663 int flags)
9664/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9665{
9666 Py_ssize_t cnt, n;
9667 int async_err = 0;
9668 struct iovec *iov;
9669 Py_buffer *buf;
9670
9671 if (!PySequence_Check(buffers)) {
9672 PyErr_SetString(PyExc_TypeError,
9673 "preadv2() arg 2 must be a sequence");
9674 return -1;
9675 }
9676
9677 cnt = PySequence_Size(buffers);
9678 if (cnt < 0) {
9679 return -1;
9680 }
9681
9682#ifndef HAVE_PREADV2
9683 if(flags != 0) {
9684 argument_unavailable_error("preadv2", "flags");
9685 return -1;
9686 }
9687#endif
9688
9689 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9690 return -1;
9691 }
9692#ifdef HAVE_PREADV2
9693 do {
9694 Py_BEGIN_ALLOW_THREADS
9695 _Py_BEGIN_SUPPRESS_IPH
9696 n = preadv2(fd, iov, cnt, offset, flags);
9697 _Py_END_SUPPRESS_IPH
9698 Py_END_ALLOW_THREADS
9699 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9700#else
9701 do {
Ronald Oussoren41761932020-11-08 10:05:27 +01009702#ifdef __APPLE__
9703/* This entire function will be removed from the module dict when the API
9704 * is not available.
9705 */
9706#pragma clang diagnostic push
9707#pragma clang diagnostic ignored "-Wunguarded-availability"
9708#pragma clang diagnostic ignored "-Wunguarded-availability-new"
9709#endif
Pablo Galindo4defba32018-01-27 16:16:37 +00009710 Py_BEGIN_ALLOW_THREADS
9711 _Py_BEGIN_SUPPRESS_IPH
9712 n = preadv(fd, iov, cnt, offset);
9713 _Py_END_SUPPRESS_IPH
9714 Py_END_ALLOW_THREADS
9715 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussoren41761932020-11-08 10:05:27 +01009716
9717#ifdef __APPLE__
9718#pragma clang diagnostic pop
9719#endif
9720
Pablo Galindo4defba32018-01-27 16:16:37 +00009721#endif
9722
9723 iov_cleanup(iov, buf, cnt);
9724 if (n < 0) {
9725 if (!async_err) {
9726 posix_error();
9727 }
9728 return -1;
9729 }
9730
9731 return n;
9732}
9733#endif /* HAVE_PREADV */
9734
Larry Hastings2f936352014-08-05 14:04:04 +10009735
9736/*[clinic input]
9737os.write -> Py_ssize_t
9738
9739 fd: int
9740 data: Py_buffer
9741 /
9742
9743Write a bytes object to a file descriptor.
9744[clinic start generated code]*/
9745
Larry Hastings2f936352014-08-05 14:04:04 +10009746static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009747os_write_impl(PyObject *module, int fd, Py_buffer *data)
9748/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009749{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009750 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009751}
9752
9753#ifdef HAVE_SENDFILE
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009754#ifdef __APPLE__
9755/*[clinic input]
9756os.sendfile
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009757
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009758 out_fd: int
9759 in_fd: int
9760 offset: Py_off_t
9761 count as sbytes: Py_off_t
9762 headers: object(c_default="NULL") = ()
9763 trailers: object(c_default="NULL") = ()
9764 flags: int = 0
9765
9766Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9767[clinic start generated code]*/
9768
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009769static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009770os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9771 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9772 int flags)
9773/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9774#elif defined(__FreeBSD__) || defined(__DragonFly__)
9775/*[clinic input]
9776os.sendfile
9777
9778 out_fd: int
9779 in_fd: int
9780 offset: Py_off_t
9781 count: Py_ssize_t
9782 headers: object(c_default="NULL") = ()
9783 trailers: object(c_default="NULL") = ()
9784 flags: int = 0
9785
9786Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9787[clinic start generated code]*/
9788
9789static PyObject *
9790os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9791 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9792 int flags)
9793/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9794#else
9795/*[clinic input]
9796os.sendfile
9797
9798 out_fd: int
9799 in_fd: int
9800 offset as offobj: object
9801 count: Py_ssize_t
9802
9803Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9804[clinic start generated code]*/
9805
9806static PyObject *
9807os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9808 Py_ssize_t count)
9809/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9810#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009811{
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009812 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009813 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009814
9815#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9816#ifndef __APPLE__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009817 off_t sbytes;
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009818#endif
9819 Py_buffer *hbuf, *tbuf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009820 struct sf_hdtr sf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009821
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009822 sf.headers = NULL;
9823 sf.trailers = NULL;
9824
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009825 if (headers != NULL) {
9826 if (!PySequence_Check(headers)) {
9827 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009828 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009829 return NULL;
9830 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009831 Py_ssize_t i = PySequence_Size(headers);
9832 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009833 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009834 if (i > INT_MAX) {
9835 PyErr_SetString(PyExc_OverflowError,
9836 "sendfile() header is too large");
9837 return NULL;
9838 }
9839 if (i > 0) {
9840 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009841 if (iov_setup(&(sf.headers), &hbuf,
9842 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009843 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009844#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009845 for (i = 0; i < sf.hdr_cnt; i++) {
9846 Py_ssize_t blen = sf.headers[i].iov_len;
9847# define OFF_T_MAX 0x7fffffffffffffff
9848 if (sbytes >= OFF_T_MAX - blen) {
9849 PyErr_SetString(PyExc_OverflowError,
9850 "sendfile() header is too large");
9851 return NULL;
9852 }
9853 sbytes += blen;
9854 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009855#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009856 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009857 }
9858 }
9859 if (trailers != NULL) {
9860 if (!PySequence_Check(trailers)) {
9861 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009862 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009863 return NULL;
9864 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009865 Py_ssize_t i = PySequence_Size(trailers);
9866 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009867 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009868 if (i > INT_MAX) {
9869 PyErr_SetString(PyExc_OverflowError,
9870 "sendfile() trailer is too large");
9871 return NULL;
9872 }
9873 if (i > 0) {
9874 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009875 if (iov_setup(&(sf.trailers), &tbuf,
9876 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009877 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009878 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009879 }
9880 }
9881
Steve Dower8fc89802015-04-12 00:26:27 -04009882 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009883 do {
9884 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009885#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009886 ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009887#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009888 ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009889#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009890 Py_END_ALLOW_THREADS
9891 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009892 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009893
9894 if (sf.headers != NULL)
9895 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9896 if (sf.trailers != NULL)
9897 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9898
9899 if (ret < 0) {
9900 if ((errno == EAGAIN) || (errno == EBUSY)) {
9901 if (sbytes != 0) {
9902 // some data has been sent
9903 goto done;
9904 }
9905 else {
9906 // no data has been sent; upper application is supposed
9907 // to retry on EAGAIN or EBUSY
9908 return posix_error();
9909 }
9910 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009911 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009912 }
9913 goto done;
9914
9915done:
9916 #if !defined(HAVE_LARGEFILE_SUPPORT)
9917 return Py_BuildValue("l", sbytes);
9918 #else
9919 return Py_BuildValue("L", sbytes);
9920 #endif
9921
9922#else
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009923#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009924 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009925 do {
9926 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009927 ret = sendfile(out_fd, in_fd, NULL, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009928 Py_END_ALLOW_THREADS
9929 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009930 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009931 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009932 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009933 }
9934#endif
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009935 off_t offset;
Larry Hastings2f936352014-08-05 14:04:04 +10009936 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009937 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009938
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009939#if defined(__sun) && defined(__SVR4)
9940 // On Solaris, sendfile raises EINVAL rather than returning 0
9941 // when the offset is equal or bigger than the in_fd size.
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009942 struct stat st;
9943
9944 do {
9945 Py_BEGIN_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009946 ret = fstat(in_fd, &st);
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009947 Py_END_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009948 } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009949 if (ret < 0)
9950 return (!async_err) ? posix_error() : NULL;
9951
9952 if (offset >= st.st_size) {
9953 return Py_BuildValue("i", 0);
9954 }
Jakub Stasiakfd4ed572020-11-12 10:49:30 +01009955
9956 // On illumos specifically sendfile() may perform a partial write but
9957 // return -1/an error (in one confirmed case the destination socket
9958 // had a 5 second timeout set and errno was EAGAIN) and it's on the client
9959 // code to check if the offset parameter was modified by sendfile().
9960 //
9961 // We need this variable to track said change.
9962 off_t original_offset = offset;
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009963#endif
9964
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009965 do {
9966 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009967 ret = sendfile(out_fd, in_fd, &offset, count);
Jakub Stasiakfd4ed572020-11-12 10:49:30 +01009968#if defined(__sun) && defined(__SVR4)
9969 // This handles illumos-specific sendfile() partial write behavior,
9970 // see a comment above for more details.
9971 if (ret < 0 && offset != original_offset) {
9972 ret = offset - original_offset;
9973 }
9974#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009975 Py_END_ALLOW_THREADS
9976 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009977 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009978 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009979 return Py_BuildValue("n", ret);
9980#endif
9981}
Larry Hastings2f936352014-08-05 14:04:04 +10009982#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009983
Larry Hastings2f936352014-08-05 14:04:04 +10009984
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009985#if defined(__APPLE__)
9986/*[clinic input]
9987os._fcopyfile
9988
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009989 in_fd: int
9990 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009991 flags: int
9992 /
9993
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009994Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009995[clinic start generated code]*/
9996
9997static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009998os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9999/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020010000{
10001 int ret;
10002
10003 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +030010004 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020010005 Py_END_ALLOW_THREADS
10006 if (ret < 0)
10007 return posix_error();
10008 Py_RETURN_NONE;
10009}
10010#endif
10011
10012
Larry Hastings2f936352014-08-05 14:04:04 +100010013/*[clinic input]
10014os.fstat
10015
10016 fd : int
10017
10018Perform a stat system call on the given file descriptor.
10019
10020Like stat(), but for an open file descriptor.
10021Equivalent to os.stat(fd).
10022[clinic start generated code]*/
10023
Larry Hastings2f936352014-08-05 14:04:04 +100010024static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010025os_fstat_impl(PyObject *module, int fd)
10026/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010027{
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 STRUCT_STAT st;
10029 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010030 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010031
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010032 do {
10033 Py_BEGIN_ALLOW_THREADS
10034 res = FSTAT(fd, &st);
10035 Py_END_ALLOW_THREADS
10036 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +000010038#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +010010039 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +000010040#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010041 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +000010042#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 }
Tim Peters5aa91602002-01-30 05:46:57 +000010044
Victor Stinner1c2fa782020-05-10 11:05:29 +020010045 return _pystat_fromstructstat(module, &st);
Guido van Rossum687dd131993-05-17 08:34:16 +000010046}
10047
Larry Hastings2f936352014-08-05 14:04:04 +100010048
10049/*[clinic input]
10050os.isatty -> bool
10051 fd: int
10052 /
10053
10054Return True if the fd is connected to a terminal.
10055
10056Return True if the file descriptor is an open file descriptor
10057connected to the slave end of a terminal.
10058[clinic start generated code]*/
10059
Larry Hastings2f936352014-08-05 14:04:04 +100010060static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010061os_isatty_impl(PyObject *module, int fd)
10062/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010063{
Steve Dower8fc89802015-04-12 00:26:27 -040010064 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040010065 _Py_BEGIN_SUPPRESS_IPH
10066 return_value = isatty(fd);
10067 _Py_END_SUPPRESS_IPH
10068 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100010069}
10070
10071
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010072#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +100010073/*[clinic input]
10074os.pipe
10075
10076Create a pipe.
10077
10078Returns a tuple of two file descriptors:
10079 (read_fd, write_fd)
10080[clinic start generated code]*/
10081
Larry Hastings2f936352014-08-05 14:04:04 +100010082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010083os_pipe_impl(PyObject *module)
10084/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +000010085{
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +020010087#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010089 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010091#else
10092 int res;
10093#endif
10094
10095#ifdef MS_WINDOWS
10096 attr.nLength = sizeof(attr);
10097 attr.lpSecurityDescriptor = NULL;
10098 attr.bInheritHandle = FALSE;
10099
10100 Py_BEGIN_ALLOW_THREADS
10101 ok = CreatePipe(&read, &write, &attr, 0);
10102 if (ok) {
Segev Finer5e437fb2021-04-24 01:00:27 +030010103 fds[0] = _Py_open_osfhandle_noraise(read, _O_RDONLY);
10104 fds[1] = _Py_open_osfhandle_noraise(write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010105 if (fds[0] == -1 || fds[1] == -1) {
10106 CloseHandle(read);
10107 CloseHandle(write);
10108 ok = 0;
10109 }
10110 }
10111 Py_END_ALLOW_THREADS
10112
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +010010114 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010115#else
10116
10117#ifdef HAVE_PIPE2
10118 Py_BEGIN_ALLOW_THREADS
10119 res = pipe2(fds, O_CLOEXEC);
10120 Py_END_ALLOW_THREADS
10121
10122 if (res != 0 && errno == ENOSYS)
10123 {
10124#endif
10125 Py_BEGIN_ALLOW_THREADS
10126 res = pipe(fds);
10127 Py_END_ALLOW_THREADS
10128
10129 if (res == 0) {
10130 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
10131 close(fds[0]);
10132 close(fds[1]);
10133 return NULL;
10134 }
10135 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
10136 close(fds[0]);
10137 close(fds[1]);
10138 return NULL;
10139 }
10140 }
10141#ifdef HAVE_PIPE2
10142 }
10143#endif
10144
10145 if (res != 0)
10146 return PyErr_SetFromErrno(PyExc_OSError);
10147#endif /* !MS_WINDOWS */
10148 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +000010149}
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010150#endif /* HAVE_PIPE */
10151
Larry Hastings2f936352014-08-05 14:04:04 +100010152
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010153#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +100010154/*[clinic input]
10155os.pipe2
10156
10157 flags: int
10158 /
10159
10160Create a pipe with flags set atomically.
10161
10162Returns a tuple of two file descriptors:
10163 (read_fd, write_fd)
10164
10165flags can be constructed by ORing together one or more of these values:
10166O_NONBLOCK, O_CLOEXEC.
10167[clinic start generated code]*/
10168
Larry Hastings2f936352014-08-05 14:04:04 +100010169static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010170os_pipe2_impl(PyObject *module, int flags)
10171/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010172{
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010173 int fds[2];
10174 int res;
10175
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010176 res = pipe2(fds, flags);
10177 if (res != 0)
10178 return posix_error();
10179 return Py_BuildValue("(ii)", fds[0], fds[1]);
10180}
10181#endif /* HAVE_PIPE2 */
10182
Larry Hastings2f936352014-08-05 14:04:04 +100010183
Ross Lagerwall7807c352011-03-17 20:20:30 +020010184#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +100010185/*[clinic input]
10186os.writev -> Py_ssize_t
10187 fd: int
10188 buffers: object
10189 /
10190
10191Iterate over buffers, and write the contents of each to a file descriptor.
10192
10193Returns the total number of bytes written.
10194buffers must be a sequence of bytes-like objects.
10195[clinic start generated code]*/
10196
Larry Hastings2f936352014-08-05 14:04:04 +100010197static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010198os_writev_impl(PyObject *module, int fd, PyObject *buffers)
10199/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010200{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010201 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +100010202 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010203 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010204 struct iovec *iov;
10205 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +100010206
10207 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020010208 PyErr_SetString(PyExc_TypeError,
10209 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +100010210 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010211 }
Larry Hastings2f936352014-08-05 14:04:04 +100010212 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010213 if (cnt < 0)
10214 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010215
Larry Hastings2f936352014-08-05 14:04:04 +100010216 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10217 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010218 }
10219
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010220 do {
10221 Py_BEGIN_ALLOW_THREADS
10222 result = writev(fd, iov, cnt);
10223 Py_END_ALLOW_THREADS
10224 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +020010225
10226 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010227 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010228 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +010010229
Georg Brandl306336b2012-06-24 12:55:33 +020010230 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010231}
Larry Hastings2f936352014-08-05 14:04:04 +100010232#endif /* HAVE_WRITEV */
10233
10234
10235#ifdef HAVE_PWRITE
10236/*[clinic input]
10237os.pwrite -> Py_ssize_t
10238
10239 fd: int
10240 buffer: Py_buffer
10241 offset: Py_off_t
10242 /
10243
10244Write bytes to a file descriptor starting at a particular offset.
10245
10246Write buffer to fd, starting at offset bytes from the beginning of
10247the file. Returns the number of bytes writte. Does not change the
10248current file offset.
10249[clinic start generated code]*/
10250
Larry Hastings2f936352014-08-05 14:04:04 +100010251static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010252os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
10253/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010254{
10255 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010256 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010257
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010258 do {
10259 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -040010260 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010261 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -040010262 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010263 Py_END_ALLOW_THREADS
10264 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010265
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010266 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010267 posix_error();
10268 return size;
10269}
10270#endif /* HAVE_PWRITE */
10271
Pablo Galindo4defba32018-01-27 16:16:37 +000010272#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
10273/*[clinic input]
10274os.pwritev -> Py_ssize_t
10275
10276 fd: int
10277 buffers: object
10278 offset: Py_off_t
10279 flags: int = 0
10280 /
10281
10282Writes the contents of bytes-like objects to a file descriptor at a given offset.
10283
10284Combines the functionality of writev() and pwrite(). All buffers must be a sequence
10285of bytes-like objects. Buffers are processed in array order. Entire contents of first
10286buffer is written before proceeding to second, and so on. The operating system may
10287set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
10288This function writes the contents of each object to the file descriptor and returns
10289the total number of bytes written.
10290
10291The flags argument contains a bitwise OR of zero or more of the following flags:
10292
10293- RWF_DSYNC
10294- RWF_SYNC
YoSTEALTH76ef2552020-05-27 15:32:22 -060010295- RWF_APPEND
Pablo Galindo4defba32018-01-27 16:16:37 +000010296
10297Using non-zero flags requires Linux 4.7 or newer.
10298[clinic start generated code]*/
10299
10300static Py_ssize_t
10301os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
10302 int flags)
YoSTEALTH76ef2552020-05-27 15:32:22 -060010303/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=35358c327e1a2a8e]*/
Pablo Galindo4defba32018-01-27 16:16:37 +000010304{
10305 Py_ssize_t cnt;
10306 Py_ssize_t result;
10307 int async_err = 0;
10308 struct iovec *iov;
10309 Py_buffer *buf;
10310
10311 if (!PySequence_Check(buffers)) {
10312 PyErr_SetString(PyExc_TypeError,
10313 "pwritev() arg 2 must be a sequence");
10314 return -1;
10315 }
10316
10317 cnt = PySequence_Size(buffers);
10318 if (cnt < 0) {
10319 return -1;
10320 }
10321
10322#ifndef HAVE_PWRITEV2
10323 if(flags != 0) {
10324 argument_unavailable_error("pwritev2", "flags");
10325 return -1;
10326 }
10327#endif
10328
10329 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10330 return -1;
10331 }
10332#ifdef HAVE_PWRITEV2
10333 do {
10334 Py_BEGIN_ALLOW_THREADS
10335 _Py_BEGIN_SUPPRESS_IPH
10336 result = pwritev2(fd, iov, cnt, offset, flags);
10337 _Py_END_SUPPRESS_IPH
10338 Py_END_ALLOW_THREADS
10339 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10340#else
Ronald Oussoren41761932020-11-08 10:05:27 +010010341
10342#ifdef __APPLE__
10343/* This entire function will be removed from the module dict when the API
10344 * is not available.
10345 */
10346#pragma clang diagnostic push
10347#pragma clang diagnostic ignored "-Wunguarded-availability"
10348#pragma clang diagnostic ignored "-Wunguarded-availability-new"
10349#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000010350 do {
10351 Py_BEGIN_ALLOW_THREADS
10352 _Py_BEGIN_SUPPRESS_IPH
10353 result = pwritev(fd, iov, cnt, offset);
10354 _Py_END_SUPPRESS_IPH
10355 Py_END_ALLOW_THREADS
10356 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussoren41761932020-11-08 10:05:27 +010010357
10358#ifdef __APPLE__
10359#pragma clang diagnostic pop
10360#endif
10361
Pablo Galindo4defba32018-01-27 16:16:37 +000010362#endif
10363
10364 iov_cleanup(iov, buf, cnt);
10365 if (result < 0) {
10366 if (!async_err) {
10367 posix_error();
10368 }
10369 return -1;
10370 }
10371
10372 return result;
10373}
10374#endif /* HAVE_PWRITEV */
10375
Pablo Galindoaac4d032019-05-31 19:39:47 +010010376#ifdef HAVE_COPY_FILE_RANGE
10377/*[clinic input]
10378
10379os.copy_file_range
10380 src: int
10381 Source file descriptor.
10382 dst: int
10383 Destination file descriptor.
10384 count: Py_ssize_t
10385 Number of bytes to copy.
10386 offset_src: object = None
10387 Starting offset in src.
10388 offset_dst: object = None
10389 Starting offset in dst.
10390
10391Copy count bytes from one file descriptor to another.
10392
10393If offset_src is None, then src is read from the current position;
10394respectively for offset_dst.
10395[clinic start generated code]*/
10396
10397static PyObject *
10398os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10399 PyObject *offset_src, PyObject *offset_dst)
10400/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
10401{
10402 off_t offset_src_val, offset_dst_val;
10403 off_t *p_offset_src = NULL;
10404 off_t *p_offset_dst = NULL;
10405 Py_ssize_t ret;
10406 int async_err = 0;
10407 /* The flags argument is provided to allow
10408 * for future extensions and currently must be to 0. */
10409 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +000010410
10411
Pablo Galindoaac4d032019-05-31 19:39:47 +010010412 if (count < 0) {
10413 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10414 return NULL;
10415 }
10416
10417 if (offset_src != Py_None) {
10418 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10419 return NULL;
10420 }
10421 p_offset_src = &offset_src_val;
10422 }
10423
10424 if (offset_dst != Py_None) {
10425 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10426 return NULL;
10427 }
10428 p_offset_dst = &offset_dst_val;
10429 }
10430
10431 do {
10432 Py_BEGIN_ALLOW_THREADS
10433 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
10434 Py_END_ALLOW_THREADS
10435 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10436
10437 if (ret < 0) {
10438 return (!async_err) ? posix_error() : NULL;
10439 }
10440
10441 return PyLong_FromSsize_t(ret);
10442}
10443#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +100010444
Pablo Galindodedc2cd2020-12-02 17:57:18 +000010445#if (defined(HAVE_SPLICE) && !defined(_AIX))
Pablo Galindoa57b3d32020-11-17 00:00:38 +000010446/*[clinic input]
10447
10448os.splice
10449 src: int
10450 Source file descriptor.
10451 dst: int
10452 Destination file descriptor.
10453 count: Py_ssize_t
10454 Number of bytes to copy.
10455 offset_src: object = None
10456 Starting offset in src.
10457 offset_dst: object = None
10458 Starting offset in dst.
10459 flags: unsigned_int = 0
10460 Flags to modify the semantics of the call.
10461
10462Transfer count bytes from one pipe to a descriptor or vice versa.
10463
10464If offset_src is None, then src is read from the current position;
10465respectively for offset_dst. The offset associated to the file
10466descriptor that refers to a pipe must be None.
10467[clinic start generated code]*/
10468
10469static PyObject *
10470os_splice_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10471 PyObject *offset_src, PyObject *offset_dst,
10472 unsigned int flags)
10473/*[clinic end generated code: output=d0386f25a8519dc5 input=047527c66c6d2e0a]*/
10474{
10475 off_t offset_src_val, offset_dst_val;
10476 off_t *p_offset_src = NULL;
10477 off_t *p_offset_dst = NULL;
10478 Py_ssize_t ret;
10479 int async_err = 0;
10480
10481 if (count < 0) {
10482 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10483 return NULL;
10484 }
10485
10486 if (offset_src != Py_None) {
10487 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10488 return NULL;
10489 }
10490 p_offset_src = &offset_src_val;
10491 }
10492
10493 if (offset_dst != Py_None) {
10494 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10495 return NULL;
10496 }
10497 p_offset_dst = &offset_dst_val;
10498 }
10499
10500 do {
10501 Py_BEGIN_ALLOW_THREADS
10502 ret = splice(src, p_offset_src, dst, p_offset_dst, count, flags);
10503 Py_END_ALLOW_THREADS
10504 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10505
10506 if (ret < 0) {
10507 return (!async_err) ? posix_error() : NULL;
10508 }
10509
10510 return PyLong_FromSsize_t(ret);
10511}
10512#endif /* HAVE_SPLICE*/
10513
Larry Hastings2f936352014-08-05 14:04:04 +100010514#ifdef HAVE_MKFIFO
10515/*[clinic input]
10516os.mkfifo
10517
10518 path: path_t
10519 mode: int=0o666
10520 *
10521 dir_fd: dir_fd(requires='mkfifoat')=None
10522
10523Create a "fifo" (a POSIX named pipe).
10524
10525If dir_fd is not None, it should be a file descriptor open to a directory,
10526 and path should be relative; path will then be relative to that directory.
10527dir_fd may not be implemented on your platform.
10528 If it is unavailable, using it will raise a NotImplementedError.
10529[clinic start generated code]*/
10530
Larry Hastings2f936352014-08-05 14:04:04 +100010531static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010532os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
10533/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010534{
10535 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010536 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010537
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010538 do {
10539 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010540#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010541 if (dir_fd != DEFAULT_DIR_FD)
10542 result = mkfifoat(dir_fd, path->narrow, mode);
10543 else
Ross Lagerwall7807c352011-03-17 20:20:30 +020010544#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010545 result = mkfifo(path->narrow, mode);
10546 Py_END_ALLOW_THREADS
10547 } while (result != 0 && errno == EINTR &&
10548 !(async_err = PyErr_CheckSignals()));
10549 if (result != 0)
10550 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010551
10552 Py_RETURN_NONE;
10553}
10554#endif /* HAVE_MKFIFO */
10555
10556
10557#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
10558/*[clinic input]
10559os.mknod
10560
10561 path: path_t
10562 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010563 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +100010564 *
10565 dir_fd: dir_fd(requires='mknodat')=None
10566
10567Create a node in the file system.
10568
10569Create a node in the file system (file, device special file or named pipe)
10570at path. mode specifies both the permissions to use and the
10571type of node to be created, being combined (bitwise OR) with one of
10572S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
10573device defines the newly created device special file (probably using
10574os.makedev()). Otherwise device is ignored.
10575
10576If dir_fd is not None, it should be a file descriptor open to a directory,
10577 and path should be relative; path will then be relative to that directory.
10578dir_fd may not be implemented on your platform.
10579 If it is unavailable, using it will raise a NotImplementedError.
10580[clinic start generated code]*/
10581
Larry Hastings2f936352014-08-05 14:04:04 +100010582static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010583os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -040010584 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010585/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010586{
10587 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010588 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010589
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010590 do {
10591 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010592#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010593 if (dir_fd != DEFAULT_DIR_FD)
10594 result = mknodat(dir_fd, path->narrow, mode, device);
10595 else
Larry Hastings2f936352014-08-05 14:04:04 +100010596#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010597 result = mknod(path->narrow, mode, device);
10598 Py_END_ALLOW_THREADS
10599 } while (result != 0 && errno == EINTR &&
10600 !(async_err = PyErr_CheckSignals()));
10601 if (result != 0)
10602 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010603
10604 Py_RETURN_NONE;
10605}
10606#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10607
10608
10609#ifdef HAVE_DEVICE_MACROS
10610/*[clinic input]
10611os.major -> unsigned_int
10612
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010613 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010614 /
10615
10616Extracts a device major number from a raw device number.
10617[clinic start generated code]*/
10618
Larry Hastings2f936352014-08-05 14:04:04 +100010619static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010620os_major_impl(PyObject *module, dev_t device)
10621/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010622{
10623 return major(device);
10624}
10625
10626
10627/*[clinic input]
10628os.minor -> unsigned_int
10629
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010630 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010631 /
10632
10633Extracts a device minor number from a raw device number.
10634[clinic start generated code]*/
10635
Larry Hastings2f936352014-08-05 14:04:04 +100010636static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010637os_minor_impl(PyObject *module, dev_t device)
10638/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010639{
10640 return minor(device);
10641}
10642
10643
10644/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010645os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010646
10647 major: int
10648 minor: int
10649 /
10650
10651Composes a raw device number from the major and minor device numbers.
10652[clinic start generated code]*/
10653
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010654static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010655os_makedev_impl(PyObject *module, int major, int minor)
10656/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010657{
10658 return makedev(major, minor);
10659}
10660#endif /* HAVE_DEVICE_MACROS */
10661
10662
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010663#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010664/*[clinic input]
10665os.ftruncate
10666
10667 fd: int
10668 length: Py_off_t
10669 /
10670
10671Truncate a file, specified by file descriptor, to a specific length.
10672[clinic start generated code]*/
10673
Larry Hastings2f936352014-08-05 14:04:04 +100010674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010675os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10676/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010677{
10678 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010679 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010680
Steve Dowerb82e17e2019-05-23 08:45:22 -070010681 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
10682 return NULL;
10683 }
10684
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010685 do {
10686 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010687 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010688#ifdef MS_WINDOWS
10689 result = _chsize_s(fd, length);
10690#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010691 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010692#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010693 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010694 Py_END_ALLOW_THREADS
10695 } while (result != 0 && errno == EINTR &&
10696 !(async_err = PyErr_CheckSignals()));
10697 if (result != 0)
10698 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010699 Py_RETURN_NONE;
10700}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010701#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010702
10703
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010704#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010705/*[clinic input]
10706os.truncate
10707 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10708 length: Py_off_t
10709
10710Truncate a file, specified by path, to a specific length.
10711
10712On some platforms, path may also be specified as an open file descriptor.
10713 If this functionality is unavailable, using it raises an exception.
10714[clinic start generated code]*/
10715
Larry Hastings2f936352014-08-05 14:04:04 +100010716static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010717os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10718/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010719{
10720 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010721#ifdef MS_WINDOWS
10722 int fd;
10723#endif
10724
10725 if (path->fd != -1)
10726 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010727
Steve Dowerb82e17e2019-05-23 08:45:22 -070010728 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10729 return NULL;
10730 }
10731
Larry Hastings2f936352014-08-05 14:04:04 +100010732 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010733 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010734#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010735 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010736 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010737 result = -1;
10738 else {
10739 result = _chsize_s(fd, length);
10740 close(fd);
10741 if (result < 0)
10742 errno = result;
10743 }
10744#else
10745 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010746#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010747 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010748 Py_END_ALLOW_THREADS
10749 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010750 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010751
10752 Py_RETURN_NONE;
10753}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010754#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010755
Ross Lagerwall7807c352011-03-17 20:20:30 +020010756
Victor Stinnerd6b17692014-09-30 12:20:05 +020010757/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10758 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10759 defined, which is the case in Python on AIX. AIX bug report:
10760 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10761#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10762# define POSIX_FADVISE_AIX_BUG
10763#endif
10764
Victor Stinnerec39e262014-09-30 12:35:58 +020010765
Victor Stinnerd6b17692014-09-30 12:20:05 +020010766#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010767/*[clinic input]
10768os.posix_fallocate
10769
10770 fd: int
10771 offset: Py_off_t
10772 length: Py_off_t
10773 /
10774
10775Ensure a file has allocated at least a particular number of bytes on disk.
10776
10777Ensure that the file specified by fd encompasses a range of bytes
10778starting at offset bytes from the beginning and continuing for length bytes.
10779[clinic start generated code]*/
10780
Larry Hastings2f936352014-08-05 14:04:04 +100010781static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010782os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010783 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010784/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010785{
10786 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010787 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010788
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010789 do {
10790 Py_BEGIN_ALLOW_THREADS
10791 result = posix_fallocate(fd, offset, length);
10792 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010793 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10794
10795 if (result == 0)
10796 Py_RETURN_NONE;
10797
10798 if (async_err)
10799 return NULL;
10800
10801 errno = result;
10802 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010803}
Victor Stinnerec39e262014-09-30 12:35:58 +020010804#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010805
Ross Lagerwall7807c352011-03-17 20:20:30 +020010806
Victor Stinnerd6b17692014-09-30 12:20:05 +020010807#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010808/*[clinic input]
10809os.posix_fadvise
10810
10811 fd: int
10812 offset: Py_off_t
10813 length: Py_off_t
10814 advice: int
10815 /
10816
10817Announce an intention to access data in a specific pattern.
10818
10819Announce an intention to access data in a specific pattern, thus allowing
10820the kernel to make optimizations.
10821The advice applies to the region of the file specified by fd starting at
10822offset and continuing for length bytes.
10823advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10824POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10825POSIX_FADV_DONTNEED.
10826[clinic start generated code]*/
10827
Larry Hastings2f936352014-08-05 14:04:04 +100010828static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010829os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010830 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010831/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010832{
10833 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010834 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010835
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010836 do {
10837 Py_BEGIN_ALLOW_THREADS
10838 result = posix_fadvise(fd, offset, length, advice);
10839 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010840 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10841
10842 if (result == 0)
10843 Py_RETURN_NONE;
10844
10845 if (async_err)
10846 return NULL;
10847
10848 errno = result;
10849 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010850}
Victor Stinnerec39e262014-09-30 12:35:58 +020010851#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010852
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010853
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010854#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010855static PyObject*
10856win32_putenv(PyObject *name, PyObject *value)
10857{
10858 /* Search from index 1 because on Windows starting '=' is allowed for
10859 defining hidden environment variables. */
10860 if (PyUnicode_GET_LENGTH(name) == 0 ||
10861 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10862 {
10863 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10864 return NULL;
10865 }
10866 PyObject *unicode;
10867 if (value != NULL) {
10868 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10869 }
10870 else {
10871 unicode = PyUnicode_FromFormat("%U=", name);
10872 }
10873 if (unicode == NULL) {
10874 return NULL;
10875 }
10876
10877 Py_ssize_t size;
10878 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10879 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10880 Py_DECREF(unicode);
10881
10882 if (env == NULL) {
10883 return NULL;
10884 }
10885 if (size > _MAX_ENV) {
10886 PyErr_Format(PyExc_ValueError,
10887 "the environment variable is longer than %u characters",
10888 _MAX_ENV);
10889 PyMem_Free(env);
10890 return NULL;
10891 }
10892
10893 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10894 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10895 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10896
10897 Prefer _wputenv() to be compatible with C libraries using CRT
10898 variables and CRT functions using these variables (ex: getenv()). */
10899 int err = _wputenv(env);
10900 PyMem_Free(env);
10901
10902 if (err) {
10903 posix_error();
10904 return NULL;
10905 }
10906
10907 Py_RETURN_NONE;
10908}
10909#endif
10910
10911
10912#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010913/*[clinic input]
10914os.putenv
10915
10916 name: unicode
10917 value: unicode
10918 /
10919
10920Change or add an environment variable.
10921[clinic start generated code]*/
10922
Larry Hastings2f936352014-08-05 14:04:04 +100010923static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010924os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10925/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010926{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010927 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10928 return NULL;
10929 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010930 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010931}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010932#else
Larry Hastings2f936352014-08-05 14:04:04 +100010933/*[clinic input]
10934os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010935
Larry Hastings2f936352014-08-05 14:04:04 +100010936 name: FSConverter
10937 value: FSConverter
10938 /
10939
10940Change or add an environment variable.
10941[clinic start generated code]*/
10942
Larry Hastings2f936352014-08-05 14:04:04 +100010943static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010944os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10945/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010946{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010947 const char *name_string = PyBytes_AS_STRING(name);
10948 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010949
Serhiy Storchaka77703942017-06-25 07:33:01 +030010950 if (strchr(name_string, '=') != NULL) {
10951 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10952 return NULL;
10953 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010954
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010955 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10956 return NULL;
10957 }
10958
Victor Stinnerb477d192020-01-22 22:48:16 +010010959 if (setenv(name_string, value_string, 1)) {
10960 return posix_error();
10961 }
Larry Hastings2f936352014-08-05 14:04:04 +100010962 Py_RETURN_NONE;
10963}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010964#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010965
10966
Victor Stinner161e7b32020-01-24 11:53:44 +010010967#ifdef MS_WINDOWS
10968/*[clinic input]
10969os.unsetenv
10970 name: unicode
10971 /
10972
10973Delete an environment variable.
10974[clinic start generated code]*/
10975
10976static PyObject *
10977os_unsetenv_impl(PyObject *module, PyObject *name)
10978/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10979{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010980 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10981 return NULL;
10982 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010983 return win32_putenv(name, NULL);
10984}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010985#else
Larry Hastings2f936352014-08-05 14:04:04 +100010986/*[clinic input]
10987os.unsetenv
10988 name: FSConverter
10989 /
10990
10991Delete an environment variable.
10992[clinic start generated code]*/
10993
Larry Hastings2f936352014-08-05 14:04:04 +100010994static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010995os_unsetenv_impl(PyObject *module, PyObject *name)
10996/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010997{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010998 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10999 return NULL;
11000 }
Victor Stinner984890f2011-11-24 13:53:38 +010011001#ifdef HAVE_BROKEN_UNSETENV
11002 unsetenv(PyBytes_AS_STRING(name));
11003#else
Victor Stinner161e7b32020-01-24 11:53:44 +010011004 int err = unsetenv(PyBytes_AS_STRING(name));
11005 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010011006 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010011007 }
Victor Stinner984890f2011-11-24 13:53:38 +010011008#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011009
Victor Stinner84ae1182010-05-06 22:05:07 +000011010 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000011011}
Victor Stinnerb8d12622020-01-24 14:05:48 +010011012#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000011013
Larry Hastings2f936352014-08-05 14:04:04 +100011014
11015/*[clinic input]
11016os.strerror
11017
11018 code: int
11019 /
11020
11021Translate an error code to a message string.
11022[clinic start generated code]*/
11023
Larry Hastings2f936352014-08-05 14:04:04 +100011024static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011025os_strerror_impl(PyObject *module, int code)
11026/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011027{
11028 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 if (message == NULL) {
11030 PyErr_SetString(PyExc_ValueError,
11031 "strerror() argument out of range");
11032 return NULL;
11033 }
Victor Stinner1b579672011-12-17 05:47:23 +010011034 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000011035}
Guido van Rossumb6a47161997-09-15 22:54:34 +000011036
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011037
Guido van Rossumc9641791998-08-04 15:26:23 +000011038#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011039#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100011040/*[clinic input]
11041os.WCOREDUMP -> bool
11042
11043 status: int
11044 /
11045
11046Return True if the process returning status was dumped to a core file.
11047[clinic start generated code]*/
11048
Larry Hastings2f936352014-08-05 14:04:04 +100011049static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011050os_WCOREDUMP_impl(PyObject *module, int status)
11051/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011052{
11053 WAIT_TYPE wait_status;
11054 WAIT_STATUS_INT(wait_status) = status;
11055 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000011056}
11057#endif /* WCOREDUMP */
11058
Larry Hastings2f936352014-08-05 14:04:04 +100011059
Fred Drake106c1a02002-04-23 15:58:02 +000011060#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100011061/*[clinic input]
11062os.WIFCONTINUED -> bool
11063
11064 status: int
11065
11066Return True if a particular process was continued from a job control stop.
11067
11068Return True if the process returning status was continued from a
11069job control stop.
11070[clinic start generated code]*/
11071
Larry Hastings2f936352014-08-05 14:04:04 +100011072static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011073os_WIFCONTINUED_impl(PyObject *module, int status)
11074/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011075{
11076 WAIT_TYPE wait_status;
11077 WAIT_STATUS_INT(wait_status) = status;
11078 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000011079}
11080#endif /* WIFCONTINUED */
11081
Larry Hastings2f936352014-08-05 14:04:04 +100011082
Guido van Rossumc9641791998-08-04 15:26:23 +000011083#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100011084/*[clinic input]
11085os.WIFSTOPPED -> bool
11086
11087 status: int
11088
11089Return True if the process returning status was stopped.
11090[clinic start generated code]*/
11091
Larry Hastings2f936352014-08-05 14:04:04 +100011092static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011093os_WIFSTOPPED_impl(PyObject *module, int status)
11094/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011095{
11096 WAIT_TYPE wait_status;
11097 WAIT_STATUS_INT(wait_status) = status;
11098 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011099}
11100#endif /* WIFSTOPPED */
11101
Larry Hastings2f936352014-08-05 14:04:04 +100011102
Guido van Rossumc9641791998-08-04 15:26:23 +000011103#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100011104/*[clinic input]
11105os.WIFSIGNALED -> bool
11106
11107 status: int
11108
11109Return True if the process returning status was terminated by a signal.
11110[clinic start generated code]*/
11111
Larry Hastings2f936352014-08-05 14:04:04 +100011112static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011113os_WIFSIGNALED_impl(PyObject *module, int status)
11114/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011115{
11116 WAIT_TYPE wait_status;
11117 WAIT_STATUS_INT(wait_status) = status;
11118 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011119}
11120#endif /* WIFSIGNALED */
11121
Larry Hastings2f936352014-08-05 14:04:04 +100011122
Guido van Rossumc9641791998-08-04 15:26:23 +000011123#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100011124/*[clinic input]
11125os.WIFEXITED -> bool
11126
11127 status: int
11128
11129Return True if the process returning status exited via the exit() system call.
11130[clinic start generated code]*/
11131
Larry Hastings2f936352014-08-05 14:04:04 +100011132static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011133os_WIFEXITED_impl(PyObject *module, int status)
11134/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011135{
11136 WAIT_TYPE wait_status;
11137 WAIT_STATUS_INT(wait_status) = status;
11138 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011139}
11140#endif /* WIFEXITED */
11141
Larry Hastings2f936352014-08-05 14:04:04 +100011142
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000011143#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100011144/*[clinic input]
11145os.WEXITSTATUS -> int
11146
11147 status: int
11148
11149Return the process return code from status.
11150[clinic start generated code]*/
11151
Larry Hastings2f936352014-08-05 14:04:04 +100011152static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011153os_WEXITSTATUS_impl(PyObject *module, int status)
11154/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011155{
11156 WAIT_TYPE wait_status;
11157 WAIT_STATUS_INT(wait_status) = status;
11158 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011159}
11160#endif /* WEXITSTATUS */
11161
Larry Hastings2f936352014-08-05 14:04:04 +100011162
Guido van Rossumc9641791998-08-04 15:26:23 +000011163#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011164/*[clinic input]
11165os.WTERMSIG -> int
11166
11167 status: int
11168
11169Return the signal that terminated the process that provided the status value.
11170[clinic start generated code]*/
11171
Larry Hastings2f936352014-08-05 14:04:04 +100011172static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011173os_WTERMSIG_impl(PyObject *module, int status)
11174/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011175{
11176 WAIT_TYPE wait_status;
11177 WAIT_STATUS_INT(wait_status) = status;
11178 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011179}
11180#endif /* WTERMSIG */
11181
Larry Hastings2f936352014-08-05 14:04:04 +100011182
Guido van Rossumc9641791998-08-04 15:26:23 +000011183#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011184/*[clinic input]
11185os.WSTOPSIG -> int
11186
11187 status: int
11188
11189Return the signal that stopped the process that provided the status value.
11190[clinic start generated code]*/
11191
Larry Hastings2f936352014-08-05 14:04:04 +100011192static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011193os_WSTOPSIG_impl(PyObject *module, int status)
11194/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011195{
11196 WAIT_TYPE wait_status;
11197 WAIT_STATUS_INT(wait_status) = status;
11198 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011199}
11200#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000011201#endif /* HAVE_SYS_WAIT_H */
11202
11203
Thomas Wouters477c8d52006-05-27 19:21:47 +000011204#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000011205#ifdef _SCO_DS
11206/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
11207 needed definitions in sys/statvfs.h */
11208#define _SVID3
11209#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011210#include <sys/statvfs.h>
11211
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011212static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +020011213_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
11214 PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080011215 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011216 if (v == NULL)
11217 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011218
11219#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11221 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11222 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
11223 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
11224 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
11225 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
11226 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
11227 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
11228 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11229 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011230#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011231 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11232 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11233 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011234 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000011235 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011236 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011237 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011238 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011240 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011242 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011243 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011244 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011245 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11246 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011247#endif
Michael Felt502d5512018-01-05 13:01:58 +010011248/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
11249 * (issue #32390). */
11250#if defined(_AIX) && defined(_ALL_SOURCE)
11251 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
11252#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010011253 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010011254#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010011255 if (PyErr_Occurred()) {
11256 Py_DECREF(v);
11257 return NULL;
11258 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011259
Victor Stinner8c62be82010-05-06 00:08:46 +000011260 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011261}
11262
Larry Hastings2f936352014-08-05 14:04:04 +100011263
11264/*[clinic input]
11265os.fstatvfs
11266 fd: int
11267 /
11268
11269Perform an fstatvfs system call on the given fd.
11270
11271Equivalent to statvfs(fd).
11272[clinic start generated code]*/
11273
Larry Hastings2f936352014-08-05 14:04:04 +100011274static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011275os_fstatvfs_impl(PyObject *module, int fd)
11276/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011277{
11278 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011279 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011281
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011282 do {
11283 Py_BEGIN_ALLOW_THREADS
11284 result = fstatvfs(fd, &st);
11285 Py_END_ALLOW_THREADS
11286 } while (result != 0 && errno == EINTR &&
11287 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100011288 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011289 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011290
Victor Stinner1c2fa782020-05-10 11:05:29 +020011291 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011292}
Larry Hastings2f936352014-08-05 14:04:04 +100011293#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000011294
11295
Thomas Wouters477c8d52006-05-27 19:21:47 +000011296#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000011297#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100011298/*[clinic input]
11299os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000011300
Larry Hastings2f936352014-08-05 14:04:04 +100011301 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
11302
11303Perform a statvfs system call on the given path.
11304
11305path may always be specified as a string.
11306On some platforms, path may also be specified as an open file descriptor.
11307 If this functionality is unavailable, using it raises an exception.
11308[clinic start generated code]*/
11309
Larry Hastings2f936352014-08-05 14:04:04 +100011310static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011311os_statvfs_impl(PyObject *module, path_t *path)
11312/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011313{
11314 int result;
11315 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011316
11317 Py_BEGIN_ALLOW_THREADS
11318#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100011319 if (path->fd != -1) {
Larry Hastings2f936352014-08-05 14:04:04 +100011320 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011321 }
11322 else
11323#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011324 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011325 Py_END_ALLOW_THREADS
11326
11327 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011328 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011329 }
11330
Victor Stinner1c2fa782020-05-10 11:05:29 +020011331 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011332}
Larry Hastings2f936352014-08-05 14:04:04 +100011333#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
11334
Guido van Rossum94f6f721999-01-06 18:42:14 +000011335
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011336#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011337/*[clinic input]
11338os._getdiskusage
11339
Steve Dower23ad6d02018-02-22 10:39:10 -080011340 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100011341
11342Return disk usage statistics about the given path as a (total, free) tuple.
11343[clinic start generated code]*/
11344
Larry Hastings2f936352014-08-05 14:04:04 +100011345static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080011346os__getdiskusage_impl(PyObject *module, path_t *path)
11347/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011348{
11349 BOOL retval;
11350 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040011351 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011352
11353 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080011354 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011355 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040011356 if (retval == 0) {
11357 if (GetLastError() == ERROR_DIRECTORY) {
11358 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011359
Joe Pamerc8c02492018-09-25 10:57:36 -040011360 dir_path = PyMem_New(wchar_t, path->length + 1);
11361 if (dir_path == NULL) {
11362 return PyErr_NoMemory();
11363 }
11364
11365 wcscpy_s(dir_path, path->length + 1, path->wide);
11366
11367 if (_dirnameW(dir_path) != -1) {
11368 Py_BEGIN_ALLOW_THREADS
11369 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
11370 Py_END_ALLOW_THREADS
11371 }
11372 /* Record the last error in case it's modified by PyMem_Free. */
11373 err = GetLastError();
11374 PyMem_Free(dir_path);
11375 if (retval) {
11376 goto success;
11377 }
11378 }
11379 return PyErr_SetFromWindowsErr(err);
11380 }
11381
11382success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011383 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
11384}
Larry Hastings2f936352014-08-05 14:04:04 +100011385#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011386
11387
Fred Drakec9680921999-12-13 16:37:25 +000011388/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
11389 * It maps strings representing configuration variable names to
11390 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000011391 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000011392 * rarely-used constants. There are three separate tables that use
11393 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000011394 *
11395 * This code is always included, even if none of the interfaces that
11396 * need it are included. The #if hackery needed to avoid it would be
11397 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000011398 */
11399struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011400 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011401 int value;
Fred Drakec9680921999-12-13 16:37:25 +000011402};
11403
Fred Drake12c6e2d1999-12-14 21:25:03 +000011404static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011405conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000011406 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000011407{
Christian Heimes217cfd12007-12-02 14:31:20 +000011408 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011409 int value = _PyLong_AsInt(arg);
11410 if (value == -1 && PyErr_Occurred())
11411 return 0;
11412 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000011413 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000011414 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000011415 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000011416 /* look up the value in the table using a binary search */
11417 size_t lo = 0;
11418 size_t mid;
11419 size_t hi = tablesize;
11420 int cmp;
11421 const char *confname;
11422 if (!PyUnicode_Check(arg)) {
11423 PyErr_SetString(PyExc_TypeError,
11424 "configuration names must be strings or integers");
11425 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020011427 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000011428 if (confname == NULL)
11429 return 0;
11430 while (lo < hi) {
11431 mid = (lo + hi) / 2;
11432 cmp = strcmp(confname, table[mid].name);
11433 if (cmp < 0)
11434 hi = mid;
11435 else if (cmp > 0)
11436 lo = mid + 1;
11437 else {
11438 *valuep = table[mid].value;
11439 return 1;
11440 }
11441 }
11442 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
11443 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000011445}
11446
11447
11448#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
11449static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011450#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011451 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011452#endif
11453#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011455#endif
Fred Drakec9680921999-12-13 16:37:25 +000011456#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011457 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011458#endif
11459#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000011460 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000011461#endif
11462#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000011464#endif
11465#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000011466 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000011467#endif
11468#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011469 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011470#endif
11471#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000011472 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000011473#endif
11474#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011475 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000011476#endif
11477#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011478 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011479#endif
11480#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011481 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000011482#endif
11483#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011484 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011485#endif
11486#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011487 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000011488#endif
11489#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011490 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011491#endif
11492#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011493 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000011494#endif
11495#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011496 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011497#endif
11498#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011499 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000011500#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000011501#ifdef _PC_ACL_ENABLED
11502 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
11503#endif
11504#ifdef _PC_MIN_HOLE_SIZE
11505 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
11506#endif
11507#ifdef _PC_ALLOC_SIZE_MIN
11508 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
11509#endif
11510#ifdef _PC_REC_INCR_XFER_SIZE
11511 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
11512#endif
11513#ifdef _PC_REC_MAX_XFER_SIZE
11514 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
11515#endif
11516#ifdef _PC_REC_MIN_XFER_SIZE
11517 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
11518#endif
11519#ifdef _PC_REC_XFER_ALIGN
11520 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
11521#endif
11522#ifdef _PC_SYMLINK_MAX
11523 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
11524#endif
11525#ifdef _PC_XATTR_ENABLED
11526 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
11527#endif
11528#ifdef _PC_XATTR_EXISTS
11529 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
11530#endif
11531#ifdef _PC_TIMESTAMP_RESOLUTION
11532 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
11533#endif
Fred Drakec9680921999-12-13 16:37:25 +000011534};
11535
Fred Drakec9680921999-12-13 16:37:25 +000011536static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011537conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011538{
11539 return conv_confname(arg, valuep, posix_constants_pathconf,
11540 sizeof(posix_constants_pathconf)
11541 / sizeof(struct constdef));
11542}
11543#endif
11544
Larry Hastings2f936352014-08-05 14:04:04 +100011545
Fred Drakec9680921999-12-13 16:37:25 +000011546#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011547/*[clinic input]
11548os.fpathconf -> long
11549
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011550 fd: fildes
Larry Hastings2f936352014-08-05 14:04:04 +100011551 name: path_confname
11552 /
11553
11554Return the configuration limit name for the file descriptor fd.
11555
11556If there is no limit, return -1.
11557[clinic start generated code]*/
11558
Larry Hastings2f936352014-08-05 14:04:04 +100011559static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011560os_fpathconf_impl(PyObject *module, int fd, int name)
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011561/*[clinic end generated code: output=d5b7042425fc3e21 input=5b8d2471cfaae186]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011562{
11563 long limit;
11564
11565 errno = 0;
11566 limit = fpathconf(fd, name);
11567 if (limit == -1 && errno != 0)
11568 posix_error();
11569
11570 return limit;
11571}
11572#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011573
11574
11575#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011576/*[clinic input]
11577os.pathconf -> long
11578 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
11579 name: path_confname
11580
11581Return the configuration limit name for the file or directory path.
11582
11583If there is no limit, return -1.
11584On some platforms, path may also be specified as an open file descriptor.
11585 If this functionality is unavailable, using it raises an exception.
11586[clinic start generated code]*/
11587
Larry Hastings2f936352014-08-05 14:04:04 +100011588static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011589os_pathconf_impl(PyObject *module, path_t *path, int name)
11590/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011591{
Victor Stinner8c62be82010-05-06 00:08:46 +000011592 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000011593
Victor Stinner8c62be82010-05-06 00:08:46 +000011594 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020011595#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011596 if (path->fd != -1)
11597 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020011598 else
11599#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011600 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000011601 if (limit == -1 && errno != 0) {
11602 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000011603 /* could be a path or name problem */
11604 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000011605 else
Larry Hastings2f936352014-08-05 14:04:04 +100011606 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000011607 }
Larry Hastings2f936352014-08-05 14:04:04 +100011608
11609 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000011610}
Larry Hastings2f936352014-08-05 14:04:04 +100011611#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011612
11613#ifdef HAVE_CONFSTR
11614static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011615#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000011616 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000011617#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000011618#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011619 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011620#endif
11621#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011622 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011623#endif
Fred Draked86ed291999-12-15 15:34:33 +000011624#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011625 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011626#endif
11627#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011628 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011629#endif
11630#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011631 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011632#endif
11633#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011634 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011635#endif
Fred Drakec9680921999-12-13 16:37:25 +000011636#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011637 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011638#endif
11639#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011640 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011641#endif
11642#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011643 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011644#endif
11645#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011646 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011647#endif
11648#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011649 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011650#endif
11651#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011652 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011653#endif
11654#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011655 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011656#endif
11657#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011658 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011659#endif
Fred Draked86ed291999-12-15 15:34:33 +000011660#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000011661 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000011662#endif
Fred Drakec9680921999-12-13 16:37:25 +000011663#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000011664 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000011665#endif
Fred Draked86ed291999-12-15 15:34:33 +000011666#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011667 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000011668#endif
11669#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011670 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000011671#endif
11672#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011673 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011674#endif
11675#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011676 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000011677#endif
Fred Drakec9680921999-12-13 16:37:25 +000011678#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011679 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011680#endif
11681#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011682 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011683#endif
11684#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011685 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011686#endif
11687#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011688 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011689#endif
11690#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011691 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011692#endif
11693#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011694 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011695#endif
11696#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011697 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011698#endif
11699#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011700 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011701#endif
11702#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011703 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011704#endif
11705#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011706 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011707#endif
11708#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011709 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011710#endif
11711#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011712 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011713#endif
11714#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011715 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011716#endif
11717#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011718 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011719#endif
11720#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011721 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011722#endif
11723#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011724 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011725#endif
Fred Draked86ed291999-12-15 15:34:33 +000011726#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011727 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011728#endif
11729#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011730 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011731#endif
11732#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011733 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011734#endif
11735#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011736 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011737#endif
11738#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011739 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011740#endif
11741#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011742 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011743#endif
11744#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011745 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011746#endif
11747#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011748 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011749#endif
11750#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011751 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011752#endif
11753#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011754 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011755#endif
11756#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011757 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011758#endif
11759#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011760 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011761#endif
11762#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011763 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011764#endif
Fred Drakec9680921999-12-13 16:37:25 +000011765};
11766
11767static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011768conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011769{
11770 return conv_confname(arg, valuep, posix_constants_confstr,
11771 sizeof(posix_constants_confstr)
11772 / sizeof(struct constdef));
11773}
11774
Larry Hastings2f936352014-08-05 14:04:04 +100011775
11776/*[clinic input]
11777os.confstr
11778
11779 name: confstr_confname
11780 /
11781
11782Return a string-valued system configuration variable.
11783[clinic start generated code]*/
11784
Larry Hastings2f936352014-08-05 14:04:04 +100011785static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011786os_confstr_impl(PyObject *module, int name)
11787/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011788{
11789 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011790 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011791 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011792
Victor Stinnercb043522010-09-10 23:49:04 +000011793 errno = 0;
11794 len = confstr(name, buffer, sizeof(buffer));
11795 if (len == 0) {
11796 if (errno) {
11797 posix_error();
11798 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011799 }
11800 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011801 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011802 }
11803 }
Victor Stinnercb043522010-09-10 23:49:04 +000011804
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011805 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011806 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011807 char *buf = PyMem_Malloc(len);
11808 if (buf == NULL)
11809 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011810 len2 = confstr(name, buf, len);
11811 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011812 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011813 PyMem_Free(buf);
11814 }
11815 else
11816 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011817 return result;
11818}
Larry Hastings2f936352014-08-05 14:04:04 +100011819#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011820
11821
11822#ifdef HAVE_SYSCONF
11823static struct constdef posix_constants_sysconf[] = {
11824#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011825 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011826#endif
11827#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011828 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011829#endif
11830#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011831 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011832#endif
11833#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011834 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011835#endif
11836#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011837 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011838#endif
11839#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011840 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011841#endif
11842#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011843 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011844#endif
11845#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011846 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011847#endif
11848#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011849 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011850#endif
11851#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011852 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011853#endif
Fred Draked86ed291999-12-15 15:34:33 +000011854#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011855 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011856#endif
11857#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011858 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011859#endif
Fred Drakec9680921999-12-13 16:37:25 +000011860#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011861 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011862#endif
Fred Drakec9680921999-12-13 16:37:25 +000011863#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011864 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011865#endif
11866#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011867 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011868#endif
11869#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011870 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011871#endif
11872#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011873 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011874#endif
11875#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011876 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011877#endif
Fred Draked86ed291999-12-15 15:34:33 +000011878#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011879 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011880#endif
Fred Drakec9680921999-12-13 16:37:25 +000011881#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011882 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011883#endif
11884#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011885 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011886#endif
11887#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011888 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011889#endif
11890#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011891 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011892#endif
11893#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011894 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011895#endif
Fred Draked86ed291999-12-15 15:34:33 +000011896#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011897 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011898#endif
Fred Drakec9680921999-12-13 16:37:25 +000011899#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011900 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011901#endif
11902#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011903 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011904#endif
11905#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011906 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011907#endif
11908#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011909 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011910#endif
11911#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011912 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011913#endif
11914#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011915 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011916#endif
11917#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011918 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011919#endif
11920#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011921 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011922#endif
11923#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011924 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011925#endif
11926#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011927 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011928#endif
11929#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011930 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011931#endif
11932#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011933 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011934#endif
11935#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011936 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011937#endif
11938#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011939 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011940#endif
11941#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011942 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011943#endif
11944#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011945 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011946#endif
11947#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011948 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011949#endif
11950#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011951 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011952#endif
11953#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011954 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011955#endif
11956#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011957 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011958#endif
11959#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011960 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011961#endif
11962#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011963 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011964#endif
11965#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011966 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011967#endif
Fred Draked86ed291999-12-15 15:34:33 +000011968#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011969 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011970#endif
Fred Drakec9680921999-12-13 16:37:25 +000011971#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011972 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011973#endif
11974#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011975 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011976#endif
11977#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011978 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011979#endif
Fred Draked86ed291999-12-15 15:34:33 +000011980#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011981 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011982#endif
Fred Drakec9680921999-12-13 16:37:25 +000011983#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011984 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011985#endif
Fred Draked86ed291999-12-15 15:34:33 +000011986#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011987 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011988#endif
11989#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011990 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011991#endif
Fred Drakec9680921999-12-13 16:37:25 +000011992#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011993 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011994#endif
11995#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011996 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011997#endif
11998#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011999 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012000#endif
12001#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012002 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000012003#endif
Fred Draked86ed291999-12-15 15:34:33 +000012004#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000012005 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000012006#endif
Fred Drakec9680921999-12-13 16:37:25 +000012007#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000012008 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000012009#endif
12010#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000012011 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000012012#endif
12013#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012014 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012015#endif
12016#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000012017 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000012018#endif
12019#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000012020 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000012021#endif
12022#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000012023 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000012024#endif
12025#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000012026 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000012027#endif
Fred Draked86ed291999-12-15 15:34:33 +000012028#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000012029 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000012030#endif
Fred Drakec9680921999-12-13 16:37:25 +000012031#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012032 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012033#endif
12034#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012035 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012036#endif
Fred Draked86ed291999-12-15 15:34:33 +000012037#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012038 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000012039#endif
Fred Drakec9680921999-12-13 16:37:25 +000012040#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012041 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012042#endif
12043#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012044 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012045#endif
12046#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012047 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012048#endif
12049#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012050 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012051#endif
12052#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012053 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012054#endif
12055#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012056 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012057#endif
12058#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012059 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012060#endif
12061#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000012062 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000012063#endif
12064#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000012065 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000012066#endif
Fred Draked86ed291999-12-15 15:34:33 +000012067#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000012068 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000012069#endif
12070#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000012071 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000012072#endif
Fred Drakec9680921999-12-13 16:37:25 +000012073#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000012074 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000012075#endif
12076#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012077 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012078#endif
12079#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012080 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012081#endif
12082#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012083 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012084#endif
Batuhan Taşkaya909f4a32020-04-05 03:40:49 +030012085#ifdef _SC_AIX_REALMEM
12086 {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
12087#endif
Fred Drakec9680921999-12-13 16:37:25 +000012088#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012089 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012090#endif
12091#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000012092 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000012093#endif
12094#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000012095 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000012096#endif
12097#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000012098 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000012099#endif
12100#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000012101 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000012102#endif
12103#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000012104 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000012105#endif
12106#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000012107 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000012108#endif
12109#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012110 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000012111#endif
12112#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012113 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000012114#endif
12115#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000012116 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000012117#endif
12118#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000012119 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000012120#endif
12121#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000012122 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000012123#endif
12124#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000012125 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000012126#endif
12127#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012128 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012129#endif
12130#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012131 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012132#endif
12133#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000012134 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000012135#endif
12136#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012137 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012138#endif
12139#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012140 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012141#endif
12142#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000012143 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000012144#endif
12145#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012146 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012147#endif
12148#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012149 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012150#endif
12151#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012152 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000012153#endif
12154#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000012155 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000012156#endif
12157#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012158 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012159#endif
12160#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012161 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012162#endif
12163#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012164 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000012165#endif
12166#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012167 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012168#endif
12169#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012170 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012171#endif
12172#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012173 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012174#endif
12175#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012176 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012177#endif
12178#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012179 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012180#endif
Fred Draked86ed291999-12-15 15:34:33 +000012181#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000012182 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000012183#endif
Fred Drakec9680921999-12-13 16:37:25 +000012184#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000012185 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000012186#endif
12187#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012188 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012189#endif
12190#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000012191 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000012192#endif
12193#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012194 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012195#endif
12196#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012197 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012198#endif
12199#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012200 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012201#endif
12202#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000012203 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000012204#endif
12205#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012206 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012207#endif
12208#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012209 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012210#endif
12211#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012212 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012213#endif
12214#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012215 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012216#endif
12217#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012218 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000012219#endif
12220#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012221 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000012222#endif
12223#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000012224 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000012225#endif
12226#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012227 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012228#endif
12229#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012230 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012231#endif
12232#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012233 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012234#endif
12235#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000012236 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000012237#endif
12238#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012239 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012240#endif
12241#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012242 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012243#endif
12244#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012245 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012246#endif
12247#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012248 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012249#endif
12250#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012251 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012252#endif
12253#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012254 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012255#endif
12256#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000012257 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000012258#endif
12259#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012260 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012261#endif
12262#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012263 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012264#endif
12265#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012266 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012267#endif
12268#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012269 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000012270#endif
12271#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000012272 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000012273#endif
12274#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012275 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012276#endif
12277#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000012278 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000012279#endif
12280#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012281 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012282#endif
12283#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000012284 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000012285#endif
12286#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000012287 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000012288#endif
12289#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000012290 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000012291#endif
12292#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012293 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000012294#endif
12295#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012296 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012297#endif
12298#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000012299 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000012300#endif
12301#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000012302 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000012303#endif
12304#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012305 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012306#endif
12307#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012308 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012309#endif
12310#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000012311 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000012312#endif
12313#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000012314 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000012315#endif
12316#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000012317 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000012318#endif
12319};
12320
12321static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012322conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000012323{
12324 return conv_confname(arg, valuep, posix_constants_sysconf,
12325 sizeof(posix_constants_sysconf)
12326 / sizeof(struct constdef));
12327}
12328
Larry Hastings2f936352014-08-05 14:04:04 +100012329
12330/*[clinic input]
12331os.sysconf -> long
12332 name: sysconf_confname
12333 /
12334
12335Return an integer-valued system configuration variable.
12336[clinic start generated code]*/
12337
Larry Hastings2f936352014-08-05 14:04:04 +100012338static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012339os_sysconf_impl(PyObject *module, int name)
12340/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012341{
12342 long value;
12343
12344 errno = 0;
12345 value = sysconf(name);
12346 if (value == -1 && errno != 0)
12347 posix_error();
12348 return value;
12349}
12350#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000012351
12352
Fred Drakebec628d1999-12-15 18:31:10 +000012353/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020012354 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000012355 * the exported dictionaries that are used to publish information about the
12356 * names available on the host platform.
12357 *
12358 * Sorting the table at runtime ensures that the table is properly ordered
12359 * when used, even for platforms we're not able to test on. It also makes
12360 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000012361 */
Fred Drakebec628d1999-12-15 18:31:10 +000012362
12363static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012364cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000012365{
12366 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012367 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000012368 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012369 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000012370
12371 return strcmp(c1->name, c2->name);
12372}
12373
12374static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012375setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012376 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012377{
Fred Drakebec628d1999-12-15 18:31:10 +000012378 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000012379 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000012380
12381 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
12382 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000012383 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000012384 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012385
Barry Warsaw3155db32000-04-13 15:20:40 +000012386 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000012387 PyObject *o = PyLong_FromLong(table[i].value);
12388 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
12389 Py_XDECREF(o);
12390 Py_DECREF(d);
12391 return -1;
12392 }
12393 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000012394 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000012395 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000012396}
12397
Fred Drakebec628d1999-12-15 18:31:10 +000012398/* Return -1 on failure, 0 on success. */
12399static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000012400setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012401{
12402#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000012403 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000012404 sizeof(posix_constants_pathconf)
12405 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012406 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012407 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012408#endif
12409#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000012410 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000012411 sizeof(posix_constants_confstr)
12412 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012413 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012414 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012415#endif
12416#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000012417 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000012418 sizeof(posix_constants_sysconf)
12419 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012420 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012421 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012422#endif
Fred Drakebec628d1999-12-15 18:31:10 +000012423 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000012424}
Fred Draked86ed291999-12-15 15:34:33 +000012425
12426
Larry Hastings2f936352014-08-05 14:04:04 +100012427/*[clinic input]
12428os.abort
12429
12430Abort the interpreter immediately.
12431
12432This function 'dumps core' or otherwise fails in the hardest way possible
12433on the hosting operating system. This function never returns.
12434[clinic start generated code]*/
12435
Larry Hastings2f936352014-08-05 14:04:04 +100012436static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012437os_abort_impl(PyObject *module)
12438/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012439{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012440 abort();
12441 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010012442#ifndef __clang__
12443 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
12444 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
12445 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012446 Py_FatalError("abort() called from Python code didn't abort!");
12447 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010012448#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012449}
Fred Drakebec628d1999-12-15 18:31:10 +000012450
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000012451#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012452/* Grab ShellExecute dynamically from shell32 */
12453static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012454static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
12455 LPCWSTR, INT);
12456static int
12457check_ShellExecute()
12458{
12459 HINSTANCE hShell32;
12460
12461 /* only recheck */
12462 if (-1 == has_ShellExecute) {
12463 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070012464 /* Security note: this call is not vulnerable to "DLL hijacking".
12465 SHELL32 is part of "KnownDLLs" and so Windows always load
12466 the system SHELL32.DLL, even if there is another SHELL32.DLL
12467 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080012468 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080012469 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080012470 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
12471 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070012472 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012473 } else {
12474 has_ShellExecute = 0;
12475 }
Tony Roberts4860f012019-02-02 18:16:42 +010012476 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012477 }
12478 return has_ShellExecute;
12479}
12480
12481
Steve Dowercc16be82016-09-08 10:35:16 -070012482/*[clinic input]
12483os.startfile
12484 filepath: path_t
12485 operation: Py_UNICODE = NULL
Steve Dower019e9e82021-04-23 18:03:17 +010012486 arguments: Py_UNICODE = NULL
12487 cwd: path_t(nullable=True) = None
12488 show_cmd: int = 1
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000012489
Steve Dowercc16be82016-09-08 10:35:16 -070012490Start a file with its associated application.
12491
12492When "operation" is not specified or "open", this acts like
12493double-clicking the file in Explorer, or giving the file name as an
12494argument to the DOS "start" command: the file is opened with whatever
12495application (if any) its extension is associated.
12496When another "operation" is given, it specifies what should be done with
12497the file. A typical operation is "print".
12498
Steve Dower019e9e82021-04-23 18:03:17 +010012499"arguments" is passed to the application, but should be omitted if the
12500file is a document.
12501
12502"cwd" is the working directory for the operation. If "filepath" is
12503relative, it will be resolved against this directory. This argument
12504should usually be an absolute path.
12505
12506"show_cmd" can be used to override the recommended visibility option.
12507See the Windows ShellExecute documentation for values.
12508
Steve Dowercc16be82016-09-08 10:35:16 -070012509startfile returns as soon as the associated application is launched.
12510There is no option to wait for the application to close, and no way
12511to retrieve the application's exit status.
12512
12513The filepath is relative to the current directory. If you want to use
12514an absolute path, make sure the first character is not a slash ("/");
12515the underlying Win32 ShellExecute function doesn't work if it is.
12516[clinic start generated code]*/
12517
12518static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020012519os_startfile_impl(PyObject *module, path_t *filepath,
Steve Dower019e9e82021-04-23 18:03:17 +010012520 const Py_UNICODE *operation, const Py_UNICODE *arguments,
12521 path_t *cwd, int show_cmd)
12522/*[clinic end generated code: output=3baa4f9795841880 input=8248997b80669622]*/
Steve Dowercc16be82016-09-08 10:35:16 -070012523{
12524 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012525
12526 if(!check_ShellExecute()) {
12527 /* If the OS doesn't have ShellExecute, return a
12528 NotImplementedError. */
12529 return PyErr_Format(PyExc_NotImplementedError,
12530 "startfile not available on this platform");
12531 }
12532
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012533 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080012534 return NULL;
12535 }
Steve Dower019e9e82021-04-23 18:03:17 +010012536 if (PySys_Audit("os.startfile/2", "OuuOi", filepath->object, operation,
12537 arguments, cwd->object ? cwd->object : Py_None,
12538 show_cmd) < 0) {
12539 return NULL;
12540 }
Saiyang Gou95f60012020-02-04 16:15:00 -080012541
Victor Stinner8c62be82010-05-06 00:08:46 +000012542 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070012543 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower019e9e82021-04-23 18:03:17 +010012544 arguments, cwd->wide, show_cmd);
Victor Stinner8c62be82010-05-06 00:08:46 +000012545 Py_END_ALLOW_THREADS
12546
Victor Stinner8c62be82010-05-06 00:08:46 +000012547 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070012548 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020012549 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012550 }
Steve Dowercc16be82016-09-08 10:35:16 -070012551 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000012552}
Larry Hastings2f936352014-08-05 14:04:04 +100012553#endif /* MS_WINDOWS */
12554
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012555
Martin v. Löwis438b5342002-12-27 10:16:42 +000012556#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100012557/*[clinic input]
12558os.getloadavg
12559
12560Return average recent system load information.
12561
12562Return the number of processes in the system run queue averaged over
12563the last 1, 5, and 15 minutes as a tuple of three floats.
12564Raises OSError if the load average was unobtainable.
12565[clinic start generated code]*/
12566
Larry Hastings2f936352014-08-05 14:04:04 +100012567static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012568os_getloadavg_impl(PyObject *module)
12569/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000012570{
12571 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000012572 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000012573 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
12574 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000012575 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000012576 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000012577}
Larry Hastings2f936352014-08-05 14:04:04 +100012578#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000012579
Larry Hastings2f936352014-08-05 14:04:04 +100012580
12581/*[clinic input]
12582os.device_encoding
12583 fd: int
12584
12585Return a string describing the encoding of a terminal's file descriptor.
12586
12587The file descriptor must be attached to a terminal.
12588If the device is not a terminal, return None.
12589[clinic start generated code]*/
12590
Larry Hastings2f936352014-08-05 14:04:04 +100012591static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012592os_device_encoding_impl(PyObject *module, int fd)
12593/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012594{
Brett Cannonefb00c02012-02-29 18:31:31 -050012595 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000012596}
12597
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012598
Larry Hastings2f936352014-08-05 14:04:04 +100012599#ifdef HAVE_SETRESUID
12600/*[clinic input]
12601os.setresuid
12602
12603 ruid: uid_t
12604 euid: uid_t
12605 suid: uid_t
12606 /
12607
12608Set the current process's real, effective, and saved user ids.
12609[clinic start generated code]*/
12610
Larry Hastings2f936352014-08-05 14:04:04 +100012611static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012612os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
12613/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012614{
Victor Stinner8c62be82010-05-06 00:08:46 +000012615 if (setresuid(ruid, euid, suid) < 0)
12616 return posix_error();
12617 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012618}
Larry Hastings2f936352014-08-05 14:04:04 +100012619#endif /* HAVE_SETRESUID */
12620
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012621
12622#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012623/*[clinic input]
12624os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012625
Larry Hastings2f936352014-08-05 14:04:04 +100012626 rgid: gid_t
12627 egid: gid_t
12628 sgid: gid_t
12629 /
12630
12631Set the current process's real, effective, and saved group ids.
12632[clinic start generated code]*/
12633
Larry Hastings2f936352014-08-05 14:04:04 +100012634static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012635os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12636/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012637{
Victor Stinner8c62be82010-05-06 00:08:46 +000012638 if (setresgid(rgid, egid, sgid) < 0)
12639 return posix_error();
12640 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012641}
Larry Hastings2f936352014-08-05 14:04:04 +100012642#endif /* HAVE_SETRESGID */
12643
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012644
12645#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100012646/*[clinic input]
12647os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012648
Larry Hastings2f936352014-08-05 14:04:04 +100012649Return a tuple of the current process's real, effective, and saved user ids.
12650[clinic start generated code]*/
12651
Larry Hastings2f936352014-08-05 14:04:04 +100012652static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012653os_getresuid_impl(PyObject *module)
12654/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012655{
Victor Stinner8c62be82010-05-06 00:08:46 +000012656 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012657 if (getresuid(&ruid, &euid, &suid) < 0)
12658 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012659 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
12660 _PyLong_FromUid(euid),
12661 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012662}
Larry Hastings2f936352014-08-05 14:04:04 +100012663#endif /* HAVE_GETRESUID */
12664
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012665
12666#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012667/*[clinic input]
12668os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012669
Larry Hastings2f936352014-08-05 14:04:04 +100012670Return a tuple of the current process's real, effective, and saved group ids.
12671[clinic start generated code]*/
12672
Larry Hastings2f936352014-08-05 14:04:04 +100012673static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012674os_getresgid_impl(PyObject *module)
12675/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012676{
12677 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012678 if (getresgid(&rgid, &egid, &sgid) < 0)
12679 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012680 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
12681 _PyLong_FromGid(egid),
12682 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012683}
Larry Hastings2f936352014-08-05 14:04:04 +100012684#endif /* HAVE_GETRESGID */
12685
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012686
Benjamin Peterson9428d532011-09-14 11:45:52 -040012687#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100012688/*[clinic input]
12689os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040012690
Larry Hastings2f936352014-08-05 14:04:04 +100012691 path: path_t(allow_fd=True)
12692 attribute: path_t
12693 *
12694 follow_symlinks: bool = True
12695
12696Return the value of extended attribute attribute on path.
12697
BNMetricsb9427072018-11-02 15:20:19 +000012698path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012699If follow_symlinks is False, and the last element of the path is a symbolic
12700 link, getxattr will examine the symbolic link itself instead of the file
12701 the link points to.
12702
12703[clinic start generated code]*/
12704
Larry Hastings2f936352014-08-05 14:04:04 +100012705static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012706os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012707 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012708/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012709{
12710 Py_ssize_t i;
12711 PyObject *buffer = NULL;
12712
12713 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12714 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012715
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012716 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12717 return NULL;
12718 }
12719
Larry Hastings9cf065c2012-06-22 16:30:09 -070012720 for (i = 0; ; i++) {
12721 void *ptr;
12722 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012723 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012724 Py_ssize_t buffer_size = buffer_sizes[i];
12725 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012726 path_error(path);
12727 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012728 }
12729 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12730 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012731 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012732 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012733
Larry Hastings9cf065c2012-06-22 16:30:09 -070012734 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012735 if (path->fd >= 0)
12736 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012737 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012738 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012739 else
Larry Hastings2f936352014-08-05 14:04:04 +100012740 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012741 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012742
Larry Hastings9cf065c2012-06-22 16:30:09 -070012743 if (result < 0) {
12744 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012745 if (errno == ERANGE)
12746 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012747 path_error(path);
12748 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012749 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012750
Larry Hastings9cf065c2012-06-22 16:30:09 -070012751 if (result != buffer_size) {
12752 /* Can only shrink. */
12753 _PyBytes_Resize(&buffer, result);
12754 }
12755 break;
12756 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012757
Larry Hastings9cf065c2012-06-22 16:30:09 -070012758 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012759}
12760
Larry Hastings2f936352014-08-05 14:04:04 +100012761
12762/*[clinic input]
12763os.setxattr
12764
12765 path: path_t(allow_fd=True)
12766 attribute: path_t
12767 value: Py_buffer
12768 flags: int = 0
12769 *
12770 follow_symlinks: bool = True
12771
12772Set extended attribute attribute on path to value.
12773
BNMetricsb9427072018-11-02 15:20:19 +000012774path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012775If follow_symlinks is False, and the last element of the path is a symbolic
12776 link, setxattr will modify the symbolic link itself instead of the file
12777 the link points to.
12778
12779[clinic start generated code]*/
12780
Benjamin Peterson799bd802011-08-31 22:15:17 -040012781static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012782os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012783 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012784/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012785{
Larry Hastings2f936352014-08-05 14:04:04 +100012786 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012787
Larry Hastings2f936352014-08-05 14:04:04 +100012788 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012789 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012790
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012791 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12792 value->buf, value->len, flags) < 0) {
12793 return NULL;
12794 }
12795
Benjamin Peterson799bd802011-08-31 22:15:17 -040012796 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012797 if (path->fd > -1)
12798 result = fsetxattr(path->fd, attribute->narrow,
12799 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012800 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012801 result = setxattr(path->narrow, attribute->narrow,
12802 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012803 else
Larry Hastings2f936352014-08-05 14:04:04 +100012804 result = lsetxattr(path->narrow, attribute->narrow,
12805 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012806 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012807
Larry Hastings9cf065c2012-06-22 16:30:09 -070012808 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012809 path_error(path);
12810 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012811 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012812
Larry Hastings2f936352014-08-05 14:04:04 +100012813 Py_RETURN_NONE;
12814}
12815
12816
12817/*[clinic input]
12818os.removexattr
12819
12820 path: path_t(allow_fd=True)
12821 attribute: path_t
12822 *
12823 follow_symlinks: bool = True
12824
12825Remove extended attribute attribute on path.
12826
BNMetricsb9427072018-11-02 15:20:19 +000012827path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012828If follow_symlinks is False, and the last element of the path is a symbolic
12829 link, removexattr will modify the symbolic link itself instead of the file
12830 the link points to.
12831
12832[clinic start generated code]*/
12833
Larry Hastings2f936352014-08-05 14:04:04 +100012834static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012835os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012836 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012837/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012838{
12839 ssize_t result;
12840
12841 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12842 return NULL;
12843
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012844 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12845 return NULL;
12846 }
12847
Larry Hastings2f936352014-08-05 14:04:04 +100012848 Py_BEGIN_ALLOW_THREADS;
12849 if (path->fd > -1)
12850 result = fremovexattr(path->fd, attribute->narrow);
12851 else if (follow_symlinks)
12852 result = removexattr(path->narrow, attribute->narrow);
12853 else
12854 result = lremovexattr(path->narrow, attribute->narrow);
12855 Py_END_ALLOW_THREADS;
12856
12857 if (result) {
12858 return path_error(path);
12859 }
12860
12861 Py_RETURN_NONE;
12862}
12863
12864
12865/*[clinic input]
12866os.listxattr
12867
12868 path: path_t(allow_fd=True, nullable=True) = None
12869 *
12870 follow_symlinks: bool = True
12871
12872Return a list of extended attributes on path.
12873
BNMetricsb9427072018-11-02 15:20:19 +000012874path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012875if path is None, listxattr will examine the current directory.
12876If follow_symlinks is False, and the last element of the path is a symbolic
12877 link, listxattr will examine the symbolic link itself instead of the file
12878 the link points to.
12879[clinic start generated code]*/
12880
Larry Hastings2f936352014-08-05 14:04:04 +100012881static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012882os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012883/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012884{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012885 Py_ssize_t i;
12886 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012887 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012888 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012889
Larry Hastings2f936352014-08-05 14:04:04 +100012890 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012891 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012892
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012893 if (PySys_Audit("os.listxattr", "(O)",
12894 path->object ? path->object : Py_None) < 0) {
12895 return NULL;
12896 }
12897
Larry Hastings2f936352014-08-05 14:04:04 +100012898 name = path->narrow ? path->narrow : ".";
12899
Larry Hastings9cf065c2012-06-22 16:30:09 -070012900 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012901 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012902 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012903 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012904 Py_ssize_t buffer_size = buffer_sizes[i];
12905 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012906 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012907 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012908 break;
12909 }
Victor Stinner00d7abd2020-12-01 09:56:42 +010012910 buffer = PyMem_Malloc(buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012911 if (!buffer) {
12912 PyErr_NoMemory();
12913 break;
12914 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012915
Larry Hastings9cf065c2012-06-22 16:30:09 -070012916 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012917 if (path->fd > -1)
12918 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012919 else if (follow_symlinks)
12920 length = listxattr(name, buffer, buffer_size);
12921 else
12922 length = llistxattr(name, buffer, buffer_size);
12923 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012924
Larry Hastings9cf065c2012-06-22 16:30:09 -070012925 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012926 if (errno == ERANGE) {
Victor Stinner00d7abd2020-12-01 09:56:42 +010012927 PyMem_Free(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012928 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012929 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012930 }
Larry Hastings2f936352014-08-05 14:04:04 +100012931 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012932 break;
12933 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012934
Larry Hastings9cf065c2012-06-22 16:30:09 -070012935 result = PyList_New(0);
12936 if (!result) {
12937 goto exit;
12938 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012939
Larry Hastings9cf065c2012-06-22 16:30:09 -070012940 end = buffer + length;
12941 for (trace = start = buffer; trace != end; trace++) {
12942 if (!*trace) {
12943 int error;
12944 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12945 trace - start);
12946 if (!attribute) {
12947 Py_DECREF(result);
12948 result = NULL;
12949 goto exit;
12950 }
12951 error = PyList_Append(result, attribute);
12952 Py_DECREF(attribute);
12953 if (error) {
12954 Py_DECREF(result);
12955 result = NULL;
12956 goto exit;
12957 }
12958 start = trace + 1;
12959 }
12960 }
12961 break;
12962 }
12963exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012964 if (buffer)
Victor Stinner00d7abd2020-12-01 09:56:42 +010012965 PyMem_Free(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012966 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012967}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012968#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012969
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012970
Larry Hastings2f936352014-08-05 14:04:04 +100012971/*[clinic input]
12972os.urandom
12973
12974 size: Py_ssize_t
12975 /
12976
12977Return a bytes object containing random bytes suitable for cryptographic use.
12978[clinic start generated code]*/
12979
Larry Hastings2f936352014-08-05 14:04:04 +100012980static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012981os_urandom_impl(PyObject *module, Py_ssize_t size)
12982/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012983{
12984 PyObject *bytes;
12985 int result;
12986
Georg Brandl2fb477c2012-02-21 00:33:36 +010012987 if (size < 0)
12988 return PyErr_Format(PyExc_ValueError,
12989 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012990 bytes = PyBytes_FromStringAndSize(NULL, size);
12991 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012992 return NULL;
12993
Victor Stinnere66987e2016-09-06 16:33:52 -070012994 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012995 if (result == -1) {
12996 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012997 return NULL;
12998 }
Larry Hastings2f936352014-08-05 14:04:04 +100012999 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010013000}
13001
Zackery Spytz43fdbd22019-05-29 13:57:07 -060013002#ifdef HAVE_MEMFD_CREATE
13003/*[clinic input]
13004os.memfd_create
13005
13006 name: FSConverter
13007 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
13008
13009[clinic start generated code]*/
13010
13011static PyObject *
13012os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
13013/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
13014{
13015 int fd;
13016 const char *bytes = PyBytes_AS_STRING(name);
13017 Py_BEGIN_ALLOW_THREADS
13018 fd = memfd_create(bytes, flags);
13019 Py_END_ALLOW_THREADS
13020 if (fd == -1) {
13021 return PyErr_SetFromErrno(PyExc_OSError);
13022 }
13023 return PyLong_FromLong(fd);
13024}
13025#endif
13026
Christian Heimescd9fed62020-11-13 19:48:52 +010013027#ifdef HAVE_EVENTFD
13028/*[clinic input]
13029os.eventfd
13030
13031 initval: unsigned_int
13032 flags: int(c_default="EFD_CLOEXEC") = EFD_CLOEXEC
13033
13034Creates and returns an event notification file descriptor.
13035[clinic start generated code]*/
13036
13037static PyObject *
13038os_eventfd_impl(PyObject *module, unsigned int initval, int flags)
13039/*[clinic end generated code: output=ce9c9bbd1446f2de input=66203e3c50c4028b]*/
13040
13041{
13042 /* initval is limited to uint32_t, internal counter is uint64_t */
13043 int fd;
13044 Py_BEGIN_ALLOW_THREADS
13045 fd = eventfd(initval, flags);
13046 Py_END_ALLOW_THREADS
13047 if (fd == -1) {
13048 return PyErr_SetFromErrno(PyExc_OSError);
13049 }
13050 return PyLong_FromLong(fd);
13051}
13052
13053/*[clinic input]
13054os.eventfd_read
13055
13056 fd: fildes
13057
13058Read eventfd value
13059[clinic start generated code]*/
13060
13061static PyObject *
13062os_eventfd_read_impl(PyObject *module, int fd)
13063/*[clinic end generated code: output=8f2c7b59a3521fd1 input=110f8b57fa596afe]*/
13064{
13065 eventfd_t value;
13066 int result;
13067 Py_BEGIN_ALLOW_THREADS
13068 result = eventfd_read(fd, &value);
13069 Py_END_ALLOW_THREADS
13070 if (result == -1) {
13071 return PyErr_SetFromErrno(PyExc_OSError);
13072 }
13073 return PyLong_FromUnsignedLongLong(value);
13074}
13075
13076/*[clinic input]
13077os.eventfd_write
13078
13079 fd: fildes
13080 value: unsigned_long_long
13081
13082Write eventfd value.
13083[clinic start generated code]*/
13084
13085static PyObject *
13086os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value)
13087/*[clinic end generated code: output=bebd9040bbf987f5 input=156de8555be5a949]*/
13088{
13089 int result;
13090 Py_BEGIN_ALLOW_THREADS
13091 result = eventfd_write(fd, value);
13092 Py_END_ALLOW_THREADS
13093 if (result == -1) {
13094 return PyErr_SetFromErrno(PyExc_OSError);
13095 }
13096 Py_RETURN_NONE;
13097}
13098#endif /* HAVE_EVENTFD */
13099
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013100/* Terminal size querying */
13101
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013102PyDoc_STRVAR(TerminalSize_docstring,
13103 "A tuple of (columns, lines) for holding terminal window size");
13104
13105static PyStructSequence_Field TerminalSize_fields[] = {
13106 {"columns", "width of the terminal window in characters"},
13107 {"lines", "height of the terminal window in characters"},
13108 {NULL, NULL}
13109};
13110
13111static PyStructSequence_Desc TerminalSize_desc = {
13112 "os.terminal_size",
13113 TerminalSize_docstring,
13114 TerminalSize_fields,
13115 2,
13116};
13117
13118#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013119/*[clinic input]
13120os.get_terminal_size
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013121
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013122 fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
13123 /
13124
13125Return the size of the terminal window as (columns, lines).
13126
13127The optional argument fd (default standard output) specifies
13128which file descriptor should be queried.
13129
13130If the file descriptor is not connected to a terminal, an OSError
13131is thrown.
13132
13133This function will only be defined if an implementation is
13134available for this system.
13135
13136shutil.get_terminal_size is the high-level function which should
13137normally be used, os.get_terminal_size is the low-level implementation.
13138[clinic start generated code]*/
13139
13140static PyObject *
13141os_get_terminal_size_impl(PyObject *module, int fd)
13142/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013143{
13144 int columns, lines;
13145 PyObject *termsize;
13146
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013147 /* Under some conditions stdout may not be connected and
13148 * fileno(stdout) may point to an invalid file descriptor. For example
13149 * GUI apps don't have valid standard streams by default.
13150 *
13151 * If this happens, and the optional fd argument is not present,
13152 * the ioctl below will fail returning EBADF. This is what we want.
13153 */
13154
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013155#ifdef TERMSIZE_USE_IOCTL
13156 {
13157 struct winsize w;
13158 if (ioctl(fd, TIOCGWINSZ, &w))
13159 return PyErr_SetFromErrno(PyExc_OSError);
13160 columns = w.ws_col;
13161 lines = w.ws_row;
13162 }
13163#endif /* TERMSIZE_USE_IOCTL */
13164
13165#ifdef TERMSIZE_USE_CONIO
13166 {
13167 DWORD nhandle;
13168 HANDLE handle;
13169 CONSOLE_SCREEN_BUFFER_INFO csbi;
13170 switch (fd) {
13171 case 0: nhandle = STD_INPUT_HANDLE;
13172 break;
13173 case 1: nhandle = STD_OUTPUT_HANDLE;
13174 break;
13175 case 2: nhandle = STD_ERROR_HANDLE;
13176 break;
13177 default:
13178 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
13179 }
13180 handle = GetStdHandle(nhandle);
13181 if (handle == NULL)
13182 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
13183 if (handle == INVALID_HANDLE_VALUE)
13184 return PyErr_SetFromWindowsErr(0);
13185
13186 if (!GetConsoleScreenBufferInfo(handle, &csbi))
13187 return PyErr_SetFromWindowsErr(0);
13188
13189 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
13190 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
13191 }
13192#endif /* TERMSIZE_USE_CONIO */
13193
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013194 PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013195 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013196 if (termsize == NULL)
13197 return NULL;
13198 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
13199 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
13200 if (PyErr_Occurred()) {
13201 Py_DECREF(termsize);
13202 return NULL;
13203 }
13204 return termsize;
13205}
13206#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
13207
Larry Hastings2f936352014-08-05 14:04:04 +100013208
13209/*[clinic input]
13210os.cpu_count
13211
Charles-François Natali80d62e62015-08-13 20:37:08 +010013212Return the number of CPUs in the system; return None if indeterminable.
13213
13214This number is not equivalent to the number of CPUs the current process can
13215use. The number of usable CPUs can be obtained with
13216``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100013217[clinic start generated code]*/
13218
Larry Hastings2f936352014-08-05 14:04:04 +100013219static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013220os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013221/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013222{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020013223 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013224#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010013225 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013226#elif defined(__hpux)
13227 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
13228#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
13229 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
pxinwr3405e052020-08-07 13:21:52 +080013230#elif defined(__VXWORKS__)
13231 ncpu = _Py_popcount32(vxCpuEnabledGet());
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013232#elif defined(__DragonFly__) || \
13233 defined(__OpenBSD__) || \
13234 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020013235 defined(__NetBSD__) || \
13236 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020013237 int mib[2];
13238 size_t len = sizeof(ncpu);
13239 mib[0] = CTL_HW;
13240 mib[1] = HW_NCPU;
13241 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
13242 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013243#endif
13244 if (ncpu >= 1)
13245 return PyLong_FromLong(ncpu);
13246 else
13247 Py_RETURN_NONE;
13248}
13249
Victor Stinnerdaf45552013-08-28 00:53:59 +020013250
Larry Hastings2f936352014-08-05 14:04:04 +100013251/*[clinic input]
13252os.get_inheritable -> bool
13253
13254 fd: int
13255 /
13256
13257Get the close-on-exe flag of the specified file descriptor.
13258[clinic start generated code]*/
13259
Larry Hastings2f936352014-08-05 14:04:04 +100013260static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013261os_get_inheritable_impl(PyObject *module, int fd)
13262/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013263{
Steve Dower8fc89802015-04-12 00:26:27 -040013264 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040013265 _Py_BEGIN_SUPPRESS_IPH
13266 return_value = _Py_get_inheritable(fd);
13267 _Py_END_SUPPRESS_IPH
13268 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100013269}
13270
13271
13272/*[clinic input]
13273os.set_inheritable
13274 fd: int
13275 inheritable: int
13276 /
13277
13278Set the inheritable flag of the specified file descriptor.
13279[clinic start generated code]*/
13280
Larry Hastings2f936352014-08-05 14:04:04 +100013281static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013282os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
13283/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020013284{
Steve Dower8fc89802015-04-12 00:26:27 -040013285 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013286
Steve Dower8fc89802015-04-12 00:26:27 -040013287 _Py_BEGIN_SUPPRESS_IPH
13288 result = _Py_set_inheritable(fd, inheritable, NULL);
13289 _Py_END_SUPPRESS_IPH
13290 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020013291 return NULL;
13292 Py_RETURN_NONE;
13293}
13294
13295
13296#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100013297/*[clinic input]
13298os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070013299 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013300 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020013301
Larry Hastings2f936352014-08-05 14:04:04 +100013302Get the close-on-exe flag of the specified file descriptor.
13303[clinic start generated code]*/
13304
Larry Hastings2f936352014-08-05 14:04:04 +100013305static int
Benjamin Petersonca470632016-09-06 13:47:26 -070013306os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070013307/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013308{
13309 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013310
13311 if (!GetHandleInformation((HANDLE)handle, &flags)) {
13312 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100013313 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013314 }
13315
Larry Hastings2f936352014-08-05 14:04:04 +100013316 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013317}
13318
Victor Stinnerdaf45552013-08-28 00:53:59 +020013319
Larry Hastings2f936352014-08-05 14:04:04 +100013320/*[clinic input]
13321os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070013322 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013323 inheritable: bool
13324 /
13325
13326Set the inheritable flag of the specified handle.
13327[clinic start generated code]*/
13328
Larry Hastings2f936352014-08-05 14:04:04 +100013329static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070013330os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040013331 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070013332/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013333{
13334 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013335 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
13336 PyErr_SetFromWindowsErr(0);
13337 return NULL;
13338 }
13339 Py_RETURN_NONE;
13340}
Larry Hastings2f936352014-08-05 14:04:04 +100013341#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013342
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013343#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013344/*[clinic input]
13345os.get_blocking -> bool
13346 fd: int
13347 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013348
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013349Get the blocking mode of the file descriptor.
13350
13351Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
13352[clinic start generated code]*/
13353
13354static int
13355os_get_blocking_impl(PyObject *module, int fd)
13356/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013357{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013358 int blocking;
13359
Steve Dower8fc89802015-04-12 00:26:27 -040013360 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013361 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040013362 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013363 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013364}
13365
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013366/*[clinic input]
13367os.set_blocking
13368 fd: int
13369 blocking: bool(accept={int})
13370 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013371
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013372Set the blocking mode of the specified file descriptor.
13373
13374Set the O_NONBLOCK flag if blocking is False,
13375clear the O_NONBLOCK flag otherwise.
13376[clinic start generated code]*/
13377
13378static PyObject *
13379os_set_blocking_impl(PyObject *module, int fd, int blocking)
13380/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013381{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013382 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013383
Steve Dower8fc89802015-04-12 00:26:27 -040013384 _Py_BEGIN_SUPPRESS_IPH
13385 result = _Py_set_blocking(fd, blocking);
13386 _Py_END_SUPPRESS_IPH
13387 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013388 return NULL;
13389 Py_RETURN_NONE;
13390}
13391#endif /* !MS_WINDOWS */
13392
13393
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013394/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080013395class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013396[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080013397/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013398
13399typedef struct {
13400 PyObject_HEAD
13401 PyObject *name;
13402 PyObject *path;
13403 PyObject *stat;
13404 PyObject *lstat;
13405#ifdef MS_WINDOWS
13406 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010013407 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010013408 int got_file_index;
13409#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010013410#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013411 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013412#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013413 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013414 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010013415#endif
13416} DirEntry;
13417
Eddie Elizondob3966632019-11-05 07:16:14 -080013418static PyObject *
13419_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
13420{
13421 PyErr_Format(PyExc_TypeError,
13422 "cannot create '%.100s' instances", _PyType_Name(type));
13423 return NULL;
13424}
13425
Victor Stinner6036e442015-03-08 01:58:04 +010013426static void
13427DirEntry_dealloc(DirEntry *entry)
13428{
Eddie Elizondob3966632019-11-05 07:16:14 -080013429 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010013430 Py_XDECREF(entry->name);
13431 Py_XDECREF(entry->path);
13432 Py_XDECREF(entry->stat);
13433 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080013434 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13435 free_func(entry);
13436 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013437}
13438
13439/* Forward reference */
13440static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013441DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13442 int follow_symlinks, unsigned short mode_bits);
Victor Stinner6036e442015-03-08 01:58:04 +010013443
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013444/*[clinic input]
13445os.DirEntry.is_symlink -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013446 defining_class: defining_class
13447 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013448
13449Return True if the entry is a symbolic link; cached per entry.
13450[clinic start generated code]*/
13451
Victor Stinner6036e442015-03-08 01:58:04 +010013452static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013453os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
13454/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013455{
13456#ifdef MS_WINDOWS
13457 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010013458#elif defined(HAVE_DIRENT_D_TYPE)
13459 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013460 if (self->d_type != DT_UNKNOWN)
13461 return self->d_type == DT_LNK;
13462 else
Victor Stinner97f33c32020-05-14 18:05:58 +020013463 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010013464#else
13465 /* POSIX without d_type */
Victor Stinner97f33c32020-05-14 18:05:58 +020013466 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010013467#endif
13468}
13469
13470static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013471DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
Victor Stinner6036e442015-03-08 01:58:04 +010013472{
13473 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013474 STRUCT_STAT st;
13475 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010013476
13477#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013478 if (!PyUnicode_FSDecoder(self->path, &ub))
13479 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013480#if USE_UNICODE_WCHAR_CACHE
13481_Py_COMP_DIAG_PUSH
13482_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013483 const wchar_t *path = PyUnicode_AsUnicode(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013484_Py_COMP_DIAG_POP
13485#else /* USE_UNICODE_WCHAR_CACHE */
13486 wchar_t *path = PyUnicode_AsWideCharString(ub, NULL);
13487 Py_DECREF(ub);
13488#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013489#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013490 if (!PyUnicode_FSConverter(self->path, &ub))
13491 return NULL;
13492 const char *path = PyBytes_AS_STRING(ub);
13493 if (self->dir_fd != DEFAULT_DIR_FD) {
13494#ifdef HAVE_FSTATAT
Ronald Oussoren41761932020-11-08 10:05:27 +010013495 if (HAVE_FSTATAT_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013496 result = fstatat(self->dir_fd, path, &st,
13497 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +010013498 } else
13499
13500#endif /* HAVE_FSTATAT */
13501 {
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013502 Py_DECREF(ub);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013503 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
13504 return NULL;
Ronald Oussoren41761932020-11-08 10:05:27 +010013505 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013506 }
13507 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013508#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013509 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013510 if (follow_symlinks)
13511 result = STAT(path, &st);
13512 else
13513 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013514 }
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013515#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE
13516 PyMem_Free(path);
13517#else /* USE_UNICODE_WCHAR_CACHE */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013518 Py_DECREF(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013519#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013520
13521 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013522 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013523
Victor Stinner97f33c32020-05-14 18:05:58 +020013524 return _pystat_fromstructstat(module, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010013525}
13526
13527static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013528DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
Victor Stinner6036e442015-03-08 01:58:04 +010013529{
13530 if (!self->lstat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013531 PyObject *module = PyType_GetModule(defining_class);
Victor Stinner6036e442015-03-08 01:58:04 +010013532#ifdef MS_WINDOWS
Victor Stinner97f33c32020-05-14 18:05:58 +020013533 self->lstat = _pystat_fromstructstat(module, &self->win32_lstat);
Victor Stinner6036e442015-03-08 01:58:04 +010013534#else /* POSIX */
Victor Stinner97f33c32020-05-14 18:05:58 +020013535 self->lstat = DirEntry_fetch_stat(module, self, 0);
Victor Stinner6036e442015-03-08 01:58:04 +010013536#endif
13537 }
13538 Py_XINCREF(self->lstat);
13539 return self->lstat;
13540}
13541
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013542/*[clinic input]
13543os.DirEntry.stat
Victor Stinner97f33c32020-05-14 18:05:58 +020013544 defining_class: defining_class
13545 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013546 *
13547 follow_symlinks: bool = True
13548
13549Return stat_result object for the entry; cached per entry.
13550[clinic start generated code]*/
13551
Victor Stinner6036e442015-03-08 01:58:04 +010013552static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013553os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
13554 int follow_symlinks)
13555/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013556{
Victor Stinner97f33c32020-05-14 18:05:58 +020013557 if (!follow_symlinks) {
13558 return DirEntry_get_lstat(defining_class, self);
13559 }
Victor Stinner6036e442015-03-08 01:58:04 +010013560
13561 if (!self->stat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013562 int result = os_DirEntry_is_symlink_impl(self, defining_class);
13563 if (result == -1) {
Victor Stinner6036e442015-03-08 01:58:04 +010013564 return NULL;
Victor Stinner97f33c32020-05-14 18:05:58 +020013565 }
13566 if (result) {
13567 PyObject *module = PyType_GetModule(defining_class);
13568 self->stat = DirEntry_fetch_stat(module, self, 1);
13569 }
13570 else {
13571 self->stat = DirEntry_get_lstat(defining_class, self);
13572 }
Victor Stinner6036e442015-03-08 01:58:04 +010013573 }
13574
13575 Py_XINCREF(self->stat);
13576 return self->stat;
13577}
13578
Victor Stinner6036e442015-03-08 01:58:04 +010013579/* Set exception and return -1 on error, 0 for False, 1 for True */
13580static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013581DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13582 int follow_symlinks, unsigned short mode_bits)
Victor Stinner6036e442015-03-08 01:58:04 +010013583{
13584 PyObject *stat = NULL;
13585 PyObject *st_mode = NULL;
13586 long mode;
13587 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010013588#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013589 int is_symlink;
13590 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010013591#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013592#ifdef MS_WINDOWS
13593 unsigned long dir_bits;
13594#endif
13595
13596#ifdef MS_WINDOWS
13597 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
13598 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010013599#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013600 is_symlink = self->d_type == DT_LNK;
13601 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
13602#endif
13603
Victor Stinner35a97c02015-03-08 02:59:09 +010013604#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013605 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010013606#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020013607 stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010013608 if (!stat) {
13609 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
13610 /* If file doesn't exist (anymore), then return False
13611 (i.e., say it's not a file/directory) */
13612 PyErr_Clear();
13613 return 0;
13614 }
13615 goto error;
13616 }
Victor Stinner97f33c32020-05-14 18:05:58 +020013617 _posixstate* state = get_posix_state(PyType_GetModule(defining_class));
13618 st_mode = PyObject_GetAttr(stat, state->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010013619 if (!st_mode)
13620 goto error;
13621
13622 mode = PyLong_AsLong(st_mode);
13623 if (mode == -1 && PyErr_Occurred())
13624 goto error;
13625 Py_CLEAR(st_mode);
13626 Py_CLEAR(stat);
13627 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010013628#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013629 }
13630 else if (is_symlink) {
13631 assert(mode_bits != S_IFLNK);
13632 result = 0;
13633 }
13634 else {
13635 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
13636#ifdef MS_WINDOWS
13637 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
13638 if (mode_bits == S_IFDIR)
13639 result = dir_bits != 0;
13640 else
13641 result = dir_bits == 0;
13642#else /* POSIX */
13643 if (mode_bits == S_IFDIR)
13644 result = self->d_type == DT_DIR;
13645 else
13646 result = self->d_type == DT_REG;
13647#endif
13648 }
Victor Stinner35a97c02015-03-08 02:59:09 +010013649#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013650
13651 return result;
13652
13653error:
13654 Py_XDECREF(st_mode);
13655 Py_XDECREF(stat);
13656 return -1;
13657}
13658
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013659/*[clinic input]
13660os.DirEntry.is_dir -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013661 defining_class: defining_class
13662 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013663 *
13664 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010013665
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013666Return True if the entry is a directory; cached per entry.
13667[clinic start generated code]*/
13668
13669static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013670os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
13671 int follow_symlinks)
13672/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013673{
Victor Stinner97f33c32020-05-14 18:05:58 +020013674 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010013675}
13676
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013677/*[clinic input]
13678os.DirEntry.is_file -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013679 defining_class: defining_class
13680 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013681 *
13682 follow_symlinks: bool = True
13683
13684Return True if the entry is a file; cached per entry.
13685[clinic start generated code]*/
13686
13687static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013688os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
13689 int follow_symlinks)
13690/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013691{
Victor Stinner97f33c32020-05-14 18:05:58 +020013692 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010013693}
13694
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013695/*[clinic input]
13696os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010013697
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013698Return inode of the entry; cached per entry.
13699[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013700
13701static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013702os_DirEntry_inode_impl(DirEntry *self)
13703/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013704{
13705#ifdef MS_WINDOWS
13706 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013707 PyObject *unicode;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013708 STRUCT_STAT stat;
13709 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010013710
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013711 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010013712 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013713#if USE_UNICODE_WCHAR_CACHE
13714_Py_COMP_DIAG_PUSH
13715_Py_COMP_DIAG_IGNORE_DEPR_DECLS
13716 const wchar_t *path = PyUnicode_AsUnicode(unicode);
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013717 result = LSTAT(path, &stat);
13718 Py_DECREF(unicode);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013719_Py_COMP_DIAG_POP
13720#else /* USE_UNICODE_WCHAR_CACHE */
13721 wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL);
13722 Py_DECREF(unicode);
13723 result = LSTAT(path, &stat);
13724 PyMem_Free(path);
13725#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013726
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013727 if (result != 0)
13728 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013729
13730 self->win32_file_index = stat.st_ino;
13731 self->got_file_index = 1;
13732 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010013733 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
13734 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010013735#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020013736 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
13737 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010013738#endif
13739}
13740
13741static PyObject *
13742DirEntry_repr(DirEntry *self)
13743{
13744 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13745}
13746
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013747/*[clinic input]
13748os.DirEntry.__fspath__
13749
13750Returns the path for the entry.
13751[clinic start generated code]*/
13752
Brett Cannon96881cd2016-06-10 14:37:21 -070013753static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013754os_DirEntry___fspath___impl(DirEntry *self)
13755/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070013756{
13757 Py_INCREF(self->path);
13758 return self->path;
13759}
13760
Victor Stinner6036e442015-03-08 01:58:04 +010013761static PyMemberDef DirEntry_members[] = {
13762 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13763 "the entry's base filename, relative to scandir() \"path\" argument"},
13764 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13765 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13766 {NULL}
13767};
13768
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013769#include "clinic/posixmodule.c.h"
13770
Victor Stinner6036e442015-03-08 01:58:04 +010013771static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013772 OS_DIRENTRY_IS_DIR_METHODDEF
13773 OS_DIRENTRY_IS_FILE_METHODDEF
13774 OS_DIRENTRY_IS_SYMLINK_METHODDEF
13775 OS_DIRENTRY_STAT_METHODDEF
13776 OS_DIRENTRY_INODE_METHODDEF
13777 OS_DIRENTRY___FSPATH___METHODDEF
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013778 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
13779 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Victor Stinner6036e442015-03-08 01:58:04 +010013780 {NULL}
13781};
13782
Eddie Elizondob3966632019-11-05 07:16:14 -080013783static PyType_Slot DirEntryType_slots[] = {
13784 {Py_tp_new, _disabled_new},
13785 {Py_tp_dealloc, DirEntry_dealloc},
13786 {Py_tp_repr, DirEntry_repr},
13787 {Py_tp_methods, DirEntry_methods},
13788 {Py_tp_members, DirEntry_members},
13789 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010013790};
13791
Eddie Elizondob3966632019-11-05 07:16:14 -080013792static PyType_Spec DirEntryType_spec = {
13793 MODNAME ".DirEntry",
13794 sizeof(DirEntry),
13795 0,
13796 Py_TPFLAGS_DEFAULT,
13797 DirEntryType_slots
13798};
13799
13800
Victor Stinner6036e442015-03-08 01:58:04 +010013801#ifdef MS_WINDOWS
13802
13803static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013804join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010013805{
13806 Py_ssize_t path_len;
13807 Py_ssize_t size;
13808 wchar_t *result;
13809 wchar_t ch;
13810
13811 if (!path_wide) { /* Default arg: "." */
13812 path_wide = L".";
13813 path_len = 1;
13814 }
13815 else {
13816 path_len = wcslen(path_wide);
13817 }
13818
13819 /* The +1's are for the path separator and the NUL */
13820 size = path_len + 1 + wcslen(filename) + 1;
13821 result = PyMem_New(wchar_t, size);
13822 if (!result) {
13823 PyErr_NoMemory();
13824 return NULL;
13825 }
13826 wcscpy(result, path_wide);
13827 if (path_len > 0) {
13828 ch = result[path_len - 1];
13829 if (ch != SEP && ch != ALTSEP && ch != L':')
13830 result[path_len++] = SEP;
13831 wcscpy(result + path_len, filename);
13832 }
13833 return result;
13834}
13835
13836static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013837DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
Victor Stinner6036e442015-03-08 01:58:04 +010013838{
13839 DirEntry *entry;
13840 BY_HANDLE_FILE_INFORMATION file_info;
13841 ULONG reparse_tag;
13842 wchar_t *joined_path;
13843
Victor Stinner1c2fa782020-05-10 11:05:29 +020013844 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013845 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013846 if (!entry)
13847 return NULL;
13848 entry->name = NULL;
13849 entry->path = NULL;
13850 entry->stat = NULL;
13851 entry->lstat = NULL;
13852 entry->got_file_index = 0;
13853
13854 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13855 if (!entry->name)
13856 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013857 if (path->narrow) {
13858 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13859 if (!entry->name)
13860 goto error;
13861 }
Victor Stinner6036e442015-03-08 01:58:04 +010013862
13863 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13864 if (!joined_path)
13865 goto error;
13866
13867 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13868 PyMem_Free(joined_path);
13869 if (!entry->path)
13870 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013871 if (path->narrow) {
13872 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13873 if (!entry->path)
13874 goto error;
13875 }
Victor Stinner6036e442015-03-08 01:58:04 +010013876
Steve Dowercc16be82016-09-08 10:35:16 -070013877 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013878 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13879
13880 return (PyObject *)entry;
13881
13882error:
13883 Py_DECREF(entry);
13884 return NULL;
13885}
13886
13887#else /* POSIX */
13888
13889static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013890join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013891{
13892 Py_ssize_t path_len;
13893 Py_ssize_t size;
13894 char *result;
13895
13896 if (!path_narrow) { /* Default arg: "." */
13897 path_narrow = ".";
13898 path_len = 1;
13899 }
13900 else {
13901 path_len = strlen(path_narrow);
13902 }
13903
13904 if (filename_len == -1)
13905 filename_len = strlen(filename);
13906
13907 /* The +1's are for the path separator and the NUL */
13908 size = path_len + 1 + filename_len + 1;
13909 result = PyMem_New(char, size);
13910 if (!result) {
13911 PyErr_NoMemory();
13912 return NULL;
13913 }
13914 strcpy(result, path_narrow);
13915 if (path_len > 0 && result[path_len - 1] != '/')
13916 result[path_len++] = '/';
13917 strcpy(result + path_len, filename);
13918 return result;
13919}
13920
13921static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013922DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13923 Py_ssize_t name_len, ino_t d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013924#ifdef HAVE_DIRENT_D_TYPE
13925 , unsigned char d_type
13926#endif
13927 )
Victor Stinner6036e442015-03-08 01:58:04 +010013928{
13929 DirEntry *entry;
13930 char *joined_path;
13931
Victor Stinner1c2fa782020-05-10 11:05:29 +020013932 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013933 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013934 if (!entry)
13935 return NULL;
13936 entry->name = NULL;
13937 entry->path = NULL;
13938 entry->stat = NULL;
13939 entry->lstat = NULL;
13940
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013941 if (path->fd != -1) {
13942 entry->dir_fd = path->fd;
13943 joined_path = NULL;
13944 }
13945 else {
13946 entry->dir_fd = DEFAULT_DIR_FD;
13947 joined_path = join_path_filename(path->narrow, name, name_len);
13948 if (!joined_path)
13949 goto error;
13950 }
Victor Stinner6036e442015-03-08 01:58:04 +010013951
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013952 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013953 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013954 if (joined_path)
13955 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013956 }
13957 else {
13958 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013959 if (joined_path)
13960 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013961 }
13962 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013963 if (!entry->name)
13964 goto error;
13965
13966 if (path->fd != -1) {
13967 entry->path = entry->name;
13968 Py_INCREF(entry->path);
13969 }
13970 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013971 goto error;
13972
Victor Stinner35a97c02015-03-08 02:59:09 +010013973#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013974 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013975#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013976 entry->d_ino = d_ino;
13977
13978 return (PyObject *)entry;
13979
13980error:
13981 Py_XDECREF(entry);
13982 return NULL;
13983}
13984
13985#endif
13986
13987
13988typedef struct {
13989 PyObject_HEAD
13990 path_t path;
13991#ifdef MS_WINDOWS
13992 HANDLE handle;
13993 WIN32_FIND_DATAW file_data;
13994 int first_time;
13995#else /* POSIX */
13996 DIR *dirp;
13997#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013998#ifdef HAVE_FDOPENDIR
13999 int fd;
14000#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014001} ScandirIterator;
14002
14003#ifdef MS_WINDOWS
14004
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014005static int
14006ScandirIterator_is_closed(ScandirIterator *iterator)
14007{
14008 return iterator->handle == INVALID_HANDLE_VALUE;
14009}
14010
Victor Stinner6036e442015-03-08 01:58:04 +010014011static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014012ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010014013{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014014 HANDLE handle = iterator->handle;
14015
14016 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010014017 return;
14018
Victor Stinner6036e442015-03-08 01:58:04 +010014019 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014020 Py_BEGIN_ALLOW_THREADS
14021 FindClose(handle);
14022 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010014023}
14024
14025static PyObject *
14026ScandirIterator_iternext(ScandirIterator *iterator)
14027{
14028 WIN32_FIND_DATAW *file_data = &iterator->file_data;
14029 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014030 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014031
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014032 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014033 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010014034 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014035
14036 while (1) {
14037 if (!iterator->first_time) {
14038 Py_BEGIN_ALLOW_THREADS
14039 success = FindNextFileW(iterator->handle, file_data);
14040 Py_END_ALLOW_THREADS
14041 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014042 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010014043 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014044 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010014045 break;
14046 }
14047 }
14048 iterator->first_time = 0;
14049
14050 /* Skip over . and .. */
14051 if (wcscmp(file_data->cFileName, L".") != 0 &&
Victor Stinner1c2fa782020-05-10 11:05:29 +020014052 wcscmp(file_data->cFileName, L"..") != 0)
14053 {
14054 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
14055 entry = DirEntry_from_find_data(module, &iterator->path, file_data);
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014056 if (!entry)
14057 break;
14058 return entry;
14059 }
Victor Stinner6036e442015-03-08 01:58:04 +010014060
14061 /* Loop till we get a non-dot directory or finish iterating */
14062 }
14063
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014064 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014065 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010014066 return NULL;
14067}
14068
14069#else /* POSIX */
14070
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014071static int
14072ScandirIterator_is_closed(ScandirIterator *iterator)
14073{
14074 return !iterator->dirp;
14075}
14076
Victor Stinner6036e442015-03-08 01:58:04 +010014077static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014078ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010014079{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014080 DIR *dirp = iterator->dirp;
14081
14082 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010014083 return;
14084
Victor Stinner6036e442015-03-08 01:58:04 +010014085 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014086 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014087#ifdef HAVE_FDOPENDIR
14088 if (iterator->path.fd != -1)
14089 rewinddir(dirp);
14090#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014091 closedir(dirp);
14092 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010014093 return;
14094}
14095
14096static PyObject *
14097ScandirIterator_iternext(ScandirIterator *iterator)
14098{
14099 struct dirent *direntp;
14100 Py_ssize_t name_len;
14101 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014102 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014103
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014104 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014105 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010014106 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014107
14108 while (1) {
14109 errno = 0;
14110 Py_BEGIN_ALLOW_THREADS
14111 direntp = readdir(iterator->dirp);
14112 Py_END_ALLOW_THREADS
14113
14114 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014115 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010014116 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014117 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010014118 break;
14119 }
14120
14121 /* Skip over . and .. */
14122 name_len = NAMLEN(direntp);
14123 is_dot = direntp->d_name[0] == '.' &&
14124 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
14125 if (!is_dot) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014126 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
14127 entry = DirEntry_from_posix_info(module,
14128 &iterator->path, direntp->d_name,
14129 name_len, direntp->d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010014130#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner1c2fa782020-05-10 11:05:29 +020014131 , direntp->d_type
Victor Stinner35a97c02015-03-08 02:59:09 +010014132#endif
14133 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014134 if (!entry)
14135 break;
14136 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014137 }
14138
14139 /* Loop till we get a non-dot directory or finish iterating */
14140 }
14141
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014142 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014143 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010014144 return NULL;
14145}
14146
14147#endif
14148
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014149static PyObject *
14150ScandirIterator_close(ScandirIterator *self, PyObject *args)
14151{
14152 ScandirIterator_closedir(self);
14153 Py_RETURN_NONE;
14154}
14155
14156static PyObject *
14157ScandirIterator_enter(PyObject *self, PyObject *args)
14158{
14159 Py_INCREF(self);
14160 return self;
14161}
14162
14163static PyObject *
14164ScandirIterator_exit(ScandirIterator *self, PyObject *args)
14165{
14166 ScandirIterator_closedir(self);
14167 Py_RETURN_NONE;
14168}
14169
Victor Stinner6036e442015-03-08 01:58:04 +010014170static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010014171ScandirIterator_finalize(ScandirIterator *iterator)
14172{
14173 PyObject *error_type, *error_value, *error_traceback;
14174
14175 /* Save the current exception, if any. */
14176 PyErr_Fetch(&error_type, &error_value, &error_traceback);
14177
14178 if (!ScandirIterator_is_closed(iterator)) {
14179 ScandirIterator_closedir(iterator);
14180
14181 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
14182 "unclosed scandir iterator %R", iterator)) {
14183 /* Spurious errors can appear at shutdown */
14184 if (PyErr_ExceptionMatches(PyExc_Warning)) {
14185 PyErr_WriteUnraisable((PyObject *) iterator);
14186 }
14187 }
14188 }
14189
Victor Stinner7bfa4092016-03-23 00:43:54 +010014190 path_cleanup(&iterator->path);
14191
14192 /* Restore the saved exception. */
14193 PyErr_Restore(error_type, error_value, error_traceback);
14194}
14195
14196static void
Victor Stinner6036e442015-03-08 01:58:04 +010014197ScandirIterator_dealloc(ScandirIterator *iterator)
14198{
Eddie Elizondob3966632019-11-05 07:16:14 -080014199 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010014200 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
14201 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014202
Eddie Elizondob3966632019-11-05 07:16:14 -080014203 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
14204 free_func(iterator);
14205 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010014206}
14207
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014208static PyMethodDef ScandirIterator_methods[] = {
14209 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
14210 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
14211 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
14212 {NULL}
14213};
14214
Eddie Elizondob3966632019-11-05 07:16:14 -080014215static PyType_Slot ScandirIteratorType_slots[] = {
14216 {Py_tp_new, _disabled_new},
14217 {Py_tp_dealloc, ScandirIterator_dealloc},
14218 {Py_tp_finalize, ScandirIterator_finalize},
14219 {Py_tp_iter, PyObject_SelfIter},
14220 {Py_tp_iternext, ScandirIterator_iternext},
14221 {Py_tp_methods, ScandirIterator_methods},
14222 {0, 0},
14223};
14224
14225static PyType_Spec ScandirIteratorType_spec = {
14226 MODNAME ".ScandirIterator",
14227 sizeof(ScandirIterator),
14228 0,
Victor Stinner97f33c32020-05-14 18:05:58 +020014229 // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
14230 // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
Eddie Elizondob3966632019-11-05 07:16:14 -080014231 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
14232 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010014233};
14234
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014235/*[clinic input]
14236os.scandir
14237
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014238 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014239
14240Return an iterator of DirEntry objects for given path.
14241
BNMetricsb9427072018-11-02 15:20:19 +000014242path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014243is bytes, the names of yielded DirEntry objects will also be bytes; in
14244all other circumstances they will be str.
14245
14246If path is None, uses the path='.'.
14247[clinic start generated code]*/
14248
Victor Stinner6036e442015-03-08 01:58:04 +010014249static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014250os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000014251/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010014252{
14253 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010014254#ifdef MS_WINDOWS
14255 wchar_t *path_strW;
14256#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014257 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014258#ifdef HAVE_FDOPENDIR
14259 int fd = -1;
14260#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014261#endif
14262
Steve Dower60419a72019-06-24 08:42:54 -070014263 if (PySys_Audit("os.scandir", "O",
14264 path->object ? path->object : Py_None) < 0) {
14265 return NULL;
14266 }
14267
Hai Shif707d942020-03-16 21:15:01 +080014268 PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014269 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010014270 if (!iterator)
14271 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014272
14273#ifdef MS_WINDOWS
14274 iterator->handle = INVALID_HANDLE_VALUE;
14275#else
14276 iterator->dirp = NULL;
14277#endif
14278
Serhiy Storchaka095ef732017-02-09 20:05:51 +020014279 /* Move the ownership to iterator->path */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014280 memcpy(&iterator->path, path, sizeof(path_t));
14281 memset(path, 0, sizeof(path_t));
Victor Stinner6036e442015-03-08 01:58:04 +010014282
14283#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010014284 iterator->first_time = 1;
14285
14286 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
14287 if (!path_strW)
14288 goto error;
14289
14290 Py_BEGIN_ALLOW_THREADS
14291 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
14292 Py_END_ALLOW_THREADS
14293
14294 PyMem_Free(path_strW);
14295
14296 if (iterator->handle == INVALID_HANDLE_VALUE) {
14297 path_error(&iterator->path);
14298 goto error;
14299 }
14300#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010014301 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014302#ifdef HAVE_FDOPENDIR
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014303 if (iterator->path.fd != -1) {
Ronald Oussoren41761932020-11-08 10:05:27 +010014304 if (HAVE_FDOPENDIR_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014305 /* closedir() closes the FD, so we duplicate it */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014306 fd = _Py_dup(iterator->path.fd);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014307 if (fd == -1)
14308 goto error;
14309
14310 Py_BEGIN_ALLOW_THREADS
14311 iterator->dirp = fdopendir(fd);
14312 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +010014313 } else {
14314 PyErr_SetString(PyExc_TypeError,
14315 "scandir: path should be string, bytes, os.PathLike or None, not int");
14316 return NULL;
14317 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014318 }
14319 else
14320#endif
14321 {
14322 if (iterator->path.narrow)
14323 path_str = iterator->path.narrow;
14324 else
14325 path_str = ".";
14326
14327 Py_BEGIN_ALLOW_THREADS
14328 iterator->dirp = opendir(path_str);
14329 Py_END_ALLOW_THREADS
14330 }
Victor Stinner6036e442015-03-08 01:58:04 +010014331
14332 if (!iterator->dirp) {
14333 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014334#ifdef HAVE_FDOPENDIR
14335 if (fd != -1) {
14336 Py_BEGIN_ALLOW_THREADS
14337 close(fd);
14338 Py_END_ALLOW_THREADS
14339 }
14340#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014341 goto error;
14342 }
14343#endif
14344
14345 return (PyObject *)iterator;
14346
14347error:
14348 Py_DECREF(iterator);
14349 return NULL;
14350}
14351
Ethan Furman410ef8e2016-06-04 12:06:26 -070014352/*
14353 Return the file system path representation of the object.
14354
14355 If the object is str or bytes, then allow it to pass through with
14356 an incremented refcount. If the object defines __fspath__(), then
14357 return the result of that method. All other types raise a TypeError.
14358*/
14359PyObject *
14360PyOS_FSPath(PyObject *path)
14361{
Brett Cannon3f9183b2016-08-26 14:44:48 -070014362 /* For error message reasons, this function is manually inlined in
14363 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070014364 PyObject *func = NULL;
14365 PyObject *path_repr = NULL;
14366
14367 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
14368 Py_INCREF(path);
14369 return path;
14370 }
14371
14372 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
14373 if (NULL == func) {
14374 return PyErr_Format(PyExc_TypeError,
14375 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014376 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080014377 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070014378 }
14379
Victor Stinnerf17c3de2016-12-06 18:46:19 +010014380 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070014381 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070014382 if (NULL == path_repr) {
14383 return NULL;
14384 }
14385
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014386 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
14387 PyErr_Format(PyExc_TypeError,
14388 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080014389 "not %.200s", _PyType_Name(Py_TYPE(path)),
14390 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014391 Py_DECREF(path_repr);
14392 return NULL;
14393 }
14394
Ethan Furman410ef8e2016-06-04 12:06:26 -070014395 return path_repr;
14396}
14397
14398/*[clinic input]
14399os.fspath
14400
14401 path: object
14402
14403Return the file system path representation of the object.
14404
Brett Cannonb4f43e92016-06-09 14:32:08 -070014405If the object is str or bytes, then allow it to pass through as-is. If the
14406object defines __fspath__(), then return the result of that method. All other
14407types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070014408[clinic start generated code]*/
14409
14410static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030014411os_fspath_impl(PyObject *module, PyObject *path)
14412/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070014413{
14414 return PyOS_FSPath(path);
14415}
Victor Stinner6036e442015-03-08 01:58:04 +010014416
Victor Stinner9b1f4742016-09-06 16:18:52 -070014417#ifdef HAVE_GETRANDOM_SYSCALL
14418/*[clinic input]
14419os.getrandom
14420
14421 size: Py_ssize_t
14422 flags: int=0
14423
14424Obtain a series of random bytes.
14425[clinic start generated code]*/
14426
14427static PyObject *
14428os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
14429/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
14430{
Victor Stinner9b1f4742016-09-06 16:18:52 -070014431 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014432 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014433
14434 if (size < 0) {
14435 errno = EINVAL;
14436 return posix_error();
14437 }
14438
Victor Stinnerec2319c2016-09-20 23:00:59 +020014439 bytes = PyBytes_FromStringAndSize(NULL, size);
14440 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014441 PyErr_NoMemory();
14442 return NULL;
14443 }
14444
14445 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014446 n = syscall(SYS_getrandom,
14447 PyBytes_AS_STRING(bytes),
14448 PyBytes_GET_SIZE(bytes),
14449 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070014450 if (n < 0 && errno == EINTR) {
14451 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014452 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014453 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020014454
14455 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070014456 continue;
14457 }
14458 break;
14459 }
14460
14461 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014462 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020014463 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014464 }
14465
Victor Stinnerec2319c2016-09-20 23:00:59 +020014466 if (n != size) {
14467 _PyBytes_Resize(&bytes, n);
14468 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070014469
14470 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014471
14472error:
14473 Py_DECREF(bytes);
14474 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014475}
14476#endif /* HAVE_GETRANDOM_SYSCALL */
14477
Steve Dower2438cdf2019-03-29 16:37:16 -070014478#ifdef MS_WINDOWS
14479/* bpo-36085: Helper functions for managing DLL search directories
14480 * on win32
14481 */
14482
14483typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
14484typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
14485
14486/*[clinic input]
14487os._add_dll_directory
14488
14489 path: path_t
14490
14491Add a path to the DLL search path.
14492
14493This search path is used when resolving dependencies for imported
14494extension modules (the module itself is resolved through sys.path),
14495and also by ctypes.
14496
14497Returns an opaque value that may be passed to os.remove_dll_directory
14498to remove this directory from the search path.
14499[clinic start generated code]*/
14500
14501static PyObject *
14502os__add_dll_directory_impl(PyObject *module, path_t *path)
14503/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
14504{
14505 HMODULE hKernel32;
14506 PAddDllDirectory AddDllDirectory;
14507 DLL_DIRECTORY_COOKIE cookie = 0;
14508 DWORD err = 0;
14509
Saiyang Gou7514f4f2020-02-12 23:47:42 -080014510 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
14511 return NULL;
14512 }
14513
Steve Dower2438cdf2019-03-29 16:37:16 -070014514 /* For Windows 7, we have to load this. As this will be a fairly
14515 infrequent operation, just do it each time. Kernel32 is always
14516 loaded. */
14517 Py_BEGIN_ALLOW_THREADS
14518 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14519 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
14520 hKernel32, "AddDllDirectory")) ||
14521 !(cookie = (*AddDllDirectory)(path->wide))) {
14522 err = GetLastError();
14523 }
14524 Py_END_ALLOW_THREADS
14525
14526 if (err) {
14527 return win32_error_object_err("add_dll_directory",
14528 path->object, err);
14529 }
14530
14531 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
14532}
14533
14534/*[clinic input]
14535os._remove_dll_directory
14536
14537 cookie: object
14538
14539Removes a path from the DLL search path.
14540
14541The parameter is an opaque value that was returned from
14542os.add_dll_directory. You can only remove directories that you added
14543yourself.
14544[clinic start generated code]*/
14545
14546static PyObject *
14547os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
14548/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
14549{
14550 HMODULE hKernel32;
14551 PRemoveDllDirectory RemoveDllDirectory;
14552 DLL_DIRECTORY_COOKIE cookieValue;
14553 DWORD err = 0;
14554
14555 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
14556 PyErr_SetString(PyExc_TypeError,
14557 "Provided cookie was not returned from os.add_dll_directory");
14558 return NULL;
14559 }
14560
14561 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
14562 cookie, "DLL directory cookie");
14563
14564 /* For Windows 7, we have to load this. As this will be a fairly
14565 infrequent operation, just do it each time. Kernel32 is always
14566 loaded. */
14567 Py_BEGIN_ALLOW_THREADS
14568 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14569 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
14570 hKernel32, "RemoveDllDirectory")) ||
14571 !(*RemoveDllDirectory)(cookieValue)) {
14572 err = GetLastError();
14573 }
14574 Py_END_ALLOW_THREADS
14575
14576 if (err) {
14577 return win32_error_object_err("remove_dll_directory",
14578 NULL, err);
14579 }
14580
14581 if (PyCapsule_SetName(cookie, NULL)) {
14582 return NULL;
14583 }
14584
14585 Py_RETURN_NONE;
14586}
14587
14588#endif
Larry Hastings31826802013-10-19 00:09:25 -070014589
Victor Stinner65a796e2020-04-01 18:49:29 +020014590
14591/* Only check if WIFEXITED is available: expect that it comes
14592 with WEXITSTATUS, WIFSIGNALED, etc.
14593
14594 os.waitstatus_to_exitcode() is implemented in C and not in Python, so
14595 subprocess can safely call it during late Python finalization without
Victor Stinner62230712020-11-18 23:18:29 +010014596 risking that used os attributes were set to None by finalize_modules(). */
Victor Stinner65a796e2020-04-01 18:49:29 +020014597#if defined(WIFEXITED) || defined(MS_WINDOWS)
14598/*[clinic input]
14599os.waitstatus_to_exitcode
14600
Victor Stinner9bee32b2020-04-22 16:30:35 +020014601 status as status_obj: object
Victor Stinner65a796e2020-04-01 18:49:29 +020014602
14603Convert a wait status to an exit code.
14604
14605On Unix:
14606
14607* If WIFEXITED(status) is true, return WEXITSTATUS(status).
14608* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
14609* Otherwise, raise a ValueError.
14610
14611On Windows, return status shifted right by 8 bits.
14612
14613On Unix, if the process is being traced or if waitpid() was called with
14614WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
14615This function must not be called if WIFSTOPPED(status) is true.
14616[clinic start generated code]*/
14617
14618static PyObject *
Victor Stinner9bee32b2020-04-22 16:30:35 +020014619os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
14620/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
Victor Stinner65a796e2020-04-01 18:49:29 +020014621{
14622#ifndef MS_WINDOWS
Victor Stinner9bee32b2020-04-22 16:30:35 +020014623 int status = _PyLong_AsInt(status_obj);
14624 if (status == -1 && PyErr_Occurred()) {
14625 return NULL;
14626 }
14627
Victor Stinner65a796e2020-04-01 18:49:29 +020014628 WAIT_TYPE wait_status;
14629 WAIT_STATUS_INT(wait_status) = status;
14630 int exitcode;
14631 if (WIFEXITED(wait_status)) {
14632 exitcode = WEXITSTATUS(wait_status);
14633 /* Sanity check to provide warranty on the function behavior.
14634 It should not occur in practice */
14635 if (exitcode < 0) {
14636 PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
14637 return NULL;
14638 }
14639 }
14640 else if (WIFSIGNALED(wait_status)) {
14641 int signum = WTERMSIG(wait_status);
14642 /* Sanity check to provide warranty on the function behavior.
14643 It should not occurs in practice */
14644 if (signum <= 0) {
14645 PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
14646 return NULL;
14647 }
14648 exitcode = -signum;
14649 } else if (WIFSTOPPED(wait_status)) {
14650 /* Status only received if the process is being traced
14651 or if waitpid() was called with WUNTRACED option. */
14652 int signum = WSTOPSIG(wait_status);
14653 PyErr_Format(PyExc_ValueError,
14654 "process stopped by delivery of signal %i",
14655 signum);
14656 return NULL;
14657 }
14658 else {
14659 PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
14660 return NULL;
14661 }
14662 return PyLong_FromLong(exitcode);
14663#else
14664 /* Windows implementation: see os.waitpid() implementation
14665 which uses _cwait(). */
Victor Stinner9bee32b2020-04-22 16:30:35 +020014666 unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
14667 if (status == (unsigned long long)-1 && PyErr_Occurred()) {
14668 return NULL;
14669 }
14670
14671 unsigned long long exitcode = (status >> 8);
14672 /* ExitProcess() accepts an UINT type:
14673 reject exit code which doesn't fit in an UINT */
14674 if (exitcode > UINT_MAX) {
14675 PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
14676 return NULL;
14677 }
14678 return PyLong_FromUnsignedLong((unsigned long)exitcode);
Victor Stinner65a796e2020-04-01 18:49:29 +020014679#endif
14680}
14681#endif
14682
14683
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014684static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070014685
14686 OS_STAT_METHODDEF
14687 OS_ACCESS_METHODDEF
14688 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014689 OS_CHDIR_METHODDEF
14690 OS_CHFLAGS_METHODDEF
14691 OS_CHMOD_METHODDEF
14692 OS_FCHMOD_METHODDEF
14693 OS_LCHMOD_METHODDEF
14694 OS_CHOWN_METHODDEF
14695 OS_FCHOWN_METHODDEF
14696 OS_LCHOWN_METHODDEF
14697 OS_LCHFLAGS_METHODDEF
14698 OS_CHROOT_METHODDEF
14699 OS_CTERMID_METHODDEF
14700 OS_GETCWD_METHODDEF
14701 OS_GETCWDB_METHODDEF
14702 OS_LINK_METHODDEF
14703 OS_LISTDIR_METHODDEF
14704 OS_LSTAT_METHODDEF
14705 OS_MKDIR_METHODDEF
14706 OS_NICE_METHODDEF
14707 OS_GETPRIORITY_METHODDEF
14708 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014709 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030014710 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014711 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010014712 OS_COPY_FILE_RANGE_METHODDEF
Pablo Galindoa57b3d32020-11-17 00:00:38 +000014713 OS_SPLICE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014714 OS_RENAME_METHODDEF
14715 OS_REPLACE_METHODDEF
14716 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014717 OS_SYMLINK_METHODDEF
14718 OS_SYSTEM_METHODDEF
14719 OS_UMASK_METHODDEF
14720 OS_UNAME_METHODDEF
14721 OS_UNLINK_METHODDEF
14722 OS_REMOVE_METHODDEF
14723 OS_UTIME_METHODDEF
14724 OS_TIMES_METHODDEF
14725 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014726 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014727 OS_EXECV_METHODDEF
14728 OS_EXECVE_METHODDEF
14729 OS_SPAWNV_METHODDEF
14730 OS_SPAWNVE_METHODDEF
14731 OS_FORK1_METHODDEF
14732 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020014733 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014734 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14735 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14736 OS_SCHED_GETPARAM_METHODDEF
14737 OS_SCHED_GETSCHEDULER_METHODDEF
14738 OS_SCHED_RR_GET_INTERVAL_METHODDEF
14739 OS_SCHED_SETPARAM_METHODDEF
14740 OS_SCHED_SETSCHEDULER_METHODDEF
14741 OS_SCHED_YIELD_METHODDEF
14742 OS_SCHED_SETAFFINITY_METHODDEF
14743 OS_SCHED_GETAFFINITY_METHODDEF
14744 OS_OPENPTY_METHODDEF
14745 OS_FORKPTY_METHODDEF
14746 OS_GETEGID_METHODDEF
14747 OS_GETEUID_METHODDEF
14748 OS_GETGID_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014749 OS_GETGROUPLIST_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014750 OS_GETGROUPS_METHODDEF
14751 OS_GETPID_METHODDEF
14752 OS_GETPGRP_METHODDEF
14753 OS_GETPPID_METHODDEF
14754 OS_GETUID_METHODDEF
14755 OS_GETLOGIN_METHODDEF
14756 OS_KILL_METHODDEF
14757 OS_KILLPG_METHODDEF
14758 OS_PLOCK_METHODDEF
Steve Dowercc16be82016-09-08 10:35:16 -070014759 OS_STARTFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014760 OS_SETUID_METHODDEF
14761 OS_SETEUID_METHODDEF
14762 OS_SETREUID_METHODDEF
14763 OS_SETGID_METHODDEF
14764 OS_SETEGID_METHODDEF
14765 OS_SETREGID_METHODDEF
14766 OS_SETGROUPS_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014767 OS_INITGROUPS_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014768 OS_GETPGID_METHODDEF
14769 OS_SETPGRP_METHODDEF
14770 OS_WAIT_METHODDEF
14771 OS_WAIT3_METHODDEF
14772 OS_WAIT4_METHODDEF
14773 OS_WAITID_METHODDEF
14774 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080014775 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014776 OS_GETSID_METHODDEF
14777 OS_SETSID_METHODDEF
14778 OS_SETPGID_METHODDEF
14779 OS_TCGETPGRP_METHODDEF
14780 OS_TCSETPGRP_METHODDEF
14781 OS_OPEN_METHODDEF
14782 OS_CLOSE_METHODDEF
14783 OS_CLOSERANGE_METHODDEF
14784 OS_DEVICE_ENCODING_METHODDEF
14785 OS_DUP_METHODDEF
14786 OS_DUP2_METHODDEF
14787 OS_LOCKF_METHODDEF
14788 OS_LSEEK_METHODDEF
14789 OS_READ_METHODDEF
14790 OS_READV_METHODDEF
14791 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014792 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014793 OS_WRITE_METHODDEF
14794 OS_WRITEV_METHODDEF
14795 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014796 OS_PWRITEV_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014797 OS_SENDFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014798 OS_FSTAT_METHODDEF
14799 OS_ISATTY_METHODDEF
14800 OS_PIPE_METHODDEF
14801 OS_PIPE2_METHODDEF
14802 OS_MKFIFO_METHODDEF
14803 OS_MKNOD_METHODDEF
14804 OS_MAJOR_METHODDEF
14805 OS_MINOR_METHODDEF
14806 OS_MAKEDEV_METHODDEF
14807 OS_FTRUNCATE_METHODDEF
14808 OS_TRUNCATE_METHODDEF
14809 OS_POSIX_FALLOCATE_METHODDEF
14810 OS_POSIX_FADVISE_METHODDEF
14811 OS_PUTENV_METHODDEF
14812 OS_UNSETENV_METHODDEF
14813 OS_STRERROR_METHODDEF
14814 OS_FCHDIR_METHODDEF
14815 OS_FSYNC_METHODDEF
14816 OS_SYNC_METHODDEF
14817 OS_FDATASYNC_METHODDEF
14818 OS_WCOREDUMP_METHODDEF
14819 OS_WIFCONTINUED_METHODDEF
14820 OS_WIFSTOPPED_METHODDEF
14821 OS_WIFSIGNALED_METHODDEF
14822 OS_WIFEXITED_METHODDEF
14823 OS_WEXITSTATUS_METHODDEF
14824 OS_WTERMSIG_METHODDEF
14825 OS_WSTOPSIG_METHODDEF
14826 OS_FSTATVFS_METHODDEF
14827 OS_STATVFS_METHODDEF
14828 OS_CONFSTR_METHODDEF
14829 OS_SYSCONF_METHODDEF
14830 OS_FPATHCONF_METHODDEF
14831 OS_PATHCONF_METHODDEF
14832 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030014833 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014834 OS__GETDISKUSAGE_METHODDEF
14835 OS__GETFINALPATHNAME_METHODDEF
14836 OS__GETVOLUMEPATHNAME_METHODDEF
Steve Dower04732ca2021-04-07 01:02:07 +010014837 OS__PATH_SPLITROOT_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014838 OS_GETLOADAVG_METHODDEF
14839 OS_URANDOM_METHODDEF
14840 OS_SETRESUID_METHODDEF
14841 OS_SETRESGID_METHODDEF
14842 OS_GETRESUID_METHODDEF
14843 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000014844
Larry Hastings2f936352014-08-05 14:04:04 +100014845 OS_GETXATTR_METHODDEF
14846 OS_SETXATTR_METHODDEF
14847 OS_REMOVEXATTR_METHODDEF
14848 OS_LISTXATTR_METHODDEF
14849
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014850 OS_GET_TERMINAL_SIZE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014851 OS_CPU_COUNT_METHODDEF
14852 OS_GET_INHERITABLE_METHODDEF
14853 OS_SET_INHERITABLE_METHODDEF
14854 OS_GET_HANDLE_INHERITABLE_METHODDEF
14855 OS_SET_HANDLE_INHERITABLE_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014856 OS_GET_BLOCKING_METHODDEF
14857 OS_SET_BLOCKING_METHODDEF
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014858 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070014859 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070014860 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014861 OS_MEMFD_CREATE_METHODDEF
Christian Heimescd9fed62020-11-13 19:48:52 +010014862 OS_EVENTFD_METHODDEF
14863 OS_EVENTFD_READ_METHODDEF
14864 OS_EVENTFD_WRITE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070014865 OS__ADD_DLL_DIRECTORY_METHODDEF
14866 OS__REMOVE_DLL_DIRECTORY_METHODDEF
Victor Stinner65a796e2020-04-01 18:49:29 +020014867 OS_WAITSTATUS_TO_EXITCODE_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014868 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014869};
14870
Barry Warsaw4a342091996-12-19 23:50:02 +000014871static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014872all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000014873{
Guido van Rossum94f6f721999-01-06 18:42:14 +000014874#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014875 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014876#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014877#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014878 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014879#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014880#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014881 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014882#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014883#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014884 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014885#endif
Fred Drakec9680921999-12-13 16:37:25 +000014886#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014887 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000014888#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014889#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014890 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014891#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014892#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014893 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014894#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014895#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014896 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014897#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014898#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014899 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014900#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014901#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014902 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014903#endif
14904#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014905 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014906#endif
14907#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014908 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014909#endif
14910#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014911 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014912#endif
14913#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014914 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014915#endif
14916#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014917 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014918#endif
14919#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014920 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014921#endif
14922#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014923 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014924#endif
14925#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014926 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014927#endif
14928#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014929 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014930#endif
14931#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014932 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014933#endif
14934#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014935 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014936#endif
14937#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014938 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014939#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014940#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014941 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014942#endif
14943#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014944 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014945#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014946#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014947 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014948#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014949#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014950 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014951#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014952#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014953#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014954 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014955#endif
14956#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014957 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014958#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014959#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014960#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014961 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014962#endif
14963#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014964 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014965#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014966#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014967 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014968#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014969#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014970 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014971#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014972#ifdef O_TMPFILE
14973 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14974#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014975#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014976 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014977#endif
14978#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014979 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014980#endif
14981#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014982 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014983#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014984#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014985 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014986#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014987#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014988 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014989#endif
Dong-hee Naf917c242021-02-04 08:32:55 +090014990#ifdef O_EVTONLY
14991 if (PyModule_AddIntMacro(m, O_EVTONLY)) return -1;
14992#endif
14993#ifdef O_FSYNC
14994 if (PyModule_AddIntMacro(m, O_FSYNC)) return -1;
14995#endif
14996#ifdef O_SYMLINK
14997 if (PyModule_AddIntMacro(m, O_SYMLINK)) return -1;
14998#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014999
Jesus Cea94363612012-06-22 18:32:07 +020015000#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015001 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020015002#endif
15003#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015004 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020015005#endif
15006
Tim Peters5aa91602002-01-30 05:46:57 +000015007/* MS Windows */
15008#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000015009 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015010 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000015011#endif
15012#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000015013 /* Optimize for short life (keep in memory). */
15014 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015015 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000015016#endif
15017#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000015018 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015019 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000015020#endif
15021#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000015022 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015023 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000015024#endif
15025#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000015026 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015027 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000015028#endif
15029
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015030/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000015031#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000015032 /* Send a SIGIO signal whenever input or output
15033 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015034 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000015035#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015036#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000015037 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015038 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015039#endif
15040#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000015041 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015042 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015043#endif
15044#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000015045 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015046 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015047#endif
Dong-hee Naf917c242021-02-04 08:32:55 +090015048#ifdef O_NOFOLLOW_ANY
15049 if (PyModule_AddIntMacro(m, O_NOFOLLOW_ANY)) return -1;
15050#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020015051#ifdef O_NOLINKS
15052 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015053 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020015054#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000015055#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000015056 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015057 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000015058#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000015059
Victor Stinner8c62be82010-05-06 00:08:46 +000015060 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015061#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015062 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015063#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015064#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015065 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015066#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015067#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015068 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015069#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015070#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015071 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015072#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015073#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015074 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015075#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015076#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015077 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015078#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015079#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015080 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015081#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015082#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015083 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015084#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015085#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015086 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015087#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015088#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015089 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015090#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015091#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015092 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015093#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015094#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015095 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015096#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015097#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015098 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015099#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015100#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015101 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015102#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015103#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015104 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015105#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015106#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015107 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015108#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015109#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015110 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015111#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015112
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000015113 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015114#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015115 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015116#endif /* ST_RDONLY */
15117#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015118 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015119#endif /* ST_NOSUID */
15120
doko@ubuntu.comca616a22013-12-08 15:23:07 +010015121 /* GNU extensions */
15122#ifdef ST_NODEV
15123 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
15124#endif /* ST_NODEV */
15125#ifdef ST_NOEXEC
15126 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
15127#endif /* ST_NOEXEC */
15128#ifdef ST_SYNCHRONOUS
15129 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
15130#endif /* ST_SYNCHRONOUS */
15131#ifdef ST_MANDLOCK
15132 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
15133#endif /* ST_MANDLOCK */
15134#ifdef ST_WRITE
15135 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
15136#endif /* ST_WRITE */
15137#ifdef ST_APPEND
15138 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
15139#endif /* ST_APPEND */
15140#ifdef ST_NOATIME
15141 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
15142#endif /* ST_NOATIME */
15143#ifdef ST_NODIRATIME
15144 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
15145#endif /* ST_NODIRATIME */
15146#ifdef ST_RELATIME
15147 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
15148#endif /* ST_RELATIME */
15149
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015150 /* FreeBSD sendfile() constants */
15151#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015152 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015153#endif
15154#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015155 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015156#endif
15157#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015158 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015159#endif
15160
Ross Lagerwall7807c352011-03-17 20:20:30 +020015161 /* constants for posix_fadvise */
15162#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015163 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015164#endif
15165#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015166 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015167#endif
15168#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015169 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015170#endif
15171#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015172 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015173#endif
15174#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015175 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015176#endif
15177#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015178 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015179#endif
15180
15181 /* constants for waitid */
15182#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015183 if (PyModule_AddIntMacro(m, P_PID)) return -1;
15184 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
15185 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080015186#ifdef P_PIDFD
15187 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
15188#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015189#endif
15190#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015191 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015192#endif
15193#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015194 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015195#endif
15196#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015197 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015198#endif
15199#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015200 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015201#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090015202#ifdef CLD_KILLED
15203 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
15204#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015205#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015206 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015207#endif
15208#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015209 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015210#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090015211#ifdef CLD_STOPPED
15212 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
15213#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015214#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015215 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015216#endif
15217
15218 /* constants for lockf */
15219#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015220 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015221#endif
15222#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015223 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015224#endif
15225#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015226 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015227#endif
15228#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015229 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015230#endif
15231
Pablo Galindo4defba32018-01-27 16:16:37 +000015232#ifdef RWF_DSYNC
15233 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
15234#endif
15235#ifdef RWF_HIPRI
15236 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
15237#endif
15238#ifdef RWF_SYNC
15239 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
15240#endif
15241#ifdef RWF_NOWAIT
15242 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
15243#endif
YoSTEALTH76ef2552020-05-27 15:32:22 -060015244#ifdef RWF_APPEND
15245 if (PyModule_AddIntConstant(m, "RWF_APPEND", RWF_APPEND)) return -1;
15246#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000015247
Pablo Galindoa57b3d32020-11-17 00:00:38 +000015248/* constants for splice */
Pablo Galindo2a9eddf2020-11-17 19:57:49 +000015249#if defined(HAVE_SPLICE) && defined(__linux__)
Pablo Galindoa57b3d32020-11-17 00:00:38 +000015250 if (PyModule_AddIntConstant(m, "SPLICE_F_MOVE", SPLICE_F_MOVE)) return -1;
15251 if (PyModule_AddIntConstant(m, "SPLICE_F_NONBLOCK", SPLICE_F_NONBLOCK)) return -1;
15252 if (PyModule_AddIntConstant(m, "SPLICE_F_MORE", SPLICE_F_MORE)) return -1;
15253#endif
15254
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000015255/* constants for posix_spawn */
15256#ifdef HAVE_POSIX_SPAWN
15257 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
15258 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
15259 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
15260#endif
15261
pxinwrf2d7ac72019-05-21 18:46:37 +080015262#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015263 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
15264 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015265 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080015266#endif
15267#ifdef HAVE_SPAWNV
15268 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015269 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000015270#endif
15271
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015272#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015273#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015274 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015275#endif
15276#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015277 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015278#endif
15279#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015280 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015281#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015282#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080015283 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015284#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015285#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015286 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015287#endif
15288#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015289 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015290#endif
15291#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015292 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015293#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015294#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015295 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015296#endif
15297#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015298 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015299#endif
15300#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015301 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015302#endif
15303#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015304 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015305#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015306#endif
15307
Benjamin Peterson9428d532011-09-14 11:45:52 -040015308#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015309 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
15310 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
15311 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015312#endif
15313
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015314#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015315 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015316#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015317#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015318 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015319#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015320#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015321 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015322#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015323#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015324 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015325#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015326#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015327 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015328#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015329#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015330 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015331#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015332#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015333 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015334#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010015335#if HAVE_DECL_RTLD_MEMBER
15336 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
15337#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020015338
Victor Stinner9b1f4742016-09-06 16:18:52 -070015339#ifdef HAVE_GETRANDOM_SYSCALL
15340 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
15341 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
15342#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015343#ifdef HAVE_MEMFD_CREATE
15344 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
15345 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
15346#ifdef MFD_HUGETLB
15347 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015348#endif
15349#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015350 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015351#endif
15352#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015353 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015354#endif
15355#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015356 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015357#endif
15358#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015359 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015360#endif
15361#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015362 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015363#endif
15364#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015365 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015366#endif
15367#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015368 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015369#endif
15370#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015371 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015372#endif
15373#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015374 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015375#endif
15376#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015377 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015378#endif
15379#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015380 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015381#endif
15382#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015383 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015384#endif
15385#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015386 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015387#endif
15388#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015389 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
15390#endif
Christian Heimescd9fed62020-11-13 19:48:52 +010015391#endif /* HAVE_MEMFD_CREATE */
15392
15393#ifdef HAVE_EVENTFD
15394 if (PyModule_AddIntMacro(m, EFD_CLOEXEC)) return -1;
15395 if (PyModule_AddIntMacro(m, EFD_NONBLOCK)) return -1;
15396 if (PyModule_AddIntMacro(m, EFD_SEMAPHORE)) return -1;
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015397#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070015398
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020015399#if defined(__APPLE__)
15400 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
15401#endif
15402
Steve Dower2438cdf2019-03-29 16:37:16 -070015403#ifdef MS_WINDOWS
15404 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
15405 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
15406 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
15407 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
15408 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
15409#endif
15410
Victor Stinner8c62be82010-05-06 00:08:46 +000015411 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000015412}
15413
15414
Ronald Oussoren41761932020-11-08 10:05:27 +010015415
15416#define PROBE(name, test) \
15417 static int name(void) \
15418 { \
15419 if (test) { \
15420 return 1; \
15421 } else { \
15422 return 0; \
15423 } \
15424 }
15425
15426#ifdef HAVE_FSTATAT
15427PROBE(probe_fstatat, HAVE_FSTATAT_RUNTIME)
15428#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070015429
15430#ifdef HAVE_FACCESSAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015431PROBE(probe_faccessat, HAVE_FACCESSAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015432#endif
15433
15434#ifdef HAVE_FCHMODAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015435PROBE(probe_fchmodat, HAVE_FCHMODAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015436#endif
15437
Larry Hastings00964ed2013-08-12 13:49:30 -040015438#ifdef HAVE_FCHOWNAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015439PROBE(probe_fchownat, HAVE_FCHOWNAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015440#endif
15441
15442#ifdef HAVE_LINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015443PROBE(probe_linkat, HAVE_LINKAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015444#endif
15445
Ronald Oussoren41761932020-11-08 10:05:27 +010015446#ifdef HAVE_FDOPENDIR
15447PROBE(probe_fdopendir, HAVE_FDOPENDIR_RUNTIME)
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015448#endif
15449
Larry Hastings9cf065c2012-06-22 16:30:09 -070015450#ifdef HAVE_MKDIRAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015451PROBE(probe_mkdirat, HAVE_MKDIRAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015452#endif
15453
15454#ifdef HAVE_RENAMEAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015455PROBE(probe_renameat, HAVE_RENAMEAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015456#endif
15457
15458#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015459PROBE(probe_unlinkat, HAVE_UNLINKAT_RUNTIME)
15460#endif
15461
15462#ifdef HAVE_OPENAT
15463PROBE(probe_openat, HAVE_OPENAT_RUNTIME)
15464#endif
15465
15466#ifdef HAVE_READLINKAT
15467PROBE(probe_readlinkat, HAVE_READLINKAT_RUNTIME)
15468#endif
15469
15470#ifdef HAVE_SYMLINKAT
15471PROBE(probe_symlinkat, HAVE_SYMLINKAT_RUNTIME)
15472#endif
15473
15474#ifdef HAVE_FUTIMENS
15475PROBE(probe_futimens, HAVE_FUTIMENS_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015476#endif
15477
15478#ifdef HAVE_UTIMENSAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015479PROBE(probe_utimensat, HAVE_UTIMENSAT_RUNTIME)
15480#endif
15481
15482
15483
15484
15485static const struct have_function {
15486 const char * const label;
15487 int (*probe)(void);
15488} have_functions[] = {
15489
Christian Heimescd9fed62020-11-13 19:48:52 +010015490#ifdef HAVE_EVENTFD
15491 {"HAVE_EVENTFD", NULL},
15492#endif
15493
Ronald Oussoren41761932020-11-08 10:05:27 +010015494#ifdef HAVE_FACCESSAT
15495 { "HAVE_FACCESSAT", probe_faccessat },
15496#endif
15497
15498#ifdef HAVE_FCHDIR
15499 { "HAVE_FCHDIR", NULL },
15500#endif
15501
15502#ifdef HAVE_FCHMOD
15503 { "HAVE_FCHMOD", NULL },
15504#endif
15505
15506#ifdef HAVE_FCHMODAT
15507 { "HAVE_FCHMODAT", probe_fchmodat },
15508#endif
15509
15510#ifdef HAVE_FCHOWN
15511 { "HAVE_FCHOWN", NULL },
15512#endif
15513
15514#ifdef HAVE_FCHOWNAT
15515 { "HAVE_FCHOWNAT", probe_fchownat },
15516#endif
15517
15518#ifdef HAVE_FEXECVE
15519 { "HAVE_FEXECVE", NULL },
15520#endif
15521
15522#ifdef HAVE_FDOPENDIR
15523 { "HAVE_FDOPENDIR", probe_fdopendir },
15524#endif
15525
15526#ifdef HAVE_FPATHCONF
15527 { "HAVE_FPATHCONF", NULL },
15528#endif
15529
15530#ifdef HAVE_FSTATAT
15531 { "HAVE_FSTATAT", probe_fstatat },
15532#endif
15533
15534#ifdef HAVE_FSTATVFS
15535 { "HAVE_FSTATVFS", NULL },
15536#endif
15537
15538#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
15539 { "HAVE_FTRUNCATE", NULL },
15540#endif
15541
15542#ifdef HAVE_FUTIMENS
15543 { "HAVE_FUTIMENS", probe_futimens },
15544#endif
15545
15546#ifdef HAVE_FUTIMES
15547 { "HAVE_FUTIMES", NULL },
15548#endif
15549
15550#ifdef HAVE_FUTIMESAT
15551 { "HAVE_FUTIMESAT", NULL },
15552#endif
15553
15554#ifdef HAVE_LINKAT
15555 { "HAVE_LINKAT", probe_linkat },
15556#endif
15557
15558#ifdef HAVE_LCHFLAGS
15559 { "HAVE_LCHFLAGS", NULL },
15560#endif
15561
15562#ifdef HAVE_LCHMOD
15563 { "HAVE_LCHMOD", NULL },
15564#endif
15565
15566#ifdef HAVE_LCHOWN
15567 { "HAVE_LCHOWN", NULL },
15568#endif
15569
15570#ifdef HAVE_LSTAT
15571 { "HAVE_LSTAT", NULL },
15572#endif
15573
15574#ifdef HAVE_LUTIMES
15575 { "HAVE_LUTIMES", NULL },
15576#endif
15577
15578#ifdef HAVE_MEMFD_CREATE
15579 { "HAVE_MEMFD_CREATE", NULL },
15580#endif
15581
15582#ifdef HAVE_MKDIRAT
15583 { "HAVE_MKDIRAT", probe_mkdirat },
15584#endif
15585
15586#ifdef HAVE_MKFIFOAT
15587 { "HAVE_MKFIFOAT", NULL },
15588#endif
15589
15590#ifdef HAVE_MKNODAT
15591 { "HAVE_MKNODAT", NULL },
15592#endif
15593
15594#ifdef HAVE_OPENAT
15595 { "HAVE_OPENAT", probe_openat },
15596#endif
15597
15598#ifdef HAVE_READLINKAT
15599 { "HAVE_READLINKAT", probe_readlinkat },
15600#endif
15601
15602#ifdef HAVE_RENAMEAT
15603 { "HAVE_RENAMEAT", probe_renameat },
15604#endif
15605
15606#ifdef HAVE_SYMLINKAT
15607 { "HAVE_SYMLINKAT", probe_symlinkat },
15608#endif
15609
15610#ifdef HAVE_UNLINKAT
15611 { "HAVE_UNLINKAT", probe_unlinkat },
15612#endif
15613
15614#ifdef HAVE_UTIMENSAT
15615 { "HAVE_UTIMENSAT", probe_utimensat },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015616#endif
15617
15618#ifdef MS_WINDOWS
Ronald Oussoren41761932020-11-08 10:05:27 +010015619 { "MS_WINDOWS", NULL },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015620#endif
15621
Ronald Oussoren41761932020-11-08 10:05:27 +010015622 { NULL, NULL }
Larry Hastings9cf065c2012-06-22 16:30:09 -070015623};
15624
15625
Victor Stinner1c2fa782020-05-10 11:05:29 +020015626static int
15627posixmodule_exec(PyObject *m)
Guido van Rossumb6775db1994-08-01 11:34:53 +000015628{
Victor Stinner97f33c32020-05-14 18:05:58 +020015629 _posixstate *state = get_posix_state(m);
Tim Peters5aa91602002-01-30 05:46:57 +000015630
Ronald Oussoren41761932020-11-08 10:05:27 +010015631#if defined(HAVE_PWRITEV)
15632 if (HAVE_PWRITEV_RUNTIME) {} else {
15633 PyObject* dct = PyModule_GetDict(m);
15634
15635 if (dct == NULL) {
15636 return -1;
15637 }
15638
15639 if (PyDict_DelItemString(dct, "pwritev") == -1) {
15640 PyErr_Clear();
15641 }
15642 if (PyDict_DelItemString(dct, "preadv") == -1) {
15643 PyErr_Clear();
15644 }
15645 }
15646#endif
15647
Victor Stinner8c62be82010-05-06 00:08:46 +000015648 /* Initialize environ dictionary */
Victor Stinner97f33c32020-05-14 18:05:58 +020015649 PyObject *v = convertenviron();
Victor Stinner8c62be82010-05-06 00:08:46 +000015650 Py_XINCREF(v);
15651 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015652 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015653 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000015654
Victor Stinner8c62be82010-05-06 00:08:46 +000015655 if (all_ins(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015656 return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000015657
Victor Stinner8c62be82010-05-06 00:08:46 +000015658 if (setup_confname_tables(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015659 return -1;
Fred Drakebec628d1999-12-15 18:31:10 +000015660
Victor Stinner8c62be82010-05-06 00:08:46 +000015661 Py_INCREF(PyExc_OSError);
15662 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000015663
Ross Lagerwall7807c352011-03-17 20:20:30 +020015664#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080015665 waitid_result_desc.name = MODNAME ".waitid_result";
15666 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
15667 if (WaitidResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015668 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015669 }
15670 Py_INCREF(WaitidResultType);
15671 PyModule_AddObject(m, "waitid_result", WaitidResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015672 state->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015673#endif
15674
Eddie Elizondob3966632019-11-05 07:16:14 -080015675 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
15676 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
15677 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
15678 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
15679 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
15680 if (StatResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015681 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015682 }
15683 Py_INCREF(StatResultType);
15684 PyModule_AddObject(m, "stat_result", StatResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015685 state->StatResultType = StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015686 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
15687 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015688
Eddie Elizondob3966632019-11-05 07:16:14 -080015689 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
15690 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
15691 if (StatVFSResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015692 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015693 }
15694 Py_INCREF(StatVFSResultType);
15695 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015696 state->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015697#ifdef NEED_TICKS_PER_SECOND
15698# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080015699 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015700# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080015701 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015702# else
Eddie Elizondob3966632019-11-05 07:16:14 -080015703 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015704# endif
15705#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015706
William Orr81574b82018-10-01 22:19:56 -070015707#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080015708 sched_param_desc.name = MODNAME ".sched_param";
15709 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
15710 if (SchedParamType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015711 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015712 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015713 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080015714 PyModule_AddObject(m, "sched_param", SchedParamType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015715 state->SchedParamType = SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015716 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050015717#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000015718
Eddie Elizondob3966632019-11-05 07:16:14 -080015719 /* initialize TerminalSize_info */
15720 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
15721 if (TerminalSizeType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015722 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015723 }
15724 Py_INCREF(TerminalSizeType);
15725 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015726 state->TerminalSizeType = TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015727
15728 /* initialize scandir types */
Victor Stinner1c2fa782020-05-10 11:05:29 +020015729 PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015730 if (ScandirIteratorType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015731 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015732 }
Victor Stinner97f33c32020-05-14 18:05:58 +020015733 state->ScandirIteratorType = ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015734
Victor Stinner1c2fa782020-05-10 11:05:29 +020015735 PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015736 if (DirEntryType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015737 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015738 }
15739 Py_INCREF(DirEntryType);
15740 PyModule_AddObject(m, "DirEntry", DirEntryType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015741 state->DirEntryType = DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015742
Larry Hastings605a62d2012-06-24 04:33:36 -070015743 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080015744 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015745 if (TimesResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015746 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015747 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015748 Py_INCREF(TimesResultType);
15749 PyModule_AddObject(m, "times_result", TimesResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015750 state->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015751
Eddie Elizondob3966632019-11-05 07:16:14 -080015752 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015753 if (UnameResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015754 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015755 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015756 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015757 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015758 state->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015759
Victor Stinner97f33c32020-05-14 18:05:58 +020015760 if ((state->billion = PyLong_FromLong(1000000000)) == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015761 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015762#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +020015763 state->struct_rusage = PyUnicode_InternFromString("struct_rusage");
15764 if (state->struct_rusage == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015765 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015766#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020015767 state->st_mode = PyUnicode_InternFromString("st_mode");
15768 if (state->st_mode == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015769 return -1;
Larry Hastings6fe20b32012-04-19 15:07:49 -070015770
Larry Hastings9cf065c2012-06-22 16:30:09 -070015771 /* suppress "function not used" warnings */
15772 {
15773 int ignored;
15774 fd_specified("", -1);
15775 follow_symlinks_specified("", 1);
15776 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
15777 dir_fd_converter(Py_None, &ignored);
15778 dir_fd_unavailable(Py_None, &ignored);
15779 }
15780
15781 /*
15782 * provide list of locally available functions
15783 * so os.py can populate support_* lists
15784 */
Victor Stinner97f33c32020-05-14 18:05:58 +020015785 PyObject *list = PyList_New(0);
15786 if (!list) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015787 return -1;
Victor Stinner97f33c32020-05-14 18:05:58 +020015788 }
Ronald Oussoren41761932020-11-08 10:05:27 +010015789 for (const struct have_function *trace = have_functions; trace->label; trace++) {
15790 PyObject *unicode;
15791 if (trace->probe && !trace->probe()) continue;
15792 unicode = PyUnicode_DecodeASCII(trace->label, strlen(trace->label), NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015793 if (!unicode)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015794 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015795 if (PyList_Append(list, unicode))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015796 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015797 Py_DECREF(unicode);
15798 }
Ronald Oussoren41761932020-11-08 10:05:27 +010015799
Larry Hastings9cf065c2012-06-22 16:30:09 -070015800 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040015801
Victor Stinner1c2fa782020-05-10 11:05:29 +020015802 return 0;
15803}
15804
15805
15806static PyModuleDef_Slot posixmodile_slots[] = {
15807 {Py_mod_exec, posixmodule_exec},
15808 {0, NULL}
15809};
15810
15811static struct PyModuleDef posixmodule = {
15812 PyModuleDef_HEAD_INIT,
15813 .m_name = MODNAME,
15814 .m_doc = posix__doc__,
15815 .m_size = sizeof(_posixstate),
15816 .m_methods = posix_methods,
15817 .m_slots = posixmodile_slots,
15818 .m_traverse = _posix_traverse,
15819 .m_clear = _posix_clear,
15820 .m_free = _posix_free,
15821};
15822
15823PyMODINIT_FUNC
15824INITFUNC(void)
15825{
15826 return PyModuleDef_Init(&posixmodule);
Guido van Rossumb6775db1994-08-01 11:34:53 +000015827}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015828
15829#ifdef __cplusplus
15830}
15831#endif