blob: 321eaec63c4a489e446f83021cbc832af5c098e5 [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 Wouters477c8d52006-05-27 19:21:47 +000010#ifdef __APPLE__
11 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000012 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000013 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
14 * at the end of this file for more information.
15 */
16# pragma weak lchown
17# pragma weak statvfs
18# pragma weak fstatvfs
19
20#endif /* __APPLE__ */
21
Thomas Wouters68bc4f92006-03-01 01:05:10 +000022#define PY_SSIZE_T_CLEAN
23
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000024#include "Python.h"
Victor Stinnerd5d9e812019-05-13 12:35:37 +020025#ifdef MS_WINDOWS
26 /* include <windows.h> early to avoid conflict with pycore_condvar.h:
27
28 #define WIN32_LEAN_AND_MEAN
29 #include <windows.h>
30
31 FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */
32# include <windows.h>
33#endif
34
pxinwr3405e052020-08-07 13:21:52 +080035#ifdef __VXWORKS__
36# include "pycore_bitutils.h" // _Py_popcount32()
37#endif
Victor Stinner4a21e572020-04-15 02:35:41 +020038#include "pycore_ceval.h" // _PyEval_ReInitThreads()
39#include "pycore_import.h" // _PyImport_ReInitLock()
Victor Stinner26881c82020-06-02 15:51:37 +020040#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
Victor Stinner4a21e572020-04-15 02:35:41 +020041#include "pycore_pystate.h" // _PyInterpreterState_GET()
42#include "structmember.h" // PyMemberDef
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020043#ifndef MS_WINDOWS
Victor Stinnerd5d9e812019-05-13 12:35:37 +020044# include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010045#else
Victor Stinnerd5d9e812019-05-13 12:35:37 +020046# include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020047#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000048
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020049/* On android API level 21, 'AT_EACCESS' is not declared although
50 * HAVE_FACCESSAT is defined. */
51#ifdef __ANDROID__
Victor Stinner5eca75d2020-04-15 15:07:31 +020052# undef HAVE_FACCESSAT
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020053#endif
54
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000055#include <stdio.h> /* needed for ctermid() */
56
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000057#ifdef __cplusplus
58extern "C" {
59#endif
60
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000061PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000062"This module provides access to operating system functionality that is\n\
63standardized by the C Standard and the POSIX standard (a thinly\n\
64disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000065corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000067
Ross Lagerwall4d076da2011-03-18 06:56:53 +020068#ifdef HAVE_SYS_UIO_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020069# include <sys/uio.h>
Ross Lagerwall4d076da2011-03-18 06:56:53 +020070#endif
71
Christian Heimes75b96182017-09-05 15:53:09 +020072#ifdef HAVE_SYS_SYSMACROS_H
73/* GNU C Library: major(), minor(), makedev() */
Victor Stinner5eca75d2020-04-15 15:07:31 +020074# include <sys/sysmacros.h>
Christian Heimes75b96182017-09-05 15:53:09 +020075#endif
76
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#ifdef HAVE_SYS_TYPES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020078# include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000079#endif /* HAVE_SYS_TYPES_H */
80
81#ifdef HAVE_SYS_STAT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020082# include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000083#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000084
Guido van Rossum36bc6801995-06-14 22:54:23 +000085#ifdef HAVE_SYS_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020086# include <sys/wait.h> // WNOHANG
Guido van Rossum36bc6801995-06-14 22:54:23 +000087#endif
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080088#ifdef HAVE_LINUX_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020089# include <linux/wait.h> // P_PIDFD
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080090#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000091
Thomas Wouters0e3f5912006-08-11 14:57:12 +000092#ifdef HAVE_SIGNAL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020093# include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000094#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000095
Guido van Rossumb6775db1994-08-01 11:34:53 +000096#ifdef HAVE_FCNTL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020097# include <fcntl.h>
98#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000099
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000100#ifdef HAVE_GRP_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200101# include <grp.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000102#endif
103
Barry Warsaw5676bd12003-01-07 20:57:09 +0000104#ifdef HAVE_SYSEXITS_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200105# include <sysexits.h>
106#endif
Barry Warsaw5676bd12003-01-07 20:57:09 +0000107
Anthony Baxter8a560de2004-10-13 15:30:56 +0000108#ifdef HAVE_SYS_LOADAVG_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200109# include <sys/loadavg.h>
Anthony Baxter8a560de2004-10-13 15:30:56 +0000110#endif
111
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000112#ifdef HAVE_SYS_SENDFILE_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200113# include <sys/sendfile.h>
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000114#endif
115
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200116#if defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200117# include <copyfile.h>
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200118#endif
119
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500120#ifdef HAVE_SCHED_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200121# include <sched.h>
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500122#endif
123
Pablo Galindoaac4d032019-05-31 19:39:47 +0100124#ifdef HAVE_COPY_FILE_RANGE
Victor Stinner5eca75d2020-04-15 15:07:31 +0200125# include <unistd.h>
Pablo Galindoaac4d032019-05-31 19:39:47 +0100126#endif
127
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500128#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200129# undef HAVE_SCHED_SETAFFINITY
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500130#endif
131
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200132#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200133# define USE_XATTRS
Benjamin Peterson9428d532011-09-14 11:45:52 -0400134#endif
135
136#ifdef USE_XATTRS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200137# include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400138#endif
139
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000140#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200141# ifdef HAVE_SYS_SOCKET_H
142# include <sys/socket.h>
143# endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000144#endif
145
Victor Stinner8b905bd2011-10-25 13:34:04 +0200146#ifdef HAVE_DLFCN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200147# include <dlfcn.h>
Victor Stinner8b905bd2011-10-25 13:34:04 +0200148#endif
149
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200150#ifdef __hpux
Victor Stinner5eca75d2020-04-15 15:07:31 +0200151# include <sys/mpctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200152#endif
153
154#if defined(__DragonFly__) || \
155 defined(__OpenBSD__) || \
156 defined(__FreeBSD__) || \
157 defined(__NetBSD__) || \
158 defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200159# include <sys/sysctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200160#endif
161
Victor Stinner9b1f4742016-09-06 16:18:52 -0700162#ifdef HAVE_LINUX_RANDOM_H
163# include <linux/random.h>
164#endif
165#ifdef HAVE_GETRANDOM_SYSCALL
166# include <sys/syscall.h>
167#endif
168
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100169#if defined(MS_WINDOWS)
170# define TERMSIZE_USE_CONIO
171#elif defined(HAVE_SYS_IOCTL_H)
172# include <sys/ioctl.h>
173# if defined(HAVE_TERMIOS_H)
174# include <termios.h>
175# endif
176# if defined(TIOCGWINSZ)
177# define TERMSIZE_USE_IOCTL
178# endif
179#endif /* MS_WINDOWS */
180
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000182/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000183#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200184# define HAVE_OPENDIR 1
185# define HAVE_SYSTEM 1
186# include <process.h>
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000187#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200188# ifdef _MSC_VER
189 /* Microsoft compiler */
190# define HAVE_GETPPID 1
191# define HAVE_GETLOGIN 1
192# define HAVE_SPAWNV 1
193# define HAVE_EXECV 1
194# define HAVE_WSPAWNV 1
195# define HAVE_WEXECV 1
196# define HAVE_PIPE 1
197# define HAVE_SYSTEM 1
198# define HAVE_CWAIT 1
199# define HAVE_FSYNC 1
200# define fsync _commit
201# else
202 /* Unix functions that the configure script doesn't check for */
203# ifndef __VXWORKS__
204# define HAVE_EXECV 1
205# define HAVE_FORK 1
206# if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
207# define HAVE_FORK1 1
208# endif
209# endif
210# define HAVE_GETEGID 1
211# define HAVE_GETEUID 1
212# define HAVE_GETGID 1
213# define HAVE_GETPPID 1
214# define HAVE_GETUID 1
215# define HAVE_KILL 1
216# define HAVE_OPENDIR 1
217# define HAVE_PIPE 1
218# define HAVE_SYSTEM 1
219# define HAVE_WAIT 1
220# define HAVE_TTYNAME 1
221# endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000222#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000223
Eddie Elizondob3966632019-11-05 07:16:14 -0800224_Py_IDENTIFIER(__fspath__);
Victor Stinnera2f7c002012-02-08 03:36:25 +0100225
Larry Hastings61272b72014-01-07 12:41:53 -0800226/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000227# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800228module os
Larry Hastings61272b72014-01-07 12:41:53 -0800229[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000230/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100231
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000233
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000234#if defined(__sgi)&&_COMPILER_VERSION>=700
235/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
236 (default) */
237extern char *ctermid_r(char *);
238#endif
239
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241
pxinwrf2d7ac72019-05-21 18:46:37 +0800242#if defined(__VXWORKS__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200243# include <vxCpuLib.h>
244# include <rtpLib.h>
245# include <wait.h>
246# include <taskLib.h>
247# ifndef _P_WAIT
248# define _P_WAIT 0
249# define _P_NOWAIT 1
250# define _P_NOWAITO 1
251# endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800252#endif /* __VXWORKS__ */
253
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000254#ifdef HAVE_POSIX_SPAWN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200255# include <spawn.h>
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000256#endif
257
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#ifdef HAVE_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200259# include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000260#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000262#ifdef HAVE_SYS_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200263# include <sys/utime.h>
264# define HAVE_UTIME_H /* pretend we do for the rest of this file */
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000265#endif /* HAVE_SYS_UTIME_H */
266
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#ifdef HAVE_SYS_TIMES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200268# include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000269#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270
271#ifdef HAVE_SYS_PARAM_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200272# include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274
275#ifdef HAVE_SYS_UTSNAME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200276# include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000277#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000279#ifdef HAVE_DIRENT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200280# include <dirent.h>
281# define NAMLEN(dirent) strlen((dirent)->d_name)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200283# if defined(__WATCOMC__) && !defined(__QNX__)
284# include <direct.h>
285# define NAMLEN(dirent) strlen((dirent)->d_name)
286# else
287# define dirent direct
288# define NAMLEN(dirent) (dirent)->d_namlen
289# endif
290# ifdef HAVE_SYS_NDIR_H
291# include <sys/ndir.h>
292# endif
293# ifdef HAVE_SYS_DIR_H
294# include <sys/dir.h>
295# endif
296# ifdef HAVE_NDIR_H
297# include <ndir.h>
298# endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000299#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000300
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000301#ifdef _MSC_VER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200302# ifdef HAVE_DIRECT_H
303# include <direct.h>
304# endif
305# ifdef HAVE_IO_H
306# include <io.h>
307# endif
308# ifdef HAVE_PROCESS_H
309# include <process.h>
310# endif
311# ifndef IO_REPARSE_TAG_SYMLINK
312# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
313# endif
314# ifndef IO_REPARSE_TAG_MOUNT_POINT
315# define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
316# endif
317# include "osdefs.h" // SEP
318# include <malloc.h>
319# include <windows.h>
320# include <shellapi.h> // ShellExecute()
321# include <lmcons.h> // UNLEN
322# define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000323#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000324
Tim Petersbc2e10e2002-03-03 23:17:02 +0000325#ifndef MAXPATHLEN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200326# if defined(PATH_MAX) && PATH_MAX > 1024
327# define MAXPATHLEN PATH_MAX
328# else
329# define MAXPATHLEN 1024
330# endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000331#endif /* MAXPATHLEN */
332
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000333#ifdef UNION_WAIT
Victor Stinner5eca75d2020-04-15 15:07:31 +0200334 /* Emulate some macros on systems that have a union instead of macros */
335# ifndef WIFEXITED
336# define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
337# endif
338# ifndef WEXITSTATUS
339# define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
340# endif
341# ifndef WTERMSIG
342# define WTERMSIG(u_wait) ((u_wait).w_termsig)
343# endif
344# define WAIT_TYPE union wait
345# define WAIT_STATUS_INT(s) (s.w_status)
346#else
347 /* !UNION_WAIT */
348# define WAIT_TYPE int
349# define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000350#endif /* UNION_WAIT */
351
Greg Wardb48bc172000-03-01 21:51:56 +0000352/* Don't use the "_r" form if we don't need it (also, won't have a
353 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200354#if defined(HAVE_CTERMID_R)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200355# define USE_CTERMID_R
Greg Wardb48bc172000-03-01 21:51:56 +0000356#endif
357
Fred Drake699f3522000-06-29 21:12:41 +0000358/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000359#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000360#undef FSTAT
361#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200362#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200363# define STAT win32_stat
364# define LSTAT win32_lstat
365# define FSTAT _Py_fstat_noraise
366# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000367#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200368# define STAT stat
369# define LSTAT lstat
370# define FSTAT fstat
371# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000372#endif
373
Tim Peters11b23062003-04-23 02:39:17 +0000374#if defined(MAJOR_IN_MKDEV)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200375# include <sys/mkdev.h>
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000376#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200377# if defined(MAJOR_IN_SYSMACROS)
378# include <sys/sysmacros.h>
379# endif
380# if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
381# include <sys/mkdev.h>
382# endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000383#endif
Fred Drake699f3522000-06-29 21:12:41 +0000384
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200385#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200386# define INITFUNC PyInit_nt
387# define MODNAME "nt"
Victor Stinner6036e442015-03-08 01:58:04 +0100388#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200389# define INITFUNC PyInit_posix
390# define MODNAME "posix"
Victor Stinner6036e442015-03-08 01:58:04 +0100391#endif
392
jcea6c51d512018-01-28 14:00:08 +0100393#if defined(__sun)
394/* Something to implement in autoconf, not present in autoconf 2.69 */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200395# define HAVE_STRUCT_STAT_ST_FSTYPE 1
jcea6c51d512018-01-28 14:00:08 +0100396#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200397
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600398/* memfd_create is either defined in sys/mman.h or sys/memfd.h
399 * linux/memfd.h defines additional flags
400 */
401#ifdef HAVE_SYS_MMAN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200402# include <sys/mman.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600403#endif
404#ifdef HAVE_SYS_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200405# include <sys/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600406#endif
407#ifdef HAVE_LINUX_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200408# include <linux/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600409#endif
410
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800411#ifdef _Py_MEMORY_SANITIZER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200412# include <sanitizer/msan_interface.h>
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800413#endif
414
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200415#ifdef HAVE_FORK
416static void
417run_at_forkers(PyObject *lst, int reverse)
418{
419 Py_ssize_t i;
420 PyObject *cpy;
421
422 if (lst != NULL) {
423 assert(PyList_CheckExact(lst));
424
425 /* Use a list copy in case register_at_fork() is called from
426 * one of the callbacks.
427 */
428 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
429 if (cpy == NULL)
430 PyErr_WriteUnraisable(lst);
431 else {
432 if (reverse)
433 PyList_Reverse(cpy);
434 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
435 PyObject *func, *res;
436 func = PyList_GET_ITEM(cpy, i);
Jeroen Demeyer7f41c8e2019-07-04 12:35:31 +0200437 res = _PyObject_CallNoArg(func);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200438 if (res == NULL)
439 PyErr_WriteUnraisable(func);
440 else
441 Py_DECREF(res);
442 }
443 Py_DECREF(cpy);
444 }
445 }
446}
447
448void
449PyOS_BeforeFork(void)
450{
Victor Stinner81a7be32020-04-14 15:14:01 +0200451 run_at_forkers(_PyInterpreterState_GET()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200452
453 _PyImport_AcquireLock();
454}
455
456void
457PyOS_AfterFork_Parent(void)
458{
459 if (_PyImport_ReleaseLock() <= 0)
460 Py_FatalError("failed releasing import lock after fork");
461
Victor Stinner81a7be32020-04-14 15:14:01 +0200462 run_at_forkers(_PyInterpreterState_GET()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200463}
464
465void
466PyOS_AfterFork_Child(void)
467{
Victor Stinner26881c82020-06-02 15:51:37 +0200468 PyStatus status;
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200469 _PyRuntimeState *runtime = &_PyRuntime;
Victor Stinner26881c82020-06-02 15:51:37 +0200470
471 status = _PyGILState_Reinit(runtime);
472 if (_PyStatus_EXCEPTION(status)) {
473 goto fatal_error;
474 }
475
Victor Stinner317bab02020-06-02 18:44:54 +0200476 PyThreadState *tstate = _PyThreadState_GET();
477 _Py_EnsureTstateNotNULL(tstate);
478
479 status = _PyEval_ReInitThreads(tstate);
Victor Stinner26881c82020-06-02 15:51:37 +0200480 if (_PyStatus_EXCEPTION(status)) {
481 goto fatal_error;
482 }
483
484 status = _PyImport_ReInitLock();
485 if (_PyStatus_EXCEPTION(status)) {
486 goto fatal_error;
487 }
488
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200489 _PySignal_AfterFork();
Victor Stinner26881c82020-06-02 15:51:37 +0200490
491 status = _PyRuntimeState_ReInitThreads(runtime);
492 if (_PyStatus_EXCEPTION(status)) {
493 goto fatal_error;
494 }
495
496 status = _PyInterpreterState_DeleteExceptMain(runtime);
497 if (_PyStatus_EXCEPTION(status)) {
498 goto fatal_error;
499 }
Victor Stinner317bab02020-06-02 18:44:54 +0200500 assert(_PyThreadState_GET() == tstate);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200501
Victor Stinner317bab02020-06-02 18:44:54 +0200502 run_at_forkers(tstate->interp->after_forkers_child, 0);
Victor Stinner26881c82020-06-02 15:51:37 +0200503 return;
504
505fatal_error:
506 Py_ExitStatusException(status);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200507}
508
509static int
510register_at_forker(PyObject **lst, PyObject *func)
511{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700512 if (func == NULL) /* nothing to register? do nothing. */
513 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200514 if (*lst == NULL) {
515 *lst = PyList_New(0);
516 if (*lst == NULL)
517 return -1;
518 }
519 return PyList_Append(*lst, func);
520}
Victor Stinner87255be2020-04-07 23:11:49 +0200521#endif /* HAVE_FORK */
522
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200523
524/* Legacy wrapper */
525void
526PyOS_AfterFork(void)
527{
528#ifdef HAVE_FORK
529 PyOS_AfterFork_Child();
530#endif
531}
532
533
Victor Stinner6036e442015-03-08 01:58:04 +0100534#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200535/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700536void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
537void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200538 ULONG, struct _Py_stat_struct *);
539#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700540
Larry Hastings9cf065c2012-06-22 16:30:09 -0700541
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200542#ifndef MS_WINDOWS
543PyObject *
544_PyLong_FromUid(uid_t uid)
545{
546 if (uid == (uid_t)-1)
547 return PyLong_FromLong(-1);
548 return PyLong_FromUnsignedLong(uid);
549}
550
551PyObject *
552_PyLong_FromGid(gid_t gid)
553{
554 if (gid == (gid_t)-1)
555 return PyLong_FromLong(-1);
556 return PyLong_FromUnsignedLong(gid);
557}
558
559int
560_Py_Uid_Converter(PyObject *obj, void *p)
561{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700562 uid_t uid;
563 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200564 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200565 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700566 unsigned long uresult;
567
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300568 index = _PyNumber_Index(obj);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700569 if (index == NULL) {
570 PyErr_Format(PyExc_TypeError,
571 "uid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800572 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200573 return 0;
574 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700575
576 /*
577 * Handling uid_t is complicated for two reasons:
578 * * Although uid_t is (always?) unsigned, it still
579 * accepts -1.
580 * * We don't know its size in advance--it may be
581 * bigger than an int, or it may be smaller than
582 * a long.
583 *
584 * So a bit of defensive programming is in order.
585 * Start with interpreting the value passed
586 * in as a signed long and see if it works.
587 */
588
589 result = PyLong_AsLongAndOverflow(index, &overflow);
590
591 if (!overflow) {
592 uid = (uid_t)result;
593
594 if (result == -1) {
595 if (PyErr_Occurred())
596 goto fail;
597 /* It's a legitimate -1, we're done. */
598 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200599 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700600
601 /* Any other negative number is disallowed. */
602 if (result < 0)
603 goto underflow;
604
605 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200606 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700607 (long)uid != result)
608 goto underflow;
609 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200610 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700611
612 if (overflow < 0)
613 goto underflow;
614
615 /*
616 * Okay, the value overflowed a signed long. If it
617 * fits in an *unsigned* long, it may still be okay,
618 * as uid_t may be unsigned long on this platform.
619 */
620 uresult = PyLong_AsUnsignedLong(index);
621 if (PyErr_Occurred()) {
622 if (PyErr_ExceptionMatches(PyExc_OverflowError))
623 goto overflow;
624 goto fail;
625 }
626
627 uid = (uid_t)uresult;
628
629 /*
630 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
631 * but this value would get interpreted as (uid_t)-1 by chown
632 * and its siblings. That's not what the user meant! So we
633 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100634 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700635 */
636 if (uid == (uid_t)-1)
637 goto overflow;
638
639 /* Ensure the value wasn't truncated. */
640 if (sizeof(uid_t) < sizeof(long) &&
641 (unsigned long)uid != uresult)
642 goto overflow;
643 /* fallthrough */
644
645success:
646 Py_DECREF(index);
647 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200648 return 1;
649
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700650underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200651 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700652 "uid is less than minimum");
653 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200654
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700655overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200656 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700657 "uid is greater than maximum");
658 /* fallthrough */
659
660fail:
661 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200662 return 0;
663}
664
665int
666_Py_Gid_Converter(PyObject *obj, void *p)
667{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700668 gid_t gid;
669 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200670 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200671 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700672 unsigned long uresult;
673
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300674 index = _PyNumber_Index(obj);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700675 if (index == NULL) {
676 PyErr_Format(PyExc_TypeError,
677 "gid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800678 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200679 return 0;
680 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700681
682 /*
683 * Handling gid_t is complicated for two reasons:
684 * * Although gid_t is (always?) unsigned, it still
685 * accepts -1.
686 * * We don't know its size in advance--it may be
687 * bigger than an int, or it may be smaller than
688 * a long.
689 *
690 * So a bit of defensive programming is in order.
691 * Start with interpreting the value passed
692 * in as a signed long and see if it works.
693 */
694
695 result = PyLong_AsLongAndOverflow(index, &overflow);
696
697 if (!overflow) {
698 gid = (gid_t)result;
699
700 if (result == -1) {
701 if (PyErr_Occurred())
702 goto fail;
703 /* It's a legitimate -1, we're done. */
704 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200705 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700706
707 /* Any other negative number is disallowed. */
708 if (result < 0) {
709 goto underflow;
710 }
711
712 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200713 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700714 (long)gid != result)
715 goto underflow;
716 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200717 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700718
719 if (overflow < 0)
720 goto underflow;
721
722 /*
723 * Okay, the value overflowed a signed long. If it
724 * fits in an *unsigned* long, it may still be okay,
725 * as gid_t may be unsigned long on this platform.
726 */
727 uresult = PyLong_AsUnsignedLong(index);
728 if (PyErr_Occurred()) {
729 if (PyErr_ExceptionMatches(PyExc_OverflowError))
730 goto overflow;
731 goto fail;
732 }
733
734 gid = (gid_t)uresult;
735
736 /*
737 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
738 * but this value would get interpreted as (gid_t)-1 by chown
739 * and its siblings. That's not what the user meant! So we
740 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100741 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700742 */
743 if (gid == (gid_t)-1)
744 goto overflow;
745
746 /* Ensure the value wasn't truncated. */
747 if (sizeof(gid_t) < sizeof(long) &&
748 (unsigned long)gid != uresult)
749 goto overflow;
750 /* fallthrough */
751
752success:
753 Py_DECREF(index);
754 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200755 return 1;
756
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700757underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200758 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700759 "gid is less than minimum");
760 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200761
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700762overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200763 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700764 "gid is greater than maximum");
765 /* fallthrough */
766
767fail:
768 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200769 return 0;
770}
771#endif /* MS_WINDOWS */
772
773
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700774#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800775
776
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200777#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
778static int
779_Py_Dev_Converter(PyObject *obj, void *p)
780{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200781 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200782 if (PyErr_Occurred())
783 return 0;
784 return 1;
785}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800786#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200787
788
Larry Hastings9cf065c2012-06-22 16:30:09 -0700789#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400790/*
791 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
792 * without the int cast, the value gets interpreted as uint (4291925331),
793 * which doesn't play nicely with all the initializer lines in this file that
794 * look like this:
795 * int dir_fd = DEFAULT_DIR_FD;
796 */
797#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700798#else
799#define DEFAULT_DIR_FD (-100)
800#endif
801
802static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300803_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200804{
805 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700806 long long_value;
807
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300808 PyObject *index = _PyNumber_Index(o);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700809 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700810 return 0;
811 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700812
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300813 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700814 long_value = PyLong_AsLongAndOverflow(index, &overflow);
815 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300816 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200817 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700818 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700819 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700820 return 0;
821 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200822 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700823 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700824 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700825 return 0;
826 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700827
Larry Hastings9cf065c2012-06-22 16:30:09 -0700828 *p = (int)long_value;
829 return 1;
830}
831
832static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200833dir_fd_converter(PyObject *o, void *p)
834{
835 if (o == Py_None) {
836 *(int *)p = DEFAULT_DIR_FD;
837 return 1;
838 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300839 else if (PyIndex_Check(o)) {
840 return _fd_converter(o, (int *)p);
841 }
842 else {
843 PyErr_Format(PyExc_TypeError,
844 "argument should be integer or None, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800845 _PyType_Name(Py_TYPE(o)));
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300846 return 0;
847 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700848}
849
Eddie Elizondob3966632019-11-05 07:16:14 -0800850typedef struct {
851 PyObject *billion;
Eddie Elizondob3966632019-11-05 07:16:14 -0800852 PyObject *DirEntryType;
853 PyObject *ScandirIteratorType;
854#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
855 PyObject *SchedParamType;
856#endif
857 PyObject *StatResultType;
858 PyObject *StatVFSResultType;
859 PyObject *TerminalSizeType;
860 PyObject *TimesResultType;
861 PyObject *UnameResultType;
862#if defined(HAVE_WAITID) && !defined(__APPLE__)
863 PyObject *WaitidResultType;
864#endif
865#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
866 PyObject *struct_rusage;
867#endif
868 PyObject *st_mode;
869} _posixstate;
870
Eddie Elizondob3966632019-11-05 07:16:14 -0800871
Hai Shif707d942020-03-16 21:15:01 +0800872static inline _posixstate*
873get_posix_state(PyObject *module)
874{
875 void *state = PyModule_GetState(module);
876 assert(state != NULL);
877 return (_posixstate *)state;
878}
879
Larry Hastings9cf065c2012-06-22 16:30:09 -0700880/*
881 * A PyArg_ParseTuple "converter" function
882 * that handles filesystem paths in the manner
883 * preferred by the os module.
884 *
885 * path_converter accepts (Unicode) strings and their
886 * subclasses, and bytes and their subclasses. What
887 * it does with the argument depends on the platform:
888 *
889 * * On Windows, if we get a (Unicode) string we
890 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700891 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700892 *
893 * * On all other platforms, strings are encoded
894 * to bytes using PyUnicode_FSConverter, then we
895 * extract the char * from the bytes object and
896 * return that.
897 *
898 * path_converter also optionally accepts signed
899 * integers (representing open file descriptors) instead
900 * of path strings.
901 *
902 * Input fields:
903 * path.nullable
904 * If nonzero, the path is permitted to be None.
905 * path.allow_fd
906 * If nonzero, the path is permitted to be a file handle
907 * (a signed int) instead of a string.
908 * path.function_name
909 * If non-NULL, path_converter will use that as the name
910 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700911 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700912 * path.argument_name
913 * If non-NULL, path_converter will use that as the name
914 * of the parameter in error messages.
915 * (If path.argument_name is NULL it uses "path".)
916 *
917 * Output fields:
918 * path.wide
919 * Points to the path if it was expressed as Unicode
920 * and was not encoded. (Only used on Windows.)
921 * path.narrow
922 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700923 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000924 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700925 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700926 * path.fd
927 * Contains a file descriptor if path.accept_fd was true
928 * and the caller provided a signed integer instead of any
929 * sort of string.
930 *
931 * WARNING: if your "path" parameter is optional, and is
932 * unspecified, path_converter will never get called.
933 * So if you set allow_fd, you *MUST* initialize path.fd = -1
934 * yourself!
935 * path.length
936 * The length of the path in characters, if specified as
937 * a string.
938 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800939 * The original object passed in (if get a PathLike object,
940 * the result of PyOS_FSPath() is treated as the original object).
941 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700942 * path.cleanup
943 * For internal use only. May point to a temporary object.
944 * (Pay no attention to the man behind the curtain.)
945 *
946 * At most one of path.wide or path.narrow will be non-NULL.
947 * If path was None and path.nullable was set,
948 * or if path was an integer and path.allow_fd was set,
949 * both path.wide and path.narrow will be NULL
950 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200951 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700952 * path_converter takes care to not write to the path_t
953 * unless it's successful. However it must reset the
954 * "cleanup" field each time it's called.
955 *
956 * Use as follows:
957 * path_t path;
958 * memset(&path, 0, sizeof(path));
959 * PyArg_ParseTuple(args, "O&", path_converter, &path);
960 * // ... use values from path ...
961 * path_cleanup(&path);
962 *
963 * (Note that if PyArg_Parse fails you don't need to call
964 * path_cleanup(). However it is safe to do so.)
965 */
966typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100967 const char *function_name;
968 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700969 int nullable;
970 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300971 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700972#ifdef MS_WINDOWS
973 BOOL narrow;
974#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300975 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700976#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700977 int fd;
978 Py_ssize_t length;
979 PyObject *object;
980 PyObject *cleanup;
981} path_t;
982
Steve Dowercc16be82016-09-08 10:35:16 -0700983#ifdef MS_WINDOWS
984#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
985 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
986#else
Larry Hastings2f936352014-08-05 14:04:04 +1000987#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
988 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700989#endif
Larry Hastings31826802013-10-19 00:09:25 -0700990
Larry Hastings9cf065c2012-06-22 16:30:09 -0700991static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800992path_cleanup(path_t *path)
993{
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +0300994#if !USE_UNICODE_WCHAR_CACHE
995 wchar_t *wide = (wchar_t *)path->wide;
996 path->wide = NULL;
997 PyMem_Free(wide);
998#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +0800999 Py_CLEAR(path->object);
1000 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001}
1002
1003static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001004path_converter(PyObject *o, void *p)
1005{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001006 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +08001007 PyObject *bytes = NULL;
1008 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001009 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001010 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001011#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +08001012 PyObject *wo = NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001013 wchar_t *wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001014#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001015
1016#define FORMAT_EXCEPTION(exc, fmt) \
1017 PyErr_Format(exc, "%s%s" fmt, \
1018 path->function_name ? path->function_name : "", \
1019 path->function_name ? ": " : "", \
1020 path->argument_name ? path->argument_name : "path")
1021
1022 /* Py_CLEANUP_SUPPORTED support */
1023 if (o == NULL) {
1024 path_cleanup(path);
1025 return 1;
1026 }
1027
Brett Cannon3f9183b2016-08-26 14:44:48 -07001028 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +08001029 path->object = path->cleanup = NULL;
1030 /* path->object owns a reference to the original object */
1031 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001032
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001033 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001034 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001035#ifdef MS_WINDOWS
1036 path->narrow = FALSE;
1037#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001038 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001039#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001040 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001041 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001042 }
1043
Brett Cannon3f9183b2016-08-26 14:44:48 -07001044 /* Only call this here so that we don't treat the return value of
1045 os.fspath() as an fd or buffer. */
1046 is_index = path->allow_fd && PyIndex_Check(o);
1047 is_buffer = PyObject_CheckBuffer(o);
1048 is_bytes = PyBytes_Check(o);
1049 is_unicode = PyUnicode_Check(o);
1050
1051 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
1052 /* Inline PyOS_FSPath() for better error messages. */
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001053 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001054
1055 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1056 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001057 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001058 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001059 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001060 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001061 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001062 goto error_exit;
1063 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001064 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001065 is_unicode = 1;
1066 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001067 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001068 is_bytes = 1;
1069 }
1070 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001071 PyErr_Format(PyExc_TypeError,
1072 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -08001073 "not %.200s", _PyType_Name(Py_TYPE(o)),
1074 _PyType_Name(Py_TYPE(res)));
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001075 Py_DECREF(res);
1076 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001077 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001078
1079 /* still owns a reference to the original object */
1080 Py_DECREF(o);
1081 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001082 }
1083
1084 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001085#ifdef MS_WINDOWS
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001086#if USE_UNICODE_WCHAR_CACHE
1087_Py_COMP_DIAG_PUSH
1088_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001089 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001090_Py_COMP_DIAG_POP
1091#else /* USE_UNICODE_WCHAR_CACHE */
1092 wide = PyUnicode_AsWideCharString(o, &length);
1093#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner59799a82013-11-13 14:17:30 +01001094 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001095 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001096 }
Victor Stinner59799a82013-11-13 14:17:30 +01001097 if (length > 32767) {
1098 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001099 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001100 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001101 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001102 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001103 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001104 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001105
1106 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001107 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001108 path->fd = -1;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001109#if !USE_UNICODE_WCHAR_CACHE
1110 wide = NULL;
1111#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001112 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001113#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001114 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001115 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001116 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001117#endif
1118 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001119 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001120 bytes = o;
1121 Py_INCREF(bytes);
1122 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001123 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001124 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001125 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001126 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1127 "%s%s%s should be %s, not %.200s",
1128 path->function_name ? path->function_name : "",
1129 path->function_name ? ": " : "",
1130 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001131 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1132 "integer or None" :
1133 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1134 path->nullable ? "string, bytes, os.PathLike or None" :
1135 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001136 _PyType_Name(Py_TYPE(o)))) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001137 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001138 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001139 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001140 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001141 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001142 }
1143 }
Steve Dowercc16be82016-09-08 10:35:16 -07001144 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001145 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001146 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001147 }
1148 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001149#ifdef MS_WINDOWS
1150 path->narrow = FALSE;
1151#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001152 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001153#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001154 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001155 }
1156 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001157 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001158 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1159 path->function_name ? path->function_name : "",
1160 path->function_name ? ": " : "",
1161 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001162 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1163 "integer or None" :
1164 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1165 path->nullable ? "string, bytes, os.PathLike or None" :
1166 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001167 _PyType_Name(Py_TYPE(o)));
Xiang Zhang04316c42017-01-08 23:26:57 +08001168 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001169 }
1170
Larry Hastings9cf065c2012-06-22 16:30:09 -07001171 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001172 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001173 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001174 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001175 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001176 }
1177
Steve Dowercc16be82016-09-08 10:35:16 -07001178#ifdef MS_WINDOWS
1179 wo = PyUnicode_DecodeFSDefaultAndSize(
1180 narrow,
1181 length
1182 );
1183 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001184 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001185 }
1186
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001187#if USE_UNICODE_WCHAR_CACHE
1188_Py_COMP_DIAG_PUSH
1189_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Xiang Zhang04316c42017-01-08 23:26:57 +08001190 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001191_Py_COMP_DIAG_POP
1192#else /* USE_UNICODE_WCHAR_CACHE */
1193 wide = PyUnicode_AsWideCharString(wo, &length);
1194 Py_DECREF(wo);
1195#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowercc16be82016-09-08 10:35:16 -07001196 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001197 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001198 }
1199 if (length > 32767) {
1200 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001201 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001202 }
1203 if (wcslen(wide) != length) {
1204 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001205 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001206 }
1207 path->wide = wide;
1208 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001209 Py_DECREF(bytes);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001210#if USE_UNICODE_WCHAR_CACHE
1211 path->cleanup = wo;
1212#else /* USE_UNICODE_WCHAR_CACHE */
1213 wide = NULL;
1214#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowercc16be82016-09-08 10:35:16 -07001215#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001216 path->wide = NULL;
1217 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001218 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001219 /* Still a reference owned by path->object, don't have to
1220 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001221 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001222 }
1223 else {
1224 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001225 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001226#endif
1227 path->fd = -1;
1228
1229 success_exit:
1230 path->length = length;
1231 path->object = o;
1232 return Py_CLEANUP_SUPPORTED;
1233
1234 error_exit:
1235 Py_XDECREF(o);
1236 Py_XDECREF(bytes);
1237#ifdef MS_WINDOWS
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001238#if USE_UNICODE_WCHAR_CACHE
Xiang Zhang04316c42017-01-08 23:26:57 +08001239 Py_XDECREF(wo);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001240#else /* USE_UNICODE_WCHAR_CACHE */
1241 PyMem_Free(wide);
1242#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001243#endif
1244 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001245}
1246
1247static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001248argument_unavailable_error(const char *function_name, const char *argument_name)
1249{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001250 PyErr_Format(PyExc_NotImplementedError,
1251 "%s%s%s unavailable on this platform",
1252 (function_name != NULL) ? function_name : "",
1253 (function_name != NULL) ? ": ": "",
1254 argument_name);
1255}
1256
1257static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001258dir_fd_unavailable(PyObject *o, void *p)
1259{
1260 int dir_fd;
1261 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001262 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001263 if (dir_fd != DEFAULT_DIR_FD) {
1264 argument_unavailable_error(NULL, "dir_fd");
1265 return 0;
1266 }
1267 *(int *)p = dir_fd;
1268 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001269}
1270
1271static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001272fd_specified(const char *function_name, int fd)
1273{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001274 if (fd == -1)
1275 return 0;
1276
1277 argument_unavailable_error(function_name, "fd");
1278 return 1;
1279}
1280
1281static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001282follow_symlinks_specified(const char *function_name, int follow_symlinks)
1283{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001284 if (follow_symlinks)
1285 return 0;
1286
1287 argument_unavailable_error(function_name, "follow_symlinks");
1288 return 1;
1289}
1290
1291static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001292path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1293{
Steve Dowercc16be82016-09-08 10:35:16 -07001294 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1295#ifndef MS_WINDOWS
1296 && !path->narrow
1297#endif
1298 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001299 PyErr_Format(PyExc_ValueError,
1300 "%s: can't specify dir_fd without matching path",
1301 function_name);
1302 return 1;
1303 }
1304 return 0;
1305}
1306
1307static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001308dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1309{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001310 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1311 PyErr_Format(PyExc_ValueError,
1312 "%s: can't specify both dir_fd and fd",
1313 function_name);
1314 return 1;
1315 }
1316 return 0;
1317}
1318
1319static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001320fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1321 int follow_symlinks)
1322{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001323 if ((fd > 0) && (!follow_symlinks)) {
1324 PyErr_Format(PyExc_ValueError,
1325 "%s: cannot use fd and follow_symlinks together",
1326 function_name);
1327 return 1;
1328 }
1329 return 0;
1330}
1331
1332static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001333dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1334 int follow_symlinks)
1335{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001336 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1337 PyErr_Format(PyExc_ValueError,
1338 "%s: cannot use dir_fd and follow_symlinks together",
1339 function_name);
1340 return 1;
1341 }
1342 return 0;
1343}
1344
Larry Hastings2f936352014-08-05 14:04:04 +10001345#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001346 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001347#else
Larry Hastings2f936352014-08-05 14:04:04 +10001348 typedef off_t Py_off_t;
1349#endif
1350
1351static int
1352Py_off_t_converter(PyObject *arg, void *addr)
1353{
1354#ifdef HAVE_LARGEFILE_SUPPORT
1355 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1356#else
1357 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001358#endif
1359 if (PyErr_Occurred())
1360 return 0;
1361 return 1;
1362}
Larry Hastings2f936352014-08-05 14:04:04 +10001363
1364static PyObject *
1365PyLong_FromPy_off_t(Py_off_t offset)
1366{
1367#ifdef HAVE_LARGEFILE_SUPPORT
1368 return PyLong_FromLongLong(offset);
1369#else
1370 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001371#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001372}
1373
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001374#ifdef HAVE_SIGSET_T
1375/* Convert an iterable of integers to a sigset.
1376 Return 1 on success, return 0 and raise an exception on error. */
1377int
1378_Py_Sigset_Converter(PyObject *obj, void *addr)
1379{
1380 sigset_t *mask = (sigset_t *)addr;
1381 PyObject *iterator, *item;
1382 long signum;
1383 int overflow;
1384
Rémi Lapeyref0900192019-05-04 01:30:53 +02001385 // The extra parens suppress the unreachable-code warning with clang on MacOS
1386 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001387 /* Probably only if mask == NULL. */
1388 PyErr_SetFromErrno(PyExc_OSError);
1389 return 0;
1390 }
1391
1392 iterator = PyObject_GetIter(obj);
1393 if (iterator == NULL) {
1394 return 0;
1395 }
1396
1397 while ((item = PyIter_Next(iterator)) != NULL) {
1398 signum = PyLong_AsLongAndOverflow(item, &overflow);
1399 Py_DECREF(item);
1400 if (signum <= 0 || signum >= NSIG) {
1401 if (overflow || signum != -1 || !PyErr_Occurred()) {
1402 PyErr_Format(PyExc_ValueError,
1403 "signal number %ld out of range", signum);
1404 }
1405 goto error;
1406 }
1407 if (sigaddset(mask, (int)signum)) {
1408 if (errno != EINVAL) {
1409 /* Probably impossible */
1410 PyErr_SetFromErrno(PyExc_OSError);
1411 goto error;
1412 }
1413 /* For backwards compatibility, allow idioms such as
1414 * `range(1, NSIG)` but warn about invalid signal numbers
1415 */
1416 const char msg[] =
1417 "invalid signal number %ld, please use valid_signals()";
1418 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1419 goto error;
1420 }
1421 }
1422 }
1423 if (!PyErr_Occurred()) {
1424 Py_DECREF(iterator);
1425 return 1;
1426 }
1427
1428error:
1429 Py_DECREF(iterator);
1430 return 0;
1431}
1432#endif /* HAVE_SIGSET_T */
1433
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001434#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001435
1436static int
Brian Curtind25aef52011-06-13 15:16:04 -05001437win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001438{
Martin Panter70214ad2016-08-04 02:38:59 +00001439 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1440 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001441 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001442
1443 if (0 == DeviceIoControl(
1444 reparse_point_handle,
1445 FSCTL_GET_REPARSE_POINT,
1446 NULL, 0, /* in buffer */
1447 target_buffer, sizeof(target_buffer),
1448 &n_bytes_returned,
1449 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001450 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001451
1452 if (reparse_tag)
1453 *reparse_tag = rdb->ReparseTag;
1454
Brian Curtind25aef52011-06-13 15:16:04 -05001455 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001456}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001457
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001458#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001459
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001460/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001461#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001462/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001463** environ directly, we must obtain it with _NSGetEnviron(). See also
1464** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001465*/
1466#include <crt_externs.h>
pxinwrf2d7ac72019-05-21 18:46:37 +08001467#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001468extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001469#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001470
Barry Warsaw53699e91996-12-10 23:23:01 +00001471static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001472convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001473{
Victor Stinner8c62be82010-05-06 00:08:46 +00001474 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001475#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001476 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001477#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001478 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001479#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001480
Victor Stinner8c62be82010-05-06 00:08:46 +00001481 d = PyDict_New();
1482 if (d == NULL)
1483 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001484#ifdef MS_WINDOWS
1485 /* _wenviron must be initialized in this way if the program is started
1486 through main() instead of wmain(). */
1487 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001488 e = _wenviron;
Benoit Hudson723f71a2019-12-06 14:15:03 -05001489#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1490 /* environ is not accessible as an extern in a shared object on OSX; use
1491 _NSGetEnviron to resolve it. The value changes if you add environment
1492 variables between calls to Py_Initialize, so don't cache the value. */
1493 e = *_NSGetEnviron();
Victor Stinner8c62be82010-05-06 00:08:46 +00001494#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001495 e = environ;
1496#endif
1497 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001498 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001499 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001500 PyObject *k;
1501 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001502#ifdef MS_WINDOWS
1503 const wchar_t *p = wcschr(*e, L'=');
1504#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001505 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001506#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001507 if (p == NULL)
1508 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001509#ifdef MS_WINDOWS
1510 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1511#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001512 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001513#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001514 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001515 Py_DECREF(d);
1516 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001517 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001518#ifdef MS_WINDOWS
1519 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1520#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001521 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001522#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001523 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001524 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001525 Py_DECREF(d);
1526 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001527 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001528 if (PyDict_GetItemWithError(d, k) == NULL) {
1529 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1530 Py_DECREF(v);
1531 Py_DECREF(k);
1532 Py_DECREF(d);
1533 return NULL;
1534 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001535 }
1536 Py_DECREF(k);
1537 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001538 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001539 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001540}
1541
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001542/* Set a POSIX-specific error from errno, and return NULL */
1543
Barry Warsawd58d7641998-07-23 16:14:40 +00001544static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001545posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001546{
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001548}
Mark Hammondef8b6542001-05-13 08:04:26 +00001549
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001550#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001551static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001552win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001553{
Victor Stinner8c62be82010-05-06 00:08:46 +00001554 /* XXX We should pass the function name along in the future.
1555 (winreg.c also wants to pass the function name.)
1556 This would however require an additional param to the
1557 Windows error object, which is non-trivial.
1558 */
1559 errno = GetLastError();
1560 if (filename)
1561 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1562 else
1563 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001564}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001565
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001566static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001567win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001568{
1569 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001570 if (filename)
1571 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001572 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001573 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001574 filename);
1575 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001576 return PyErr_SetFromWindowsErr(err);
1577}
1578
1579static PyObject *
1580win32_error_object(const char* function, PyObject* filename)
1581{
1582 errno = GetLastError();
1583 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001584}
1585
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001586#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001587
Larry Hastings9cf065c2012-06-22 16:30:09 -07001588static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001589posix_path_object_error(PyObject *path)
1590{
1591 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1592}
1593
1594static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001595path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001596{
1597#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001598 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1599 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001600#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001601 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001602#endif
1603}
1604
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001605static PyObject *
1606path_object_error2(PyObject *path, PyObject *path2)
1607{
1608#ifdef MS_WINDOWS
1609 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1610 PyExc_OSError, 0, path, path2);
1611#else
1612 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1613#endif
1614}
1615
1616static PyObject *
1617path_error(path_t *path)
1618{
1619 return path_object_error(path->object);
1620}
Larry Hastings31826802013-10-19 00:09:25 -07001621
Larry Hastingsb0827312014-02-09 22:05:19 -08001622static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001623posix_path_error(path_t *path)
1624{
1625 return posix_path_object_error(path->object);
1626}
1627
1628static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001629path_error2(path_t *path, path_t *path2)
1630{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001631 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001632}
1633
1634
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001635/* POSIX generic methods */
1636
Larry Hastings2f936352014-08-05 14:04:04 +10001637static PyObject *
1638posix_fildes_fd(int fd, int (*func)(int))
1639{
1640 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001641 int async_err = 0;
1642
1643 do {
1644 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001645 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001646 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001647 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001648 Py_END_ALLOW_THREADS
1649 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1650 if (res != 0)
1651 return (!async_err) ? posix_error() : NULL;
1652 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001653}
Guido van Rossum21142a01999-01-08 21:05:37 +00001654
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001655
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001656#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001657/* This is a reimplementation of the C library's chdir function,
1658 but one that produces Win32 errors instead of DOS error codes.
1659 chdir is essentially a wrapper around SetCurrentDirectory; however,
1660 it also needs to set "magic" environment variables indicating
1661 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001662static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001663win32_wchdir(LPCWSTR path)
1664{
Victor Stinnered537822015-12-13 21:40:26 +01001665 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001666 int result;
1667 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001668
Victor Stinner8c62be82010-05-06 00:08:46 +00001669 if(!SetCurrentDirectoryW(path))
1670 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001671 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001672 if (!result)
1673 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001674 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001675 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001676 if (!new_path) {
1677 SetLastError(ERROR_OUTOFMEMORY);
1678 return FALSE;
1679 }
1680 result = GetCurrentDirectoryW(result, new_path);
1681 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001682 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001683 return FALSE;
1684 }
1685 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001686 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1687 wcsncmp(new_path, L"//", 2) == 0);
1688 if (!is_unc_like_path) {
1689 env[1] = new_path[0];
1690 result = SetEnvironmentVariableW(env, new_path);
1691 }
Victor Stinnered537822015-12-13 21:40:26 +01001692 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001693 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001694 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001695}
1696#endif
1697
Martin v. Löwis14694662006-02-03 12:54:16 +00001698#ifdef MS_WINDOWS
1699/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1700 - time stamps are restricted to second resolution
1701 - file modification times suffer from forth-and-back conversions between
1702 UTC and local time
1703 Therefore, we implement our own stat, based on the Win32 API directly.
1704*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001705#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001706#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001707#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001708
Victor Stinner6036e442015-03-08 01:58:04 +01001709static void
Steve Dowercc16be82016-09-08 10:35:16 -07001710find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1711 BY_HANDLE_FILE_INFORMATION *info,
1712 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001713{
1714 memset(info, 0, sizeof(*info));
1715 info->dwFileAttributes = pFileData->dwFileAttributes;
1716 info->ftCreationTime = pFileData->ftCreationTime;
1717 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1718 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1719 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1720 info->nFileSizeLow = pFileData->nFileSizeLow;
1721/* info->nNumberOfLinks = 1; */
1722 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1723 *reparse_tag = pFileData->dwReserved0;
1724 else
1725 *reparse_tag = 0;
1726}
1727
Guido van Rossumd8faa362007-04-27 19:54:29 +00001728static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001729attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001730{
Victor Stinner8c62be82010-05-06 00:08:46 +00001731 HANDLE hFindFile;
1732 WIN32_FIND_DATAW FileData;
1733 hFindFile = FindFirstFileW(pszFile, &FileData);
1734 if (hFindFile == INVALID_HANDLE_VALUE)
1735 return FALSE;
1736 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001737 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001738 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001739}
1740
Brian Curtind25aef52011-06-13 15:16:04 -05001741static int
Steve Dowercc16be82016-09-08 10:35:16 -07001742win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001743 BOOL traverse)
1744{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001745 HANDLE hFile;
1746 BY_HANDLE_FILE_INFORMATION fileInfo;
1747 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1748 DWORD fileType, error;
1749 BOOL isUnhandledTag = FALSE;
1750 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001751
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001752 DWORD access = FILE_READ_ATTRIBUTES;
1753 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1754 if (!traverse) {
1755 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1756 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001757
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001758 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001759 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001760 /* Either the path doesn't exist, or the caller lacks access. */
1761 error = GetLastError();
1762 switch (error) {
1763 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1764 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1765 /* Try reading the parent directory. */
1766 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1767 /* Cannot read the parent directory. */
1768 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001769 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001770 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001771 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1772 if (traverse ||
1773 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1774 /* The stat call has to traverse but cannot, so fail. */
1775 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001776 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001777 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001778 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001779 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001780
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001781 case ERROR_INVALID_PARAMETER:
1782 /* \\.\con requires read or write access. */
1783 hFile = CreateFileW(path, access | GENERIC_READ,
1784 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1785 OPEN_EXISTING, flags, NULL);
1786 if (hFile == INVALID_HANDLE_VALUE) {
1787 SetLastError(error);
1788 return -1;
1789 }
1790 break;
1791
1792 case ERROR_CANT_ACCESS_FILE:
1793 /* bpo37834: open unhandled reparse points if traverse fails. */
1794 if (traverse) {
1795 traverse = FALSE;
1796 isUnhandledTag = TRUE;
1797 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1798 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1799 }
1800 if (hFile == INVALID_HANDLE_VALUE) {
1801 SetLastError(error);
1802 return -1;
1803 }
1804 break;
1805
1806 default:
1807 return -1;
1808 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001809 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001810
1811 if (hFile != INVALID_HANDLE_VALUE) {
1812 /* Handle types other than files on disk. */
1813 fileType = GetFileType(hFile);
1814 if (fileType != FILE_TYPE_DISK) {
1815 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1816 retval = -1;
1817 goto cleanup;
1818 }
1819 DWORD fileAttributes = GetFileAttributesW(path);
1820 memset(result, 0, sizeof(*result));
1821 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1822 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1823 /* \\.\pipe\ or \\.\mailslot\ */
1824 result->st_mode = _S_IFDIR;
1825 } else if (fileType == FILE_TYPE_CHAR) {
1826 /* \\.\nul */
1827 result->st_mode = _S_IFCHR;
1828 } else if (fileType == FILE_TYPE_PIPE) {
1829 /* \\.\pipe\spam */
1830 result->st_mode = _S_IFIFO;
1831 }
1832 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1833 goto cleanup;
1834 }
1835
1836 /* Query the reparse tag, and traverse a non-link. */
1837 if (!traverse) {
1838 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1839 &tagInfo, sizeof(tagInfo))) {
1840 /* Allow devices that do not support FileAttributeTagInfo. */
1841 switch (GetLastError()) {
1842 case ERROR_INVALID_PARAMETER:
1843 case ERROR_INVALID_FUNCTION:
1844 case ERROR_NOT_SUPPORTED:
1845 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1846 tagInfo.ReparseTag = 0;
1847 break;
1848 default:
1849 retval = -1;
1850 goto cleanup;
1851 }
1852 } else if (tagInfo.FileAttributes &
1853 FILE_ATTRIBUTE_REPARSE_POINT) {
1854 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1855 if (isUnhandledTag) {
1856 /* Traversing previously failed for either this link
1857 or its target. */
1858 SetLastError(ERROR_CANT_ACCESS_FILE);
1859 retval = -1;
1860 goto cleanup;
1861 }
1862 /* Traverse a non-link, but not if traversing already failed
1863 for an unhandled tag. */
1864 } else if (!isUnhandledTag) {
1865 CloseHandle(hFile);
1866 return win32_xstat_impl(path, result, TRUE);
1867 }
1868 }
1869 }
1870
1871 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
1872 switch (GetLastError()) {
1873 case ERROR_INVALID_PARAMETER:
1874 case ERROR_INVALID_FUNCTION:
1875 case ERROR_NOT_SUPPORTED:
Steve Dower772ec0f2019-09-04 14:42:54 -07001876 /* Volumes and physical disks are block devices, e.g.
1877 \\.\C: and \\.\PhysicalDrive0. */
1878 memset(result, 0, sizeof(*result));
1879 result->st_mode = 0x6000; /* S_IFBLK */
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001880 goto cleanup;
1881 }
Steve Dower772ec0f2019-09-04 14:42:54 -07001882 retval = -1;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001883 goto cleanup;
1884 }
1885 }
1886
1887 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
1888
1889 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
1890 /* Fix the file execute permissions. This hack sets S_IEXEC if
1891 the filename has an extension that is commonly used by files
1892 that CreateProcessW can execute. A real implementation calls
1893 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
1894 AccessCheck to check for generic read, write, and execute
1895 access. */
1896 const wchar_t *fileExtension = wcsrchr(path, '.');
1897 if (fileExtension) {
1898 if (_wcsicmp(fileExtension, L".exe") == 0 ||
1899 _wcsicmp(fileExtension, L".bat") == 0 ||
1900 _wcsicmp(fileExtension, L".cmd") == 0 ||
1901 _wcsicmp(fileExtension, L".com") == 0) {
1902 result->st_mode |= 0111;
1903 }
1904 }
1905 }
1906
1907cleanup:
1908 if (hFile != INVALID_HANDLE_VALUE) {
Steve Dower772ec0f2019-09-04 14:42:54 -07001909 /* Preserve last error if we are failing */
1910 error = retval ? GetLastError() : 0;
1911 if (!CloseHandle(hFile)) {
1912 retval = -1;
1913 } else if (retval) {
1914 /* Restore last error */
1915 SetLastError(error);
1916 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001917 }
1918
1919 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001920}
1921
1922static int
Steve Dowercc16be82016-09-08 10:35:16 -07001923win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001924{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001925 /* Protocol violation: we explicitly clear errno, instead of
1926 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001927 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001928 errno = 0;
1929 return code;
1930}
Brian Curtind25aef52011-06-13 15:16:04 -05001931/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001932
1933 In Posix, stat automatically traverses symlinks and returns the stat
1934 structure for the target. In Windows, the equivalent GetFileAttributes by
1935 default does not traverse symlinks and instead returns attributes for
1936 the symlink.
1937
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001938 Instead, we will open the file (which *does* traverse symlinks by default)
1939 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00001940
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001941static int
Steve Dowercc16be82016-09-08 10:35:16 -07001942win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001943{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001944 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001945}
1946
Victor Stinner8c62be82010-05-06 00:08:46 +00001947static int
Steve Dowercc16be82016-09-08 10:35:16 -07001948win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001949{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001950 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001951}
1952
Martin v. Löwis14694662006-02-03 12:54:16 +00001953#endif /* MS_WINDOWS */
1954
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001955PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001956"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001957This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001958 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001959or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1960\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001961Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1962or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001963\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001964See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001965
1966static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001967 {"st_mode", "protection bits"},
1968 {"st_ino", "inode"},
1969 {"st_dev", "device"},
1970 {"st_nlink", "number of hard links"},
1971 {"st_uid", "user ID of owner"},
1972 {"st_gid", "group ID of owner"},
1973 {"st_size", "total size, in bytes"},
1974 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1975 {NULL, "integer time of last access"},
1976 {NULL, "integer time of last modification"},
1977 {NULL, "integer time of last change"},
1978 {"st_atime", "time of last access"},
1979 {"st_mtime", "time of last modification"},
1980 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001981 {"st_atime_ns", "time of last access in nanoseconds"},
1982 {"st_mtime_ns", "time of last modification in nanoseconds"},
1983 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001984#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001985 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001986#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001987#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001988 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001989#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001990#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001992#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001993#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001994 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001995#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001996#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001998#endif
1999#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002000 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002001#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002002#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2003 {"st_file_attributes", "Windows file attribute bits"},
2004#endif
jcea6c51d512018-01-28 14:00:08 +01002005#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2006 {"st_fstype", "Type of filesystem"},
2007#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002008#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2009 {"st_reparse_tag", "Windows reparse tag"},
2010#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002011 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002012};
2013
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002014#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002015#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002016#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002017#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002018#endif
2019
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002020#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002021#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2022#else
2023#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2024#endif
2025
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002026#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002027#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2028#else
2029#define ST_RDEV_IDX ST_BLOCKS_IDX
2030#endif
2031
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002032#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2033#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2034#else
2035#define ST_FLAGS_IDX ST_RDEV_IDX
2036#endif
2037
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002038#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002039#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002040#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002041#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002042#endif
2043
2044#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2045#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2046#else
2047#define ST_BIRTHTIME_IDX ST_GEN_IDX
2048#endif
2049
Zachary Ware63f277b2014-06-19 09:46:37 -05002050#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2051#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
2052#else
2053#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2054#endif
2055
jcea6c51d512018-01-28 14:00:08 +01002056#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2057#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2058#else
2059#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2060#endif
2061
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002062#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2063#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2064#else
2065#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2066#endif
2067
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002068static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 "stat_result", /* name */
2070 stat_result__doc__, /* doc */
2071 stat_result_fields,
2072 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002073};
2074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002075PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002076"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2077This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002078 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002079or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002080\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002081See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002082
2083static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 {"f_bsize", },
2085 {"f_frsize", },
2086 {"f_blocks", },
2087 {"f_bfree", },
2088 {"f_bavail", },
2089 {"f_files", },
2090 {"f_ffree", },
2091 {"f_favail", },
2092 {"f_flag", },
2093 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002094 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002095 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002096};
2097
2098static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002099 "statvfs_result", /* name */
2100 statvfs_result__doc__, /* doc */
2101 statvfs_result_fields,
2102 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002103};
2104
Ross Lagerwall7807c352011-03-17 20:20:30 +02002105#if defined(HAVE_WAITID) && !defined(__APPLE__)
2106PyDoc_STRVAR(waitid_result__doc__,
2107"waitid_result: Result from waitid.\n\n\
2108This object may be accessed either as a tuple of\n\
2109 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2110or via the attributes si_pid, si_uid, and so on.\n\
2111\n\
2112See os.waitid for more information.");
2113
2114static PyStructSequence_Field waitid_result_fields[] = {
2115 {"si_pid", },
2116 {"si_uid", },
2117 {"si_signo", },
2118 {"si_status", },
2119 {"si_code", },
2120 {0}
2121};
2122
2123static PyStructSequence_Desc waitid_result_desc = {
2124 "waitid_result", /* name */
2125 waitid_result__doc__, /* doc */
2126 waitid_result_fields,
2127 5
2128};
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002129#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002130static newfunc structseq_new;
2131
2132static PyObject *
2133statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2134{
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 PyStructSequence *result;
2136 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002137
Victor Stinner8c62be82010-05-06 00:08:46 +00002138 result = (PyStructSequence*)structseq_new(type, args, kwds);
2139 if (!result)
2140 return NULL;
2141 /* If we have been initialized from a tuple,
2142 st_?time might be set to None. Initialize it
2143 from the int slots. */
2144 for (i = 7; i <= 9; i++) {
2145 if (result->ob_item[i+3] == Py_None) {
2146 Py_DECREF(Py_None);
2147 Py_INCREF(result->ob_item[i]);
2148 result->ob_item[i+3] = result->ob_item[i];
2149 }
2150 }
2151 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002152}
2153
Eddie Elizondob3966632019-11-05 07:16:14 -08002154static int
2155_posix_clear(PyObject *module)
2156{
Victor Stinner97f33c32020-05-14 18:05:58 +02002157 _posixstate *state = get_posix_state(module);
2158 Py_CLEAR(state->billion);
2159 Py_CLEAR(state->DirEntryType);
2160 Py_CLEAR(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002161#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002162 Py_CLEAR(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002163#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002164 Py_CLEAR(state->StatResultType);
2165 Py_CLEAR(state->StatVFSResultType);
2166 Py_CLEAR(state->TerminalSizeType);
2167 Py_CLEAR(state->TimesResultType);
2168 Py_CLEAR(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002169#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002170 Py_CLEAR(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002171#endif
2172#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002173 Py_CLEAR(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002174#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002175 Py_CLEAR(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002176 return 0;
2177}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002178
Eddie Elizondob3966632019-11-05 07:16:14 -08002179static int
2180_posix_traverse(PyObject *module, visitproc visit, void *arg)
2181{
Victor Stinner97f33c32020-05-14 18:05:58 +02002182 _posixstate *state = get_posix_state(module);
2183 Py_VISIT(state->billion);
2184 Py_VISIT(state->DirEntryType);
2185 Py_VISIT(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002186#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002187 Py_VISIT(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002188#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002189 Py_VISIT(state->StatResultType);
2190 Py_VISIT(state->StatVFSResultType);
2191 Py_VISIT(state->TerminalSizeType);
2192 Py_VISIT(state->TimesResultType);
2193 Py_VISIT(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002194#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002195 Py_VISIT(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002196#endif
2197#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002198 Py_VISIT(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002199#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002200 Py_VISIT(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002201 return 0;
2202}
2203
2204static void
2205_posix_free(void *module)
2206{
2207 _posix_clear((PyObject *)module);
2208}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002209
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002210static void
Victor Stinner1c2fa782020-05-10 11:05:29 +02002211fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002212{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002213 PyObject *s = _PyLong_FromTime_t(sec);
2214 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2215 PyObject *s_in_ns = NULL;
2216 PyObject *ns_total = NULL;
2217 PyObject *float_s = NULL;
2218
2219 if (!(s && ns_fractional))
2220 goto exit;
2221
Victor Stinner1c2fa782020-05-10 11:05:29 +02002222 s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002223 if (!s_in_ns)
2224 goto exit;
2225
2226 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2227 if (!ns_total)
2228 goto exit;
2229
Victor Stinner01b5aab2017-10-24 02:02:00 -07002230 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2231 if (!float_s) {
2232 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002233 }
2234
2235 PyStructSequence_SET_ITEM(v, index, s);
2236 PyStructSequence_SET_ITEM(v, index+3, float_s);
2237 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2238 s = NULL;
2239 float_s = NULL;
2240 ns_total = NULL;
2241exit:
2242 Py_XDECREF(s);
2243 Py_XDECREF(ns_fractional);
2244 Py_XDECREF(s_in_ns);
2245 Py_XDECREF(ns_total);
2246 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002247}
2248
Tim Peters5aa91602002-01-30 05:46:57 +00002249/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002250 (used by posix_stat() and posix_fstat()) */
2251static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +02002252_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002253{
Victor Stinner8c62be82010-05-06 00:08:46 +00002254 unsigned long ansec, mnsec, cnsec;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002255 PyObject *StatResultType = get_posix_state(module)->StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08002256 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002257 if (v == NULL)
2258 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002259
Victor Stinner8c62be82010-05-06 00:08:46 +00002260 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002261 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002262 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002263#ifdef MS_WINDOWS
2264 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002265#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002266 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002267#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002268 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002269#if defined(MS_WINDOWS)
2270 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2271 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2272#else
2273 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2274 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2275#endif
xdegaye50e86032017-05-22 11:15:08 +02002276 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2277 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002278
Martin v. Löwis14694662006-02-03 12:54:16 +00002279#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002280 ansec = st->st_atim.tv_nsec;
2281 mnsec = st->st_mtim.tv_nsec;
2282 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002283#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002284 ansec = st->st_atimespec.tv_nsec;
2285 mnsec = st->st_mtimespec.tv_nsec;
2286 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002287#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002288 ansec = st->st_atime_nsec;
2289 mnsec = st->st_mtime_nsec;
2290 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002291#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002292 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002293#endif
Victor Stinner1c2fa782020-05-10 11:05:29 +02002294 fill_time(module, v, 7, st->st_atime, ansec);
2295 fill_time(module, v, 8, st->st_mtime, mnsec);
2296 fill_time(module, v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002297
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002298#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002299 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2300 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002301#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002302#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002303 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2304 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002305#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002306#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002307 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2308 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002309#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002310#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002311 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2312 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002313#endif
2314#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002315 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002316 PyObject *val;
2317 unsigned long bsec,bnsec;
2318 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002319#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002320 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002321#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002322 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002323#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002324 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002325 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2326 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002327 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002328#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002329#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002330 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2331 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002332#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002333#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2334 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2335 PyLong_FromUnsignedLong(st->st_file_attributes));
2336#endif
jcea6c51d512018-01-28 14:00:08 +01002337#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2338 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2339 PyUnicode_FromString(st->st_fstype));
2340#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002341#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2342 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2343 PyLong_FromUnsignedLong(st->st_reparse_tag));
2344#endif
Fred Drake699f3522000-06-29 21:12:41 +00002345
Victor Stinner8c62be82010-05-06 00:08:46 +00002346 if (PyErr_Occurred()) {
2347 Py_DECREF(v);
2348 return NULL;
2349 }
Fred Drake699f3522000-06-29 21:12:41 +00002350
Victor Stinner8c62be82010-05-06 00:08:46 +00002351 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002352}
2353
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002354/* POSIX methods */
2355
Guido van Rossum94f6f721999-01-06 18:42:14 +00002356
2357static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02002358posix_do_stat(PyObject *module, const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002359 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002360{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002361 STRUCT_STAT st;
2362 int result;
2363
2364#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2365 if (follow_symlinks_specified(function_name, follow_symlinks))
2366 return NULL;
2367#endif
2368
2369 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2370 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2371 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2372 return NULL;
2373
2374 Py_BEGIN_ALLOW_THREADS
2375 if (path->fd != -1)
2376 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002377#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002378 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002379 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002380 else
Steve Dowercc16be82016-09-08 10:35:16 -07002381 result = win32_lstat(path->wide, &st);
2382#else
2383 else
2384#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002385 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2386 result = LSTAT(path->narrow, &st);
2387 else
Steve Dowercc16be82016-09-08 10:35:16 -07002388#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002389#ifdef HAVE_FSTATAT
2390 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2391 result = fstatat(dir_fd, path->narrow, &st,
2392 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2393 else
Steve Dowercc16be82016-09-08 10:35:16 -07002394#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002395 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002396#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002397 Py_END_ALLOW_THREADS
2398
Victor Stinner292c8352012-10-30 02:17:38 +01002399 if (result != 0) {
2400 return path_error(path);
2401 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002402
Victor Stinner1c2fa782020-05-10 11:05:29 +02002403 return _pystat_fromstructstat(module, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002404}
2405
Larry Hastings2f936352014-08-05 14:04:04 +10002406/*[python input]
2407
2408for s in """
2409
2410FACCESSAT
2411FCHMODAT
2412FCHOWNAT
2413FSTATAT
2414LINKAT
2415MKDIRAT
2416MKFIFOAT
2417MKNODAT
2418OPENAT
2419READLINKAT
2420SYMLINKAT
2421UNLINKAT
2422
2423""".strip().split():
2424 s = s.strip()
2425 print("""
2426#ifdef HAVE_{s}
2427 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002428#else
Larry Hastings2f936352014-08-05 14:04:04 +10002429 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002430#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002431""".rstrip().format(s=s))
2432
2433for s in """
2434
2435FCHDIR
2436FCHMOD
2437FCHOWN
2438FDOPENDIR
2439FEXECVE
2440FPATHCONF
2441FSTATVFS
2442FTRUNCATE
2443
2444""".strip().split():
2445 s = s.strip()
2446 print("""
2447#ifdef HAVE_{s}
2448 #define PATH_HAVE_{s} 1
2449#else
2450 #define PATH_HAVE_{s} 0
2451#endif
2452
2453""".rstrip().format(s=s))
2454[python start generated code]*/
2455
2456#ifdef HAVE_FACCESSAT
2457 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2458#else
2459 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2460#endif
2461
2462#ifdef HAVE_FCHMODAT
2463 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2464#else
2465 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2466#endif
2467
2468#ifdef HAVE_FCHOWNAT
2469 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2470#else
2471 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2472#endif
2473
2474#ifdef HAVE_FSTATAT
2475 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2476#else
2477 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2478#endif
2479
2480#ifdef HAVE_LINKAT
2481 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2482#else
2483 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2484#endif
2485
2486#ifdef HAVE_MKDIRAT
2487 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2488#else
2489 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2490#endif
2491
2492#ifdef HAVE_MKFIFOAT
2493 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2494#else
2495 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2496#endif
2497
2498#ifdef HAVE_MKNODAT
2499 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2500#else
2501 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2502#endif
2503
2504#ifdef HAVE_OPENAT
2505 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2506#else
2507 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2508#endif
2509
2510#ifdef HAVE_READLINKAT
2511 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2512#else
2513 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2514#endif
2515
2516#ifdef HAVE_SYMLINKAT
2517 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2518#else
2519 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2520#endif
2521
2522#ifdef HAVE_UNLINKAT
2523 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2524#else
2525 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2526#endif
2527
2528#ifdef HAVE_FCHDIR
2529 #define PATH_HAVE_FCHDIR 1
2530#else
2531 #define PATH_HAVE_FCHDIR 0
2532#endif
2533
2534#ifdef HAVE_FCHMOD
2535 #define PATH_HAVE_FCHMOD 1
2536#else
2537 #define PATH_HAVE_FCHMOD 0
2538#endif
2539
2540#ifdef HAVE_FCHOWN
2541 #define PATH_HAVE_FCHOWN 1
2542#else
2543 #define PATH_HAVE_FCHOWN 0
2544#endif
2545
2546#ifdef HAVE_FDOPENDIR
2547 #define PATH_HAVE_FDOPENDIR 1
2548#else
2549 #define PATH_HAVE_FDOPENDIR 0
2550#endif
2551
2552#ifdef HAVE_FEXECVE
2553 #define PATH_HAVE_FEXECVE 1
2554#else
2555 #define PATH_HAVE_FEXECVE 0
2556#endif
2557
2558#ifdef HAVE_FPATHCONF
2559 #define PATH_HAVE_FPATHCONF 1
2560#else
2561 #define PATH_HAVE_FPATHCONF 0
2562#endif
2563
2564#ifdef HAVE_FSTATVFS
2565 #define PATH_HAVE_FSTATVFS 1
2566#else
2567 #define PATH_HAVE_FSTATVFS 0
2568#endif
2569
2570#ifdef HAVE_FTRUNCATE
2571 #define PATH_HAVE_FTRUNCATE 1
2572#else
2573 #define PATH_HAVE_FTRUNCATE 0
2574#endif
2575/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002576
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002577#ifdef MS_WINDOWS
2578 #undef PATH_HAVE_FTRUNCATE
2579 #define PATH_HAVE_FTRUNCATE 1
2580#endif
Larry Hastings31826802013-10-19 00:09:25 -07002581
Larry Hastings61272b72014-01-07 12:41:53 -08002582/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002583
2584class path_t_converter(CConverter):
2585
2586 type = "path_t"
2587 impl_by_reference = True
2588 parse_by_reference = True
2589
2590 converter = 'path_converter'
2591
2592 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002593 # right now path_t doesn't support default values.
2594 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002595 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002596 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002597
Larry Hastings2f936352014-08-05 14:04:04 +10002598 if self.c_default not in (None, 'Py_None'):
2599 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002600
2601 self.nullable = nullable
2602 self.allow_fd = allow_fd
2603
Larry Hastings7726ac92014-01-31 22:03:12 -08002604 def pre_render(self):
2605 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002606 if isinstance(value, str):
2607 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002608 return str(int(bool(value)))
2609
2610 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002611 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002612 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002613 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002614 strify(self.nullable),
2615 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002616 )
2617
2618 def cleanup(self):
2619 return "path_cleanup(&" + self.name + ");\n"
2620
2621
2622class dir_fd_converter(CConverter):
2623 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002624
Larry Hastings2f936352014-08-05 14:04:04 +10002625 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002626 if self.default in (unspecified, None):
2627 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002628 if isinstance(requires, str):
2629 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2630 else:
2631 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002632
Larry Hastings2f936352014-08-05 14:04:04 +10002633class uid_t_converter(CConverter):
2634 type = "uid_t"
2635 converter = '_Py_Uid_Converter'
2636
2637class gid_t_converter(CConverter):
2638 type = "gid_t"
2639 converter = '_Py_Gid_Converter'
2640
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002641class dev_t_converter(CConverter):
2642 type = 'dev_t'
2643 converter = '_Py_Dev_Converter'
2644
2645class dev_t_return_converter(unsigned_long_return_converter):
2646 type = 'dev_t'
2647 conversion_fn = '_PyLong_FromDev'
2648 unsigned_cast = '(dev_t)'
2649
Larry Hastings2f936352014-08-05 14:04:04 +10002650class FSConverter_converter(CConverter):
2651 type = 'PyObject *'
2652 converter = 'PyUnicode_FSConverter'
2653 def converter_init(self):
2654 if self.default is not unspecified:
2655 fail("FSConverter_converter does not support default values")
2656 self.c_default = 'NULL'
2657
2658 def cleanup(self):
2659 return "Py_XDECREF(" + self.name + ");\n"
2660
2661class pid_t_converter(CConverter):
2662 type = 'pid_t'
2663 format_unit = '" _Py_PARSE_PID "'
2664
2665class idtype_t_converter(int_converter):
2666 type = 'idtype_t'
2667
2668class id_t_converter(CConverter):
2669 type = 'id_t'
2670 format_unit = '" _Py_PARSE_PID "'
2671
Benjamin Petersonca470632016-09-06 13:47:26 -07002672class intptr_t_converter(CConverter):
2673 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002674 format_unit = '" _Py_PARSE_INTPTR "'
2675
2676class Py_off_t_converter(CConverter):
2677 type = 'Py_off_t'
2678 converter = 'Py_off_t_converter'
2679
2680class Py_off_t_return_converter(long_return_converter):
2681 type = 'Py_off_t'
2682 conversion_fn = 'PyLong_FromPy_off_t'
2683
2684class path_confname_converter(CConverter):
2685 type="int"
2686 converter="conv_path_confname"
2687
2688class confstr_confname_converter(path_confname_converter):
2689 converter='conv_confstr_confname'
2690
2691class sysconf_confname_converter(path_confname_converter):
2692 converter="conv_sysconf_confname"
2693
Larry Hastings61272b72014-01-07 12:41:53 -08002694[python start generated code]*/
Serhiy Storchaka9975cc52020-10-09 23:00:45 +03002695/*[python end generated code: output=da39a3ee5e6b4b0d input=3338733161aa7879]*/
Larry Hastings31826802013-10-19 00:09:25 -07002696
Larry Hastings61272b72014-01-07 12:41:53 -08002697/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002698
Larry Hastings2a727912014-01-16 11:32:01 -08002699os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002700
2701 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002702 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002703 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002704
2705 *
2706
Larry Hastings2f936352014-08-05 14:04:04 +10002707 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002708 If not None, it should be a file descriptor open to a directory,
2709 and path should be a relative string; path will then be relative to
2710 that directory.
2711
2712 follow_symlinks: bool = True
2713 If False, and the last element of the path is a symbolic link,
2714 stat will examine the symbolic link itself instead of the file
2715 the link points to.
2716
2717Perform a stat system call on the given path.
2718
2719dir_fd and follow_symlinks may not be implemented
2720 on your platform. If they are unavailable, using them will raise a
2721 NotImplementedError.
2722
2723It's an error to use dir_fd or follow_symlinks when specifying path as
2724 an open file descriptor.
2725
Larry Hastings61272b72014-01-07 12:41:53 -08002726[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002727
Larry Hastings31826802013-10-19 00:09:25 -07002728static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002729os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002730/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002731{
Victor Stinner1c2fa782020-05-10 11:05:29 +02002732 return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002733}
2734
Larry Hastings2f936352014-08-05 14:04:04 +10002735
2736/*[clinic input]
2737os.lstat
2738
2739 path : path_t
2740
2741 *
2742
2743 dir_fd : dir_fd(requires='fstatat') = None
2744
2745Perform a stat system call on the given path, without following symbolic links.
2746
2747Like stat(), but do not follow symbolic links.
2748Equivalent to stat(path, follow_symlinks=False).
2749[clinic start generated code]*/
2750
Larry Hastings2f936352014-08-05 14:04:04 +10002751static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002752os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2753/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002754{
2755 int follow_symlinks = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002756 return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10002757}
Larry Hastings31826802013-10-19 00:09:25 -07002758
Larry Hastings2f936352014-08-05 14:04:04 +10002759
Larry Hastings61272b72014-01-07 12:41:53 -08002760/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002761os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002762
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002763 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002764 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002765
2766 mode: int
2767 Operating-system mode bitfield. Can be F_OK to test existence,
2768 or the inclusive-OR of R_OK, W_OK, and X_OK.
2769
2770 *
2771
Larry Hastings2f936352014-08-05 14:04:04 +10002772 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002773 If not None, it should be a file descriptor open to a directory,
2774 and path should be relative; path will then be relative to that
2775 directory.
2776
2777 effective_ids: bool = False
2778 If True, access will use the effective uid/gid instead of
2779 the real uid/gid.
2780
2781 follow_symlinks: bool = True
2782 If False, and the last element of the path is a symbolic link,
2783 access will examine the symbolic link itself instead of the file
2784 the link points to.
2785
2786Use the real uid/gid to test for access to a path.
2787
2788{parameters}
2789dir_fd, effective_ids, and follow_symlinks may not be implemented
2790 on your platform. If they are unavailable, using them will raise a
2791 NotImplementedError.
2792
2793Note that most operations will use the effective uid/gid, therefore this
2794 routine can be used in a suid/sgid environment to test if the invoking user
2795 has the specified access to the path.
2796
Larry Hastings61272b72014-01-07 12:41:53 -08002797[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002798
Larry Hastings2f936352014-08-05 14:04:04 +10002799static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002800os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002801 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002802/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002803{
Larry Hastings2f936352014-08-05 14:04:04 +10002804 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002805
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002806#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002807 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002808#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002809 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002810#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811
Larry Hastings9cf065c2012-06-22 16:30:09 -07002812#ifndef HAVE_FACCESSAT
2813 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002814 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002815
2816 if (effective_ids) {
2817 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002818 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002819 }
2820#endif
2821
2822#ifdef MS_WINDOWS
2823 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002824 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825 Py_END_ALLOW_THREADS
2826
2827 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002828 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829 * * we didn't get a -1, and
2830 * * write access wasn't requested,
2831 * * or the file isn't read-only,
2832 * * or it's a directory.
2833 * (Directories cannot be read-only on Windows.)
2834 */
Larry Hastings2f936352014-08-05 14:04:04 +10002835 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002836 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002837 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002838 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002839#else
2840
2841 Py_BEGIN_ALLOW_THREADS
2842#ifdef HAVE_FACCESSAT
2843 if ((dir_fd != DEFAULT_DIR_FD) ||
2844 effective_ids ||
2845 !follow_symlinks) {
2846 int flags = 0;
2847 if (!follow_symlinks)
2848 flags |= AT_SYMLINK_NOFOLLOW;
2849 if (effective_ids)
2850 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002851 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002852 }
2853 else
2854#endif
Larry Hastings31826802013-10-19 00:09:25 -07002855 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002856 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002857 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002858#endif
2859
Larry Hastings9cf065c2012-06-22 16:30:09 -07002860 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002861}
2862
Guido van Rossumd371ff11999-01-25 16:12:23 +00002863#ifndef F_OK
2864#define F_OK 0
2865#endif
2866#ifndef R_OK
2867#define R_OK 4
2868#endif
2869#ifndef W_OK
2870#define W_OK 2
2871#endif
2872#ifndef X_OK
2873#define X_OK 1
2874#endif
2875
Larry Hastings31826802013-10-19 00:09:25 -07002876
Guido van Rossumd371ff11999-01-25 16:12:23 +00002877#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002878/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002879os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002880
2881 fd: int
2882 Integer file descriptor handle.
2883
2884 /
2885
2886Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002887[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002888
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002889static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002890os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002891/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002892{
Guido van Rossum94f6f721999-01-06 18:42:14 +00002893
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002894 long size = sysconf(_SC_TTY_NAME_MAX);
2895 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002896 return posix_error();
2897 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002898 char *buffer = (char *)PyMem_RawMalloc(size);
2899 if (buffer == NULL) {
2900 return PyErr_NoMemory();
2901 }
2902 int ret = ttyname_r(fd, buffer, size);
2903 if (ret != 0) {
2904 PyMem_RawFree(buffer);
2905 errno = ret;
2906 return posix_error();
2907 }
2908 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
2909 PyMem_RawFree(buffer);
2910 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002911}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002912#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002913
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002914#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002915/*[clinic input]
2916os.ctermid
2917
2918Return the name of the controlling terminal for this process.
2919[clinic start generated code]*/
2920
Larry Hastings2f936352014-08-05 14:04:04 +10002921static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002922os_ctermid_impl(PyObject *module)
2923/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002924{
Victor Stinner8c62be82010-05-06 00:08:46 +00002925 char *ret;
2926 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002927
Greg Wardb48bc172000-03-01 21:51:56 +00002928#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002929 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002930#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002931 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002932#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002933 if (ret == NULL)
2934 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002935 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002936}
Larry Hastings2f936352014-08-05 14:04:04 +10002937#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002938
Larry Hastings2f936352014-08-05 14:04:04 +10002939
2940/*[clinic input]
2941os.chdir
2942
2943 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2944
2945Change the current working directory to the specified path.
2946
2947path may always be specified as a string.
2948On some platforms, path may also be specified as an open file descriptor.
2949 If this functionality is unavailable, using it raises an exception.
2950[clinic start generated code]*/
2951
Larry Hastings2f936352014-08-05 14:04:04 +10002952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002953os_chdir_impl(PyObject *module, path_t *path)
2954/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002955{
2956 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002957
Saiyang Gou7514f4f2020-02-12 23:47:42 -08002958 if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
2959 return NULL;
2960 }
2961
Larry Hastings9cf065c2012-06-22 16:30:09 -07002962 Py_BEGIN_ALLOW_THREADS
2963#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002964 /* on unix, success = 0, on windows, success = !0 */
2965 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002966#else
2967#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002968 if (path->fd != -1)
2969 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002970 else
2971#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002972 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002973#endif
2974 Py_END_ALLOW_THREADS
2975
2976 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002977 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002978 }
2979
Larry Hastings2f936352014-08-05 14:04:04 +10002980 Py_RETURN_NONE;
2981}
2982
2983
2984#ifdef HAVE_FCHDIR
2985/*[clinic input]
2986os.fchdir
2987
2988 fd: fildes
2989
2990Change to the directory of the given file descriptor.
2991
2992fd must be opened on a directory, not a file.
2993Equivalent to os.chdir(fd).
2994
2995[clinic start generated code]*/
2996
Fred Drake4d1e64b2002-04-15 19:40:07 +00002997static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002998os_fchdir_impl(PyObject *module, int fd)
2999/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00003000{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003001 if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
3002 return NULL;
3003 }
Larry Hastings2f936352014-08-05 14:04:04 +10003004 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00003005}
3006#endif /* HAVE_FCHDIR */
3007
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003008
Larry Hastings2f936352014-08-05 14:04:04 +10003009/*[clinic input]
3010os.chmod
3011
3012 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00003013 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10003014 On some platforms, path may also be specified as an open file descriptor.
3015 If this functionality is unavailable, using it raises an exception.
3016
3017 mode: int
3018 Operating-system mode bitfield.
3019
3020 *
3021
3022 dir_fd : dir_fd(requires='fchmodat') = None
3023 If not None, it should be a file descriptor open to a directory,
3024 and path should be relative; path will then be relative to that
3025 directory.
3026
3027 follow_symlinks: bool = True
3028 If False, and the last element of the path is a symbolic link,
3029 chmod will modify the symbolic link itself instead of the file
3030 the link points to.
3031
3032Change the access permissions of a file.
3033
3034It is an error to use dir_fd or follow_symlinks when specifying path as
3035 an open file descriptor.
3036dir_fd and follow_symlinks may not be implemented on your platform.
3037 If they are unavailable, using them will raise a NotImplementedError.
3038
3039[clinic start generated code]*/
3040
Larry Hastings2f936352014-08-05 14:04:04 +10003041static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003042os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003043 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003044/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003045{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003046 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003047
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003048#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003049 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003050#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003051
Larry Hastings9cf065c2012-06-22 16:30:09 -07003052#ifdef HAVE_FCHMODAT
3053 int fchmodat_nofollow_unsupported = 0;
3054#endif
3055
Larry Hastings9cf065c2012-06-22 16:30:09 -07003056#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3057 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003058 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003059#endif
3060
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003061 if (PySys_Audit("os.chmod", "Oii", path->object, mode,
3062 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3063 return NULL;
3064 }
3065
Larry Hastings9cf065c2012-06-22 16:30:09 -07003066#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003067 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003068 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003069 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003070 result = 0;
3071 else {
3072 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003073 attr &= ~FILE_ATTRIBUTE_READONLY;
3074 else
3075 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003076 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003077 }
3078 Py_END_ALLOW_THREADS
3079
3080 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003081 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003082 }
3083#else /* MS_WINDOWS */
3084 Py_BEGIN_ALLOW_THREADS
3085#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003086 if (path->fd != -1)
3087 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003088 else
3089#endif
3090#ifdef HAVE_LCHMOD
3091 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003092 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003093 else
3094#endif
3095#ifdef HAVE_FCHMODAT
3096 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
3097 /*
3098 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3099 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003100 * and then says it isn't implemented yet.
3101 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003102 *
3103 * Once it is supported, os.chmod will automatically
3104 * support dir_fd and follow_symlinks=False. (Hopefully.)
3105 * Until then, we need to be careful what exception we raise.
3106 */
Larry Hastings2f936352014-08-05 14:04:04 +10003107 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003108 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3109 /*
3110 * But wait! We can't throw the exception without allowing threads,
3111 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3112 */
3113 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003114 result &&
3115 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3116 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003117 }
3118 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003119#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003120 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003121 Py_END_ALLOW_THREADS
3122
3123 if (result) {
3124#ifdef HAVE_FCHMODAT
3125 if (fchmodat_nofollow_unsupported) {
3126 if (dir_fd != DEFAULT_DIR_FD)
3127 dir_fd_and_follow_symlinks_invalid("chmod",
3128 dir_fd, follow_symlinks);
3129 else
3130 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003131 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003132 }
3133 else
3134#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003135 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003136 }
3137#endif
3138
Larry Hastings2f936352014-08-05 14:04:04 +10003139 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003140}
3141
Larry Hastings9cf065c2012-06-22 16:30:09 -07003142
Christian Heimes4e30a842007-11-30 22:12:06 +00003143#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003144/*[clinic input]
3145os.fchmod
3146
3147 fd: int
3148 mode: int
3149
3150Change the access permissions of the file given by file descriptor fd.
3151
3152Equivalent to os.chmod(fd, mode).
3153[clinic start generated code]*/
3154
Larry Hastings2f936352014-08-05 14:04:04 +10003155static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003156os_fchmod_impl(PyObject *module, int fd, int mode)
3157/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003158{
3159 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003160 int async_err = 0;
3161
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003162 if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
3163 return NULL;
3164 }
3165
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003166 do {
3167 Py_BEGIN_ALLOW_THREADS
3168 res = fchmod(fd, mode);
3169 Py_END_ALLOW_THREADS
3170 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3171 if (res != 0)
3172 return (!async_err) ? posix_error() : NULL;
3173
Victor Stinner8c62be82010-05-06 00:08:46 +00003174 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003175}
3176#endif /* HAVE_FCHMOD */
3177
Larry Hastings2f936352014-08-05 14:04:04 +10003178
Christian Heimes4e30a842007-11-30 22:12:06 +00003179#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003180/*[clinic input]
3181os.lchmod
3182
3183 path: path_t
3184 mode: int
3185
3186Change the access permissions of a file, without following symbolic links.
3187
3188If path is a symlink, this affects the link itself rather than the target.
3189Equivalent to chmod(path, mode, follow_symlinks=False)."
3190[clinic start generated code]*/
3191
Larry Hastings2f936352014-08-05 14:04:04 +10003192static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003193os_lchmod_impl(PyObject *module, path_t *path, int mode)
3194/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003195{
Victor Stinner8c62be82010-05-06 00:08:46 +00003196 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003197 if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3198 return NULL;
3199 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003200 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003201 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003202 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003203 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003204 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003205 return NULL;
3206 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003207 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003208}
3209#endif /* HAVE_LCHMOD */
3210
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003211
Thomas Wouterscf297e42007-02-23 15:07:44 +00003212#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003213/*[clinic input]
3214os.chflags
3215
3216 path: path_t
3217 flags: unsigned_long(bitwise=True)
3218 follow_symlinks: bool=True
3219
3220Set file flags.
3221
3222If follow_symlinks is False, and the last element of the path is a symbolic
3223 link, chflags will change flags on the symbolic link itself instead of the
3224 file the link points to.
3225follow_symlinks may not be implemented on your platform. If it is
3226unavailable, using it will raise a NotImplementedError.
3227
3228[clinic start generated code]*/
3229
Larry Hastings2f936352014-08-05 14:04:04 +10003230static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003231os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003232 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003233/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003234{
3235 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003236
3237#ifndef HAVE_LCHFLAGS
3238 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003239 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003240#endif
3241
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003242 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3243 return NULL;
3244 }
3245
Victor Stinner8c62be82010-05-06 00:08:46 +00003246 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003247#ifdef HAVE_LCHFLAGS
3248 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003249 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250 else
3251#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003252 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003253 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003254
Larry Hastings2f936352014-08-05 14:04:04 +10003255 if (result)
3256 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003257
Larry Hastings2f936352014-08-05 14:04:04 +10003258 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003259}
3260#endif /* HAVE_CHFLAGS */
3261
Larry Hastings2f936352014-08-05 14:04:04 +10003262
Thomas Wouterscf297e42007-02-23 15:07:44 +00003263#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003264/*[clinic input]
3265os.lchflags
3266
3267 path: path_t
3268 flags: unsigned_long(bitwise=True)
3269
3270Set file flags.
3271
3272This function will not follow symbolic links.
3273Equivalent to chflags(path, flags, follow_symlinks=False).
3274[clinic start generated code]*/
3275
Larry Hastings2f936352014-08-05 14:04:04 +10003276static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003277os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3278/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003279{
Victor Stinner8c62be82010-05-06 00:08:46 +00003280 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003281 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3282 return NULL;
3283 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003284 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003285 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003287 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003288 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003289 }
Victor Stinner292c8352012-10-30 02:17:38 +01003290 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003291}
3292#endif /* HAVE_LCHFLAGS */
3293
Larry Hastings2f936352014-08-05 14:04:04 +10003294
Martin v. Löwis244edc82001-10-04 22:44:26 +00003295#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003296/*[clinic input]
3297os.chroot
3298 path: path_t
3299
3300Change root directory to path.
3301
3302[clinic start generated code]*/
3303
Larry Hastings2f936352014-08-05 14:04:04 +10003304static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003305os_chroot_impl(PyObject *module, path_t *path)
3306/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003307{
3308 int res;
3309 Py_BEGIN_ALLOW_THREADS
3310 res = chroot(path->narrow);
3311 Py_END_ALLOW_THREADS
3312 if (res < 0)
3313 return path_error(path);
3314 Py_RETURN_NONE;
3315}
3316#endif /* HAVE_CHROOT */
3317
Martin v. Löwis244edc82001-10-04 22:44:26 +00003318
Guido van Rossum21142a01999-01-08 21:05:37 +00003319#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003320/*[clinic input]
3321os.fsync
3322
3323 fd: fildes
3324
3325Force write of fd to disk.
3326[clinic start generated code]*/
3327
Larry Hastings2f936352014-08-05 14:04:04 +10003328static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003329os_fsync_impl(PyObject *module, int fd)
3330/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003331{
3332 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003333}
3334#endif /* HAVE_FSYNC */
3335
Larry Hastings2f936352014-08-05 14:04:04 +10003336
Ross Lagerwall7807c352011-03-17 20:20:30 +02003337#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003338/*[clinic input]
3339os.sync
3340
3341Force write of everything to disk.
3342[clinic start generated code]*/
3343
Larry Hastings2f936352014-08-05 14:04:04 +10003344static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003345os_sync_impl(PyObject *module)
3346/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003347{
3348 Py_BEGIN_ALLOW_THREADS
3349 sync();
3350 Py_END_ALLOW_THREADS
3351 Py_RETURN_NONE;
3352}
Larry Hastings2f936352014-08-05 14:04:04 +10003353#endif /* HAVE_SYNC */
3354
Ross Lagerwall7807c352011-03-17 20:20:30 +02003355
Guido van Rossum21142a01999-01-08 21:05:37 +00003356#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003357#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003358extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3359#endif
3360
Larry Hastings2f936352014-08-05 14:04:04 +10003361/*[clinic input]
3362os.fdatasync
3363
3364 fd: fildes
3365
3366Force write of fd to disk without forcing update of metadata.
3367[clinic start generated code]*/
3368
Larry Hastings2f936352014-08-05 14:04:04 +10003369static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003370os_fdatasync_impl(PyObject *module, int fd)
3371/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003372{
3373 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003374}
3375#endif /* HAVE_FDATASYNC */
3376
3377
Fredrik Lundh10723342000-07-10 16:38:09 +00003378#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003379/*[clinic input]
3380os.chown
3381
3382 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003383 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003384
3385 uid: uid_t
3386
3387 gid: gid_t
3388
3389 *
3390
3391 dir_fd : dir_fd(requires='fchownat') = None
3392 If not None, it should be a file descriptor open to a directory,
3393 and path should be relative; path will then be relative to that
3394 directory.
3395
3396 follow_symlinks: bool = True
3397 If False, and the last element of the path is a symbolic link,
3398 stat will examine the symbolic link itself instead of the file
3399 the link points to.
3400
3401Change the owner and group id of path to the numeric uid and gid.\
3402
3403path may always be specified as a string.
3404On some platforms, path may also be specified as an open file descriptor.
3405 If this functionality is unavailable, using it raises an exception.
3406If dir_fd is not None, it should be a file descriptor open to a directory,
3407 and path should be relative; path will then be relative to that directory.
3408If follow_symlinks is False, and the last element of the path is a symbolic
3409 link, chown will modify the symbolic link itself instead of the file the
3410 link points to.
3411It is an error to use dir_fd or follow_symlinks when specifying path as
3412 an open file descriptor.
3413dir_fd and follow_symlinks may not be implemented on your platform.
3414 If they are unavailable, using them will raise a NotImplementedError.
3415
3416[clinic start generated code]*/
3417
Larry Hastings2f936352014-08-05 14:04:04 +10003418static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003419os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003420 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003421/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003422{
3423 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003424
3425#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3426 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003427 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003429 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3430 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3431 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432
3433#ifdef __APPLE__
3434 /*
3435 * This is for Mac OS X 10.3, which doesn't have lchown.
3436 * (But we still have an lchown symbol because of weak-linking.)
3437 * It doesn't have fchownat either. So there's no possibility
3438 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003439 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440 if ((!follow_symlinks) && (lchown == NULL)) {
3441 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003442 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 }
3444#endif
3445
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003446 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
3447 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3448 return NULL;
3449 }
3450
Victor Stinner8c62be82010-05-06 00:08:46 +00003451 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003453 if (path->fd != -1)
3454 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455 else
3456#endif
3457#ifdef HAVE_LCHOWN
3458 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003459 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003460 else
3461#endif
3462#ifdef HAVE_FCHOWNAT
3463 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003464 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3466 else
3467#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003468 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003469 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470
Larry Hastings2f936352014-08-05 14:04:04 +10003471 if (result)
3472 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003473
Larry Hastings2f936352014-08-05 14:04:04 +10003474 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003475}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003476#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003477
Larry Hastings2f936352014-08-05 14:04:04 +10003478
Christian Heimes4e30a842007-11-30 22:12:06 +00003479#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003480/*[clinic input]
3481os.fchown
3482
3483 fd: int
3484 uid: uid_t
3485 gid: gid_t
3486
3487Change the owner and group id of the file specified by file descriptor.
3488
3489Equivalent to os.chown(fd, uid, gid).
3490
3491[clinic start generated code]*/
3492
Larry Hastings2f936352014-08-05 14:04:04 +10003493static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003494os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3495/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003496{
Victor Stinner8c62be82010-05-06 00:08:46 +00003497 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003498 int async_err = 0;
3499
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003500 if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
3501 return NULL;
3502 }
3503
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003504 do {
3505 Py_BEGIN_ALLOW_THREADS
3506 res = fchown(fd, uid, gid);
3507 Py_END_ALLOW_THREADS
3508 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3509 if (res != 0)
3510 return (!async_err) ? posix_error() : NULL;
3511
Victor Stinner8c62be82010-05-06 00:08:46 +00003512 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003513}
3514#endif /* HAVE_FCHOWN */
3515
Larry Hastings2f936352014-08-05 14:04:04 +10003516
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003517#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003518/*[clinic input]
3519os.lchown
3520
3521 path : path_t
3522 uid: uid_t
3523 gid: gid_t
3524
3525Change the owner and group id of path to the numeric uid and gid.
3526
3527This function will not follow symbolic links.
3528Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3529[clinic start generated code]*/
3530
Larry Hastings2f936352014-08-05 14:04:04 +10003531static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003532os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3533/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003534{
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003536 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
3537 return NULL;
3538 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003540 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003542 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003543 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003544 }
Larry Hastings2f936352014-08-05 14:04:04 +10003545 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003546}
3547#endif /* HAVE_LCHOWN */
3548
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003549
Barry Warsaw53699e91996-12-10 23:23:01 +00003550static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003551posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003552{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003553#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003554 wchar_t wbuf[MAXPATHLEN];
3555 wchar_t *wbuf2 = wbuf;
3556 DWORD len;
3557
3558 Py_BEGIN_ALLOW_THREADS
3559 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3560 /* If the buffer is large enough, len does not include the
3561 terminating \0. If the buffer is too small, len includes
3562 the space needed for the terminator. */
3563 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003564 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003565 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003566 }
Victor Stinner689830e2019-06-26 17:31:12 +02003567 else {
3568 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003569 }
Victor Stinner689830e2019-06-26 17:31:12 +02003570 if (wbuf2) {
3571 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003572 }
Victor Stinner689830e2019-06-26 17:31:12 +02003573 }
3574 Py_END_ALLOW_THREADS
3575
3576 if (!wbuf2) {
3577 PyErr_NoMemory();
3578 return NULL;
3579 }
3580 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003581 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003582 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003583 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003584 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003585
Victor Stinner689830e2019-06-26 17:31:12 +02003586 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3587 if (wbuf2 != wbuf) {
3588 PyMem_RawFree(wbuf2);
3589 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003590
Victor Stinner689830e2019-06-26 17:31:12 +02003591 if (use_bytes) {
3592 if (resobj == NULL) {
3593 return NULL;
3594 }
3595 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3596 }
3597
3598 return resobj;
3599#else
3600 const size_t chunk = 1024;
3601
3602 char *buf = NULL;
3603 char *cwd = NULL;
3604 size_t buflen = 0;
3605
Victor Stinner8c62be82010-05-06 00:08:46 +00003606 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003607 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003608 char *newbuf;
3609 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3610 buflen += chunk;
3611 newbuf = PyMem_RawRealloc(buf, buflen);
3612 }
3613 else {
3614 newbuf = NULL;
3615 }
3616 if (newbuf == NULL) {
3617 PyMem_RawFree(buf);
3618 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003619 break;
3620 }
Victor Stinner689830e2019-06-26 17:31:12 +02003621 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003622
Victor Stinner4403d7d2015-04-25 00:16:10 +02003623 cwd = getcwd(buf, buflen);
3624 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003625 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003626
Victor Stinner689830e2019-06-26 17:31:12 +02003627 if (buf == NULL) {
3628 return PyErr_NoMemory();
3629 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003630 if (cwd == NULL) {
3631 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003632 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003633 }
3634
Victor Stinner689830e2019-06-26 17:31:12 +02003635 PyObject *obj;
3636 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003637 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003638 }
3639 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003640 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003641 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003642 PyMem_RawFree(buf);
3643
3644 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003645#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003646}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003647
Larry Hastings2f936352014-08-05 14:04:04 +10003648
3649/*[clinic input]
3650os.getcwd
3651
3652Return a unicode string representing the current working directory.
3653[clinic start generated code]*/
3654
Larry Hastings2f936352014-08-05 14:04:04 +10003655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003656os_getcwd_impl(PyObject *module)
3657/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003658{
3659 return posix_getcwd(0);
3660}
3661
Larry Hastings2f936352014-08-05 14:04:04 +10003662
3663/*[clinic input]
3664os.getcwdb
3665
3666Return a bytes string representing the current working directory.
3667[clinic start generated code]*/
3668
Larry Hastings2f936352014-08-05 14:04:04 +10003669static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003670os_getcwdb_impl(PyObject *module)
3671/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003672{
3673 return posix_getcwd(1);
3674}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003675
Larry Hastings2f936352014-08-05 14:04:04 +10003676
Larry Hastings9cf065c2012-06-22 16:30:09 -07003677#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3678#define HAVE_LINK 1
3679#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003680
Guido van Rossumb6775db1994-08-01 11:34:53 +00003681#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003682/*[clinic input]
3683
3684os.link
3685
3686 src : path_t
3687 dst : path_t
3688 *
3689 src_dir_fd : dir_fd = None
3690 dst_dir_fd : dir_fd = None
3691 follow_symlinks: bool = True
3692
3693Create a hard link to a file.
3694
3695If either src_dir_fd or dst_dir_fd is not None, it should be a file
3696 descriptor open to a directory, and the respective path string (src or dst)
3697 should be relative; the path will then be relative to that directory.
3698If follow_symlinks is False, and the last element of src is a symbolic
3699 link, link will create a link to the symbolic link itself instead of the
3700 file the link points to.
3701src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3702 platform. If they are unavailable, using them will raise a
3703 NotImplementedError.
3704[clinic start generated code]*/
3705
Larry Hastings2f936352014-08-05 14:04:04 +10003706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003707os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003708 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003709/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003710{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003711#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003712 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003713#else
3714 int result;
3715#endif
3716
Larry Hastings9cf065c2012-06-22 16:30:09 -07003717#ifndef HAVE_LINKAT
3718 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3719 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003720 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003721 }
3722#endif
3723
Steve Dowercc16be82016-09-08 10:35:16 -07003724#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003725 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003726 PyErr_SetString(PyExc_NotImplementedError,
3727 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003728 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003729 }
Steve Dowercc16be82016-09-08 10:35:16 -07003730#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003731
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003732 if (PySys_Audit("os.link", "OOii", src->object, dst->object,
3733 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
3734 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
3735 return NULL;
3736 }
3737
Brian Curtin1b9df392010-11-24 20:24:31 +00003738#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003739 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003740 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003741 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003742
Larry Hastings2f936352014-08-05 14:04:04 +10003743 if (!result)
3744 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003745#else
3746 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003747#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003748 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3749 (dst_dir_fd != DEFAULT_DIR_FD) ||
3750 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003751 result = linkat(src_dir_fd, src->narrow,
3752 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003753 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3754 else
Steve Dowercc16be82016-09-08 10:35:16 -07003755#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003756 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003757 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003758
Larry Hastings2f936352014-08-05 14:04:04 +10003759 if (result)
3760 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003761#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003762
Larry Hastings2f936352014-08-05 14:04:04 +10003763 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003764}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003765#endif
3766
Brian Curtin1b9df392010-11-24 20:24:31 +00003767
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003768#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003769static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003770_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003771{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003772 PyObject *v;
3773 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3774 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003775 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003776 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003777 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003778 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003779
Steve Dowercc16be82016-09-08 10:35:16 -07003780 WIN32_FIND_DATAW wFileData;
3781 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003782
Steve Dowercc16be82016-09-08 10:35:16 -07003783 if (!path->wide) { /* Default arg: "." */
3784 po_wchars = L".";
3785 len = 1;
3786 } else {
3787 po_wchars = path->wide;
3788 len = wcslen(path->wide);
3789 }
3790 /* The +5 is so we can append "\\*.*\0" */
3791 wnamebuf = PyMem_New(wchar_t, len + 5);
3792 if (!wnamebuf) {
3793 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003794 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003795 }
Steve Dowercc16be82016-09-08 10:35:16 -07003796 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003797 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003798 wchar_t wch = wnamebuf[len-1];
3799 if (wch != SEP && wch != ALTSEP && wch != L':')
3800 wnamebuf[len++] = SEP;
3801 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003802 }
Steve Dowercc16be82016-09-08 10:35:16 -07003803 if ((list = PyList_New(0)) == NULL) {
3804 goto exit;
3805 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003806 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003807 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003808 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003809 if (hFindFile == INVALID_HANDLE_VALUE) {
3810 int error = GetLastError();
3811 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003812 goto exit;
3813 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003814 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003815 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003816 }
3817 do {
3818 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003819 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3820 wcscmp(wFileData.cFileName, L"..") != 0) {
3821 v = PyUnicode_FromWideChar(wFileData.cFileName,
3822 wcslen(wFileData.cFileName));
3823 if (path->narrow && v) {
3824 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3825 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003826 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003827 Py_DECREF(list);
3828 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003829 break;
3830 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003831 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003832 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003833 Py_DECREF(list);
3834 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003835 break;
3836 }
3837 Py_DECREF(v);
3838 }
3839 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003840 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003841 Py_END_ALLOW_THREADS
3842 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3843 it got to the end of the directory. */
3844 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003845 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003846 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003847 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003848 }
3849 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003850
Larry Hastings9cf065c2012-06-22 16:30:09 -07003851exit:
3852 if (hFindFile != INVALID_HANDLE_VALUE) {
3853 if (FindClose(hFindFile) == FALSE) {
3854 if (list != NULL) {
3855 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003856 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003857 }
3858 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003859 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003860 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003861
Larry Hastings9cf065c2012-06-22 16:30:09 -07003862 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003863} /* end of _listdir_windows_no_opendir */
3864
3865#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3866
3867static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003868_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003869{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003870 PyObject *v;
3871 DIR *dirp = NULL;
3872 struct dirent *ep;
3873 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003874#ifdef HAVE_FDOPENDIR
3875 int fd = -1;
3876#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003877
Victor Stinner8c62be82010-05-06 00:08:46 +00003878 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003879#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003880 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003881 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003882 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003883 if (fd == -1)
3884 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003885
Larry Hastingsfdaea062012-06-25 04:42:23 -07003886 return_str = 1;
3887
Larry Hastings9cf065c2012-06-22 16:30:09 -07003888 Py_BEGIN_ALLOW_THREADS
3889 dirp = fdopendir(fd);
3890 Py_END_ALLOW_THREADS
3891 }
3892 else
3893#endif
3894 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003895 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003896 if (path->narrow) {
3897 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003898 /* only return bytes if they specified a bytes-like object */
3899 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003900 }
3901 else {
3902 name = ".";
3903 return_str = 1;
3904 }
3905
Larry Hastings9cf065c2012-06-22 16:30:09 -07003906 Py_BEGIN_ALLOW_THREADS
3907 dirp = opendir(name);
3908 Py_END_ALLOW_THREADS
3909 }
3910
3911 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003912 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003913#ifdef HAVE_FDOPENDIR
3914 if (fd != -1) {
3915 Py_BEGIN_ALLOW_THREADS
3916 close(fd);
3917 Py_END_ALLOW_THREADS
3918 }
3919#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003920 goto exit;
3921 }
3922 if ((list = PyList_New(0)) == NULL) {
3923 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003924 }
3925 for (;;) {
3926 errno = 0;
3927 Py_BEGIN_ALLOW_THREADS
3928 ep = readdir(dirp);
3929 Py_END_ALLOW_THREADS
3930 if (ep == NULL) {
3931 if (errno == 0) {
3932 break;
3933 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003934 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003935 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003936 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003937 }
3938 }
3939 if (ep->d_name[0] == '.' &&
3940 (NAMLEN(ep) == 1 ||
3941 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3942 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003943 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003944 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3945 else
3946 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003947 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003948 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003949 break;
3950 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003951 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003953 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003954 break;
3955 }
3956 Py_DECREF(v);
3957 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003958
Larry Hastings9cf065c2012-06-22 16:30:09 -07003959exit:
3960 if (dirp != NULL) {
3961 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003962#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003963 if (fd > -1)
3964 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003965#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003966 closedir(dirp);
3967 Py_END_ALLOW_THREADS
3968 }
3969
Larry Hastings9cf065c2012-06-22 16:30:09 -07003970 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003971} /* end of _posix_listdir */
3972#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003973
Larry Hastings2f936352014-08-05 14:04:04 +10003974
3975/*[clinic input]
3976os.listdir
3977
3978 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3979
3980Return a list containing the names of the files in the directory.
3981
BNMetricsb9427072018-11-02 15:20:19 +00003982path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003983 the filenames returned will also be bytes; in all other circumstances
3984 the filenames returned will be str.
3985If path is None, uses the path='.'.
3986On some platforms, path may also be specified as an open file descriptor;\
3987 the file descriptor must refer to a directory.
3988 If this functionality is unavailable, using it raises NotImplementedError.
3989
3990The list is in arbitrary order. It does not include the special
3991entries '.' and '..' even if they are present in the directory.
3992
3993
3994[clinic start generated code]*/
3995
Larry Hastings2f936352014-08-05 14:04:04 +10003996static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003997os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003998/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003999{
Steve Dower60419a72019-06-24 08:42:54 -07004000 if (PySys_Audit("os.listdir", "O",
4001 path->object ? path->object : Py_None) < 0) {
4002 return NULL;
4003 }
Larry Hastings2f936352014-08-05 14:04:04 +10004004#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4005 return _listdir_windows_no_opendir(path, NULL);
4006#else
4007 return _posix_listdir(path, NULL);
4008#endif
4009}
4010
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004011#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00004012/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004013/*[clinic input]
4014os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02004015
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004016 path: path_t
4017 /
4018
4019[clinic start generated code]*/
4020
4021static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004022os__getfullpathname_impl(PyObject *module, path_t *path)
4023/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004024{
Victor Stinner3939c322019-06-25 15:02:43 +02004025 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004026
Victor Stinner3939c322019-06-25 15:02:43 +02004027 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
4028 if (_Py_abspath(path->wide, &abspath) < 0) {
4029 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00004030 }
Victor Stinner3939c322019-06-25 15:02:43 +02004031 if (abspath == NULL) {
4032 return PyErr_NoMemory();
4033 }
4034
4035 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
4036 PyMem_RawFree(abspath);
4037 if (str == NULL) {
4038 return NULL;
4039 }
4040 if (path->narrow) {
4041 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
4042 }
4043 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10004044}
Brian Curtind40e6f72010-07-08 21:39:08 +00004045
Brian Curtind25aef52011-06-13 15:16:04 -05004046
Larry Hastings2f936352014-08-05 14:04:04 +10004047/*[clinic input]
4048os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004049
Steve Dower23ad6d02018-02-22 10:39:10 -08004050 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004051 /
4052
4053A helper function for samepath on windows.
4054[clinic start generated code]*/
4055
Larry Hastings2f936352014-08-05 14:04:04 +10004056static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004057os__getfinalpathname_impl(PyObject *module, path_t *path)
4058/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004059{
4060 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004061 wchar_t buf[MAXPATHLEN], *target_path = buf;
4062 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00004063 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004064 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004065
Steve Dower23ad6d02018-02-22 10:39:10 -08004066 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004067 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08004068 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004069 0, /* desired access */
4070 0, /* share mode */
4071 NULL, /* security attributes */
4072 OPEN_EXISTING,
4073 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4074 FILE_FLAG_BACKUP_SEMANTICS,
4075 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004076 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004077
Steve Dower23ad6d02018-02-22 10:39:10 -08004078 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004079 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004080 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004081
4082 /* We have a good handle to the target, use it to determine the
4083 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004084 while (1) {
4085 Py_BEGIN_ALLOW_THREADS
4086 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4087 buf_size, VOLUME_NAME_DOS);
4088 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004089
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004090 if (!result_length) {
4091 result = win32_error_object("GetFinalPathNameByHandleW",
4092 path->object);
4093 goto cleanup;
4094 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004095
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004096 if (result_length < buf_size) {
4097 break;
4098 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004099
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004100 wchar_t *tmp;
4101 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4102 result_length * sizeof(*tmp));
4103 if (!tmp) {
4104 result = PyErr_NoMemory();
4105 goto cleanup;
4106 }
4107
4108 buf_size = result_length;
4109 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004110 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004111
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004112 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004113 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004114 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004115 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004116
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004117cleanup:
4118 if (target_path != buf) {
4119 PyMem_Free(target_path);
4120 }
4121 CloseHandle(hFile);
4122 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004123}
Brian Curtin62857742010-09-06 17:07:27 +00004124
Tim Golden6b528062013-08-01 12:44:00 +01004125
Larry Hastings2f936352014-08-05 14:04:04 +10004126/*[clinic input]
4127os._getvolumepathname
4128
Steve Dower23ad6d02018-02-22 10:39:10 -08004129 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004130
4131A helper function for ismount on Win32.
4132[clinic start generated code]*/
4133
Larry Hastings2f936352014-08-05 14:04:04 +10004134static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004135os__getvolumepathname_impl(PyObject *module, path_t *path)
4136/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004137{
4138 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004139 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004140 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004141 BOOL ret;
4142
Tim Golden6b528062013-08-01 12:44:00 +01004143 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004144 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004145
Victor Stinner850a18e2017-10-24 16:53:32 -07004146 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004147 PyErr_SetString(PyExc_OverflowError, "path too long");
4148 return NULL;
4149 }
4150
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004151 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004152 if (mountpath == NULL)
4153 return PyErr_NoMemory();
4154
4155 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004156 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004157 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004158 Py_END_ALLOW_THREADS
4159
4160 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004161 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004162 goto exit;
4163 }
4164 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004165 if (path->narrow)
4166 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004167
4168exit:
4169 PyMem_Free(mountpath);
4170 return result;
4171}
Tim Golden6b528062013-08-01 12:44:00 +01004172
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004173#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004174
Larry Hastings2f936352014-08-05 14:04:04 +10004175
4176/*[clinic input]
4177os.mkdir
4178
4179 path : path_t
4180
4181 mode: int = 0o777
4182
4183 *
4184
4185 dir_fd : dir_fd(requires='mkdirat') = None
4186
4187# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4188
4189Create a directory.
4190
4191If dir_fd is not None, it should be a file descriptor open to a directory,
4192 and path should be relative; path will then be relative to that directory.
4193dir_fd may not be implemented on your platform.
4194 If it is unavailable, using it will raise a NotImplementedError.
4195
4196The mode argument is ignored on Windows.
4197[clinic start generated code]*/
4198
Larry Hastings2f936352014-08-05 14:04:04 +10004199static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004200os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4201/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004202{
4203 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004204
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004205 if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
4206 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4207 return NULL;
4208 }
4209
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004210#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004211 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004212 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004213 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004214
Larry Hastings2f936352014-08-05 14:04:04 +10004215 if (!result)
4216 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004217#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004218 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004219#if HAVE_MKDIRAT
4220 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004221 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004222 else
4223#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004224#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004225 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004226#else
Larry Hastings2f936352014-08-05 14:04:04 +10004227 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004228#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004229 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004230 if (result < 0)
4231 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004232#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004233 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004234}
4235
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004236
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004237/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4238#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004239#include <sys/resource.h>
4240#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004241
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004242
4243#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004244/*[clinic input]
4245os.nice
4246
4247 increment: int
4248 /
4249
4250Add increment to the priority of process and return the new priority.
4251[clinic start generated code]*/
4252
Larry Hastings2f936352014-08-05 14:04:04 +10004253static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004254os_nice_impl(PyObject *module, int increment)
4255/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004256{
4257 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004258
Victor Stinner8c62be82010-05-06 00:08:46 +00004259 /* There are two flavours of 'nice': one that returns the new
4260 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004261 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004262 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004263
Victor Stinner8c62be82010-05-06 00:08:46 +00004264 If we are of the nice family that returns the new priority, we
4265 need to clear errno before the call, and check if errno is filled
4266 before calling posix_error() on a returnvalue of -1, because the
4267 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004268
Victor Stinner8c62be82010-05-06 00:08:46 +00004269 errno = 0;
4270 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004271#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004272 if (value == 0)
4273 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004274#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004275 if (value == -1 && errno != 0)
4276 /* either nice() or getpriority() returned an error */
4277 return posix_error();
4278 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004279}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004280#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004281
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004282
4283#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004284/*[clinic input]
4285os.getpriority
4286
4287 which: int
4288 who: int
4289
4290Return program scheduling priority.
4291[clinic start generated code]*/
4292
Larry Hastings2f936352014-08-05 14:04:04 +10004293static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004294os_getpriority_impl(PyObject *module, int which, int who)
4295/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004296{
4297 int retval;
4298
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004299 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004300 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004301 if (errno != 0)
4302 return posix_error();
4303 return PyLong_FromLong((long)retval);
4304}
4305#endif /* HAVE_GETPRIORITY */
4306
4307
4308#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004309/*[clinic input]
4310os.setpriority
4311
4312 which: int
4313 who: int
4314 priority: int
4315
4316Set program scheduling priority.
4317[clinic start generated code]*/
4318
Larry Hastings2f936352014-08-05 14:04:04 +10004319static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004320os_setpriority_impl(PyObject *module, int which, int who, int priority)
4321/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004322{
4323 int retval;
4324
4325 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004326 if (retval == -1)
4327 return posix_error();
4328 Py_RETURN_NONE;
4329}
4330#endif /* HAVE_SETPRIORITY */
4331
4332
Barry Warsaw53699e91996-12-10 23:23:01 +00004333static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004334internal_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 +00004335{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004336 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004337 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004338
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004339#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004340 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004341 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004342#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004343 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004344#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004345
Larry Hastings9cf065c2012-06-22 16:30:09 -07004346 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4347 (dst_dir_fd != DEFAULT_DIR_FD);
4348#ifndef HAVE_RENAMEAT
4349 if (dir_fd_specified) {
4350 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004351 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004352 }
4353#endif
4354
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004355 if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
4356 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
4357 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
4358 return NULL;
4359 }
4360
Larry Hastings9cf065c2012-06-22 16:30:09 -07004361#ifdef MS_WINDOWS
4362 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004363 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004364 Py_END_ALLOW_THREADS
4365
Larry Hastings2f936352014-08-05 14:04:04 +10004366 if (!result)
4367 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004368
4369#else
Steve Dowercc16be82016-09-08 10:35:16 -07004370 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4371 PyErr_Format(PyExc_ValueError,
4372 "%s: src and dst must be the same type", function_name);
4373 return NULL;
4374 }
4375
Larry Hastings9cf065c2012-06-22 16:30:09 -07004376 Py_BEGIN_ALLOW_THREADS
4377#ifdef HAVE_RENAMEAT
4378 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004379 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004380 else
4381#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004382 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004383 Py_END_ALLOW_THREADS
4384
Larry Hastings2f936352014-08-05 14:04:04 +10004385 if (result)
4386 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004387#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004388 Py_RETURN_NONE;
4389}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004390
Larry Hastings2f936352014-08-05 14:04:04 +10004391
4392/*[clinic input]
4393os.rename
4394
4395 src : path_t
4396 dst : path_t
4397 *
4398 src_dir_fd : dir_fd = None
4399 dst_dir_fd : dir_fd = None
4400
4401Rename a file or directory.
4402
4403If either src_dir_fd or dst_dir_fd is not None, it should be a file
4404 descriptor open to a directory, and the respective path string (src or dst)
4405 should be relative; the path will then be relative to that directory.
4406src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4407 If they are unavailable, using them will raise a NotImplementedError.
4408[clinic start generated code]*/
4409
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004410static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004411os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004412 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004413/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004414{
Larry Hastings2f936352014-08-05 14:04:04 +10004415 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004416}
4417
Larry Hastings2f936352014-08-05 14:04:04 +10004418
4419/*[clinic input]
4420os.replace = os.rename
4421
4422Rename a file or directory, overwriting the destination.
4423
4424If either src_dir_fd or dst_dir_fd is not None, it should be a file
4425 descriptor open to a directory, and the respective path string (src or dst)
4426 should be relative; the path will then be relative to that directory.
4427src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004428 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004429[clinic start generated code]*/
4430
Larry Hastings2f936352014-08-05 14:04:04 +10004431static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004432os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4433 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004434/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004435{
4436 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4437}
4438
4439
4440/*[clinic input]
4441os.rmdir
4442
4443 path: path_t
4444 *
4445 dir_fd: dir_fd(requires='unlinkat') = None
4446
4447Remove a directory.
4448
4449If dir_fd is not None, it should be a file descriptor open to a directory,
4450 and path should be relative; path will then be relative to that directory.
4451dir_fd may not be implemented on your platform.
4452 If it is unavailable, using it will raise a NotImplementedError.
4453[clinic start generated code]*/
4454
Larry Hastings2f936352014-08-05 14:04:04 +10004455static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004456os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4457/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004458{
4459 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004460
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004461 if (PySys_Audit("os.rmdir", "Oi", path->object,
4462 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4463 return NULL;
4464 }
4465
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004466 Py_BEGIN_ALLOW_THREADS
4467#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004468 /* Windows, success=1, UNIX, success=0 */
4469 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004470#else
4471#ifdef HAVE_UNLINKAT
4472 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004473 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004474 else
4475#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004476 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004477#endif
4478 Py_END_ALLOW_THREADS
4479
Larry Hastings2f936352014-08-05 14:04:04 +10004480 if (result)
4481 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004482
Larry Hastings2f936352014-08-05 14:04:04 +10004483 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004484}
4485
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004486
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004487#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004488#ifdef MS_WINDOWS
4489/*[clinic input]
4490os.system -> long
4491
4492 command: Py_UNICODE
4493
4494Execute the command in a subshell.
4495[clinic start generated code]*/
4496
Larry Hastings2f936352014-08-05 14:04:04 +10004497static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004498os_system_impl(PyObject *module, const Py_UNICODE *command)
4499/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004500{
4501 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004502
Steve Dowerfbe3c762019-10-18 00:52:15 -07004503 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004504 return -1;
4505 }
4506
Victor Stinner8c62be82010-05-06 00:08:46 +00004507 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004508 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004509 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004510 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004511 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004512 return result;
4513}
4514#else /* MS_WINDOWS */
4515/*[clinic input]
4516os.system -> long
4517
4518 command: FSConverter
4519
4520Execute the command in a subshell.
4521[clinic start generated code]*/
4522
Larry Hastings2f936352014-08-05 14:04:04 +10004523static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004524os_system_impl(PyObject *module, PyObject *command)
4525/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004526{
4527 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004528 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004529
Steve Dowerfbe3c762019-10-18 00:52:15 -07004530 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004531 return -1;
4532 }
4533
Larry Hastings2f936352014-08-05 14:04:04 +10004534 Py_BEGIN_ALLOW_THREADS
4535 result = system(bytes);
4536 Py_END_ALLOW_THREADS
4537 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004538}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004539#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004540#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004541
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004542
Larry Hastings2f936352014-08-05 14:04:04 +10004543/*[clinic input]
4544os.umask
4545
4546 mask: int
4547 /
4548
4549Set the current numeric umask and return the previous umask.
4550[clinic start generated code]*/
4551
Larry Hastings2f936352014-08-05 14:04:04 +10004552static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004553os_umask_impl(PyObject *module, int mask)
4554/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004555{
4556 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004557 if (i < 0)
4558 return posix_error();
4559 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004560}
4561
Brian Curtind40e6f72010-07-08 21:39:08 +00004562#ifdef MS_WINDOWS
4563
4564/* override the default DeleteFileW behavior so that directory
4565symlinks can be removed with this function, the same as with
4566Unix symlinks */
4567BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4568{
4569 WIN32_FILE_ATTRIBUTE_DATA info;
4570 WIN32_FIND_DATAW find_data;
4571 HANDLE find_data_handle;
4572 int is_directory = 0;
4573 int is_link = 0;
4574
4575 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4576 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004577
Brian Curtind40e6f72010-07-08 21:39:08 +00004578 /* Get WIN32_FIND_DATA structure for the path to determine if
4579 it is a symlink */
4580 if(is_directory &&
4581 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4582 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4583
4584 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004585 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4586 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4587 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4588 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004589 FindClose(find_data_handle);
4590 }
4591 }
4592 }
4593
4594 if (is_directory && is_link)
4595 return RemoveDirectoryW(lpFileName);
4596
4597 return DeleteFileW(lpFileName);
4598}
4599#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004600
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004601
Larry Hastings2f936352014-08-05 14:04:04 +10004602/*[clinic input]
4603os.unlink
4604
4605 path: path_t
4606 *
4607 dir_fd: dir_fd(requires='unlinkat')=None
4608
4609Remove a file (same as remove()).
4610
4611If dir_fd is not None, it should be a file descriptor open to a directory,
4612 and path should be relative; path will then be relative to that directory.
4613dir_fd may not be implemented on your platform.
4614 If it is unavailable, using it will raise a NotImplementedError.
4615
4616[clinic start generated code]*/
4617
Larry Hastings2f936352014-08-05 14:04:04 +10004618static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004619os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4620/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004621{
4622 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004623
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004624 if (PySys_Audit("os.remove", "Oi", path->object,
4625 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4626 return NULL;
4627 }
4628
Larry Hastings9cf065c2012-06-22 16:30:09 -07004629 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004630 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004632 /* Windows, success=1, UNIX, success=0 */
4633 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004634#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004635#ifdef HAVE_UNLINKAT
4636 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004637 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004638 else
4639#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004640 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004642 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004643 Py_END_ALLOW_THREADS
4644
Larry Hastings2f936352014-08-05 14:04:04 +10004645 if (result)
4646 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647
Larry Hastings2f936352014-08-05 14:04:04 +10004648 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004649}
4650
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004651
Larry Hastings2f936352014-08-05 14:04:04 +10004652/*[clinic input]
4653os.remove = os.unlink
4654
4655Remove a file (same as unlink()).
4656
4657If dir_fd is not None, it should be a file descriptor open to a directory,
4658 and path should be relative; path will then be relative to that directory.
4659dir_fd may not be implemented on your platform.
4660 If it is unavailable, using it will raise a NotImplementedError.
4661[clinic start generated code]*/
4662
Larry Hastings2f936352014-08-05 14:04:04 +10004663static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004664os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4665/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004666{
4667 return os_unlink_impl(module, path, dir_fd);
4668}
4669
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004670
Larry Hastings605a62d2012-06-24 04:33:36 -07004671static PyStructSequence_Field uname_result_fields[] = {
4672 {"sysname", "operating system name"},
4673 {"nodename", "name of machine on network (implementation-defined)"},
4674 {"release", "operating system release"},
4675 {"version", "operating system version"},
4676 {"machine", "hardware identifier"},
4677 {NULL}
4678};
4679
4680PyDoc_STRVAR(uname_result__doc__,
4681"uname_result: Result from os.uname().\n\n\
4682This object may be accessed either as a tuple of\n\
4683 (sysname, nodename, release, version, machine),\n\
4684or via the attributes sysname, nodename, release, version, and machine.\n\
4685\n\
4686See os.uname for more information.");
4687
4688static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08004689 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07004690 uname_result__doc__, /* doc */
4691 uname_result_fields,
4692 5
4693};
4694
Larry Hastings605a62d2012-06-24 04:33:36 -07004695#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004696/*[clinic input]
4697os.uname
4698
4699Return an object identifying the current operating system.
4700
4701The object behaves like a named tuple with the following fields:
4702 (sysname, nodename, release, version, machine)
4703
4704[clinic start generated code]*/
4705
Larry Hastings2f936352014-08-05 14:04:04 +10004706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004707os_uname_impl(PyObject *module)
4708/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004709{
Victor Stinner8c62be82010-05-06 00:08:46 +00004710 struct utsname u;
4711 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004712 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004713
Victor Stinner8c62be82010-05-06 00:08:46 +00004714 Py_BEGIN_ALLOW_THREADS
4715 res = uname(&u);
4716 Py_END_ALLOW_THREADS
4717 if (res < 0)
4718 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004719
Hai Shif707d942020-03-16 21:15:01 +08004720 PyObject *UnameResultType = get_posix_state(module)->UnameResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08004721 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004722 if (value == NULL)
4723 return NULL;
4724
4725#define SET(i, field) \
4726 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004727 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004728 if (!o) { \
4729 Py_DECREF(value); \
4730 return NULL; \
4731 } \
4732 PyStructSequence_SET_ITEM(value, i, o); \
4733 } \
4734
4735 SET(0, u.sysname);
4736 SET(1, u.nodename);
4737 SET(2, u.release);
4738 SET(3, u.version);
4739 SET(4, u.machine);
4740
4741#undef SET
4742
4743 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004744}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004745#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004746
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004747
Larry Hastings9cf065c2012-06-22 16:30:09 -07004748
4749typedef struct {
4750 int now;
4751 time_t atime_s;
4752 long atime_ns;
4753 time_t mtime_s;
4754 long mtime_ns;
4755} utime_t;
4756
4757/*
Victor Stinner484df002014-10-09 13:52:31 +02004758 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004759 * they also intentionally leak the declaration of a pointer named "time"
4760 */
4761#define UTIME_TO_TIMESPEC \
4762 struct timespec ts[2]; \
4763 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004764 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 time = NULL; \
4766 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004767 ts[0].tv_sec = ut->atime_s; \
4768 ts[0].tv_nsec = ut->atime_ns; \
4769 ts[1].tv_sec = ut->mtime_s; \
4770 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004771 time = ts; \
4772 } \
4773
4774#define UTIME_TO_TIMEVAL \
4775 struct timeval tv[2]; \
4776 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004777 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004778 time = NULL; \
4779 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004780 tv[0].tv_sec = ut->atime_s; \
4781 tv[0].tv_usec = ut->atime_ns / 1000; \
4782 tv[1].tv_sec = ut->mtime_s; \
4783 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004784 time = tv; \
4785 } \
4786
4787#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004788 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004789 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004790 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004791 time = NULL; \
4792 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004793 u.actime = ut->atime_s; \
4794 u.modtime = ut->mtime_s; \
4795 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004796 }
4797
4798#define UTIME_TO_TIME_T \
4799 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004800 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004801 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004802 time = NULL; \
4803 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004804 timet[0] = ut->atime_s; \
4805 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004806 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004807 } \
4808
4809
Victor Stinner528a9ab2015-09-03 21:30:26 +02004810#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811
4812static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004813utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004814{
4815#ifdef HAVE_UTIMENSAT
4816 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4817 UTIME_TO_TIMESPEC;
4818 return utimensat(dir_fd, path, time, flags);
4819#elif defined(HAVE_FUTIMESAT)
4820 UTIME_TO_TIMEVAL;
4821 /*
4822 * follow_symlinks will never be false here;
4823 * we only allow !follow_symlinks and dir_fd together
4824 * if we have utimensat()
4825 */
4826 assert(follow_symlinks);
4827 return futimesat(dir_fd, path, time);
4828#endif
4829}
4830
Larry Hastings2f936352014-08-05 14:04:04 +10004831 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4832#else
4833 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004834#endif
4835
Victor Stinner528a9ab2015-09-03 21:30:26 +02004836#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004837
4838static int
Victor Stinner484df002014-10-09 13:52:31 +02004839utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004840{
4841#ifdef HAVE_FUTIMENS
4842 UTIME_TO_TIMESPEC;
4843 return futimens(fd, time);
4844#else
4845 UTIME_TO_TIMEVAL;
4846 return futimes(fd, time);
4847#endif
4848}
4849
Larry Hastings2f936352014-08-05 14:04:04 +10004850 #define PATH_UTIME_HAVE_FD 1
4851#else
4852 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004853#endif
4854
Victor Stinner5ebae872015-09-22 01:29:33 +02004855#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4856# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4857#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004858
Victor Stinner4552ced2015-09-21 22:37:15 +02004859#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004860
4861static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004862utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004863{
4864#ifdef HAVE_UTIMENSAT
4865 UTIME_TO_TIMESPEC;
4866 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4867#else
4868 UTIME_TO_TIMEVAL;
4869 return lutimes(path, time);
4870#endif
4871}
4872
4873#endif
4874
4875#ifndef MS_WINDOWS
4876
4877static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004878utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004879{
4880#ifdef HAVE_UTIMENSAT
4881 UTIME_TO_TIMESPEC;
4882 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4883#elif defined(HAVE_UTIMES)
4884 UTIME_TO_TIMEVAL;
4885 return utimes(path, time);
4886#elif defined(HAVE_UTIME_H)
4887 UTIME_TO_UTIMBUF;
4888 return utime(path, time);
4889#else
4890 UTIME_TO_TIME_T;
4891 return utime(path, time);
4892#endif
4893}
4894
4895#endif
4896
Larry Hastings76ad59b2012-05-03 00:30:07 -07004897static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02004898split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004899{
4900 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004901 PyObject *divmod;
Victor Stinner1c2fa782020-05-10 11:05:29 +02004902 divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07004903 if (!divmod)
4904 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004905 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4906 PyErr_Format(PyExc_TypeError,
4907 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08004908 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004909 goto exit;
4910 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004911 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4912 if ((*s == -1) && PyErr_Occurred())
4913 goto exit;
4914 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004915 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004916 goto exit;
4917
4918 result = 1;
4919exit:
4920 Py_XDECREF(divmod);
4921 return result;
4922}
4923
Larry Hastings2f936352014-08-05 14:04:04 +10004924
4925/*[clinic input]
4926os.utime
4927
4928 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004929 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10004930 *
4931 ns: object = NULL
4932 dir_fd: dir_fd(requires='futimensat') = None
4933 follow_symlinks: bool=True
4934
Martin Panter0ff89092015-09-09 01:56:53 +00004935# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004936
4937Set the access and modified time of path.
4938
4939path may always be specified as a string.
4940On some platforms, path may also be specified as an open file descriptor.
4941 If this functionality is unavailable, using it raises an exception.
4942
4943If times is not None, it must be a tuple (atime, mtime);
4944 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004945If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004946 atime_ns and mtime_ns should be expressed as integer nanoseconds
4947 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004948If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004949Specifying tuples for both times and ns is an error.
4950
4951If dir_fd is not None, it should be a file descriptor open to a directory,
4952 and path should be relative; path will then be relative to that directory.
4953If follow_symlinks is False, and the last element of the path is a symbolic
4954 link, utime will modify the symbolic link itself instead of the file the
4955 link points to.
4956It is an error to use dir_fd or follow_symlinks when specifying path
4957 as an open file descriptor.
4958dir_fd and follow_symlinks may not be available on your platform.
4959 If they are unavailable, using them will raise a NotImplementedError.
4960
4961[clinic start generated code]*/
4962
Larry Hastings2f936352014-08-05 14:04:04 +10004963static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004964os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4965 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004966/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004967{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968#ifdef MS_WINDOWS
4969 HANDLE hFile;
4970 FILETIME atime, mtime;
4971#else
4972 int result;
4973#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004974
Larry Hastings2f936352014-08-05 14:04:04 +10004975 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004976
Christian Heimesb3c87242013-08-01 00:08:16 +02004977 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004978
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004979 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004980 PyErr_SetString(PyExc_ValueError,
4981 "utime: you may specify either 'times'"
4982 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004983 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004984 }
4985
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004986 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004987 time_t a_sec, m_sec;
4988 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004989 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004990 PyErr_SetString(PyExc_TypeError,
4991 "utime: 'times' must be either"
4992 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004993 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004994 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004995 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004996 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004997 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004998 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004999 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005000 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005001 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005002 utime.atime_s = a_sec;
5003 utime.atime_ns = a_nsec;
5004 utime.mtime_s = m_sec;
5005 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005006 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005007 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07005008 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005009 PyErr_SetString(PyExc_TypeError,
5010 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005011 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005012 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005013 utime.now = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005014 if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005015 &utime.atime_s, &utime.atime_ns) ||
Victor Stinner1c2fa782020-05-10 11:05:29 +02005016 !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005017 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005018 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005019 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005020 }
5021 else {
5022 /* times and ns are both None/unspecified. use "now". */
5023 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005024 }
5025
Victor Stinner4552ced2015-09-21 22:37:15 +02005026#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005027 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005028 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005029#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005030
Larry Hastings2f936352014-08-05 14:04:04 +10005031 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
5032 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
5033 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005034 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005035
Larry Hastings9cf065c2012-06-22 16:30:09 -07005036#if !defined(HAVE_UTIMENSAT)
5037 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02005038 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005039 "utime: cannot use dir_fd and follow_symlinks "
5040 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005041 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005042 }
5043#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005044
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005045 if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
5046 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
5047 return NULL;
5048 }
5049
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005050#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005051 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005052 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5053 NULL, OPEN_EXISTING,
5054 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005055 Py_END_ALLOW_THREADS
5056 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10005057 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005058 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005059 }
5060
Larry Hastings9cf065c2012-06-22 16:30:09 -07005061 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005062 GetSystemTimeAsFileTime(&mtime);
5063 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005065 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08005066 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5067 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005068 }
5069 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5070 /* Avoid putting the file name into the error here,
5071 as that may confuse the user into believing that
5072 something is wrong with the file, when it also
5073 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005074 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005075 CloseHandle(hFile);
5076 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005077 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005078 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005079#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005080 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005081
Victor Stinner4552ced2015-09-21 22:37:15 +02005082#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005083 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10005084 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005085 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005086#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005087
Victor Stinner528a9ab2015-09-03 21:30:26 +02005088#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005089 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10005090 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005091 else
5092#endif
5093
Victor Stinner528a9ab2015-09-03 21:30:26 +02005094#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005095 if (path->fd != -1)
5096 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005097 else
5098#endif
5099
Larry Hastings2f936352014-08-05 14:04:04 +10005100 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005101
5102 Py_END_ALLOW_THREADS
5103
5104 if (result < 0) {
5105 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005106 posix_error();
5107 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005108 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005109
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005110#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005111
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005112 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005113}
5114
Guido van Rossum3b066191991-06-04 19:40:25 +00005115/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005116
Larry Hastings2f936352014-08-05 14:04:04 +10005117
5118/*[clinic input]
5119os._exit
5120
5121 status: int
5122
5123Exit to the system with specified status, without normal exit processing.
5124[clinic start generated code]*/
5125
Larry Hastings2f936352014-08-05 14:04:04 +10005126static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005127os__exit_impl(PyObject *module, int status)
5128/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005129{
5130 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005132}
5133
Steve Dowercc16be82016-09-08 10:35:16 -07005134#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5135#define EXECV_CHAR wchar_t
5136#else
5137#define EXECV_CHAR char
5138#endif
5139
pxinwrf2d7ac72019-05-21 18:46:37 +08005140#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005141static void
Steve Dowercc16be82016-09-08 10:35:16 -07005142free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005143{
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 Py_ssize_t i;
5145 for (i = 0; i < count; i++)
5146 PyMem_Free(array[i]);
5147 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005148}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005149
Berker Peksag81816462016-09-15 20:19:47 +03005150static int
5151fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005152{
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005154 PyObject *ub;
5155 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005156#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005157 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005158 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005159 *out = PyUnicode_AsWideCharString(ub, &size);
5160 if (*out)
5161 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005162#else
Berker Peksag81816462016-09-15 20:19:47 +03005163 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005165 size = PyBytes_GET_SIZE(ub);
5166 *out = PyMem_Malloc(size + 1);
5167 if (*out) {
5168 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5169 result = 1;
5170 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005171 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005172#endif
Berker Peksag81816462016-09-15 20:19:47 +03005173 Py_DECREF(ub);
5174 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005175}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005176#endif
5177
pxinwrf2d7ac72019-05-21 18:46:37 +08005178#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005179static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005180parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5181{
Victor Stinner8c62be82010-05-06 00:08:46 +00005182 Py_ssize_t i, pos, envc;
5183 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005184 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005185 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005186
Victor Stinner8c62be82010-05-06 00:08:46 +00005187 i = PyMapping_Size(env);
5188 if (i < 0)
5189 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005190 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005191 if (envlist == NULL) {
5192 PyErr_NoMemory();
5193 return NULL;
5194 }
5195 envc = 0;
5196 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005197 if (!keys)
5198 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005199 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005200 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 goto error;
5202 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5203 PyErr_Format(PyExc_TypeError,
5204 "env.keys() or env.values() is not a list");
5205 goto error;
5206 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005207
Victor Stinner8c62be82010-05-06 00:08:46 +00005208 for (pos = 0; pos < i; pos++) {
5209 key = PyList_GetItem(keys, pos);
5210 val = PyList_GetItem(vals, pos);
5211 if (!key || !val)
5212 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005213
Berker Peksag81816462016-09-15 20:19:47 +03005214#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5215 if (!PyUnicode_FSDecoder(key, &key2))
5216 goto error;
5217 if (!PyUnicode_FSDecoder(val, &val2)) {
5218 Py_DECREF(key2);
5219 goto error;
5220 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005221 /* Search from index 1 because on Windows starting '=' is allowed for
5222 defining hidden environment variables. */
5223 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5224 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5225 {
5226 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005227 Py_DECREF(key2);
5228 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005229 goto error;
5230 }
Berker Peksag81816462016-09-15 20:19:47 +03005231 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5232#else
5233 if (!PyUnicode_FSConverter(key, &key2))
5234 goto error;
5235 if (!PyUnicode_FSConverter(val, &val2)) {
5236 Py_DECREF(key2);
5237 goto error;
5238 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005239 if (PyBytes_GET_SIZE(key2) == 0 ||
5240 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5241 {
5242 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005243 Py_DECREF(key2);
5244 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005245 goto error;
5246 }
Berker Peksag81816462016-09-15 20:19:47 +03005247 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5248 PyBytes_AS_STRING(val2));
5249#endif
5250 Py_DECREF(key2);
5251 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005252 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005253 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005254
5255 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5256 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005257 goto error;
5258 }
Berker Peksag81816462016-09-15 20:19:47 +03005259
Steve Dowercc16be82016-09-08 10:35:16 -07005260 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005261 }
5262 Py_DECREF(vals);
5263 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005264
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 envlist[envc] = 0;
5266 *envc_ptr = envc;
5267 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005268
5269error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005270 Py_XDECREF(keys);
5271 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005272 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005274}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005275
Steve Dowercc16be82016-09-08 10:35:16 -07005276static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005277parse_arglist(PyObject* argv, Py_ssize_t *argc)
5278{
5279 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005280 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005281 if (argvlist == NULL) {
5282 PyErr_NoMemory();
5283 return NULL;
5284 }
5285 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005286 PyObject* item = PySequence_ITEM(argv, i);
5287 if (item == NULL)
5288 goto fail;
5289 if (!fsconvert_strdup(item, &argvlist[i])) {
5290 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005291 goto fail;
5292 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005293 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005294 }
5295 argvlist[*argc] = NULL;
5296 return argvlist;
5297fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005298 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005299 free_string_array(argvlist, *argc);
5300 return NULL;
5301}
Steve Dowercc16be82016-09-08 10:35:16 -07005302
Ross Lagerwall7807c352011-03-17 20:20:30 +02005303#endif
5304
Larry Hastings2f936352014-08-05 14:04:04 +10005305
Ross Lagerwall7807c352011-03-17 20:20:30 +02005306#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005307/*[clinic input]
5308os.execv
5309
Steve Dowercc16be82016-09-08 10:35:16 -07005310 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005311 Path of executable file.
5312 argv: object
5313 Tuple or list of strings.
5314 /
5315
5316Execute an executable path with arguments, replacing current process.
5317[clinic start generated code]*/
5318
Larry Hastings2f936352014-08-05 14:04:04 +10005319static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005320os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5321/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005322{
Steve Dowercc16be82016-09-08 10:35:16 -07005323 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005324 Py_ssize_t argc;
5325
5326 /* execv has two arguments: (path, argv), where
5327 argv is a list or tuple of strings. */
5328
Ross Lagerwall7807c352011-03-17 20:20:30 +02005329 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5330 PyErr_SetString(PyExc_TypeError,
5331 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005332 return NULL;
5333 }
5334 argc = PySequence_Size(argv);
5335 if (argc < 1) {
5336 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005337 return NULL;
5338 }
5339
5340 argvlist = parse_arglist(argv, &argc);
5341 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005342 return NULL;
5343 }
Steve Dowerbce26262016-11-19 19:17:26 -08005344 if (!argvlist[0][0]) {
5345 PyErr_SetString(PyExc_ValueError,
5346 "execv() arg 2 first element cannot be empty");
5347 free_string_array(argvlist, argc);
5348 return NULL;
5349 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005350
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005351 if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005352 free_string_array(argvlist, argc);
5353 return NULL;
5354 }
5355
Steve Dowerbce26262016-11-19 19:17:26 -08005356 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005357#ifdef HAVE_WEXECV
5358 _wexecv(path->wide, argvlist);
5359#else
5360 execv(path->narrow, argvlist);
5361#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005362 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005363
5364 /* If we get here it's definitely an error */
5365
5366 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005367 return posix_error();
5368}
5369
Larry Hastings2f936352014-08-05 14:04:04 +10005370
5371/*[clinic input]
5372os.execve
5373
5374 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5375 Path of executable file.
5376 argv: object
5377 Tuple or list of strings.
5378 env: object
5379 Dictionary of strings mapping to strings.
5380
5381Execute an executable path with arguments, replacing current process.
5382[clinic start generated code]*/
5383
Larry Hastings2f936352014-08-05 14:04:04 +10005384static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005385os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5386/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005387{
Steve Dowercc16be82016-09-08 10:35:16 -07005388 EXECV_CHAR **argvlist = NULL;
5389 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005390 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005391
Victor Stinner8c62be82010-05-06 00:08:46 +00005392 /* execve has three arguments: (path, argv, env), where
5393 argv is a list or tuple of strings and env is a dictionary
5394 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005395
Ross Lagerwall7807c352011-03-17 20:20:30 +02005396 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005397 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005398 "execve: argv must be a tuple or list");
Saiyang Gou95f60012020-02-04 16:15:00 -08005399 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005400 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005401 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005402 if (argc < 1) {
5403 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5404 return NULL;
5405 }
5406
Victor Stinner8c62be82010-05-06 00:08:46 +00005407 if (!PyMapping_Check(env)) {
5408 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005409 "execve: environment must be a mapping object");
Saiyang Gou95f60012020-02-04 16:15:00 -08005410 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005411 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005412
Ross Lagerwall7807c352011-03-17 20:20:30 +02005413 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005414 if (argvlist == NULL) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005415 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005416 }
Steve Dowerbce26262016-11-19 19:17:26 -08005417 if (!argvlist[0][0]) {
5418 PyErr_SetString(PyExc_ValueError,
5419 "execve: argv first element cannot be empty");
Saiyang Gou95f60012020-02-04 16:15:00 -08005420 goto fail_0;
Steve Dowerbce26262016-11-19 19:17:26 -08005421 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005422
Victor Stinner8c62be82010-05-06 00:08:46 +00005423 envlist = parse_envlist(env, &envc);
5424 if (envlist == NULL)
Saiyang Gou95f60012020-02-04 16:15:00 -08005425 goto fail_0;
5426
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005427 if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005428 goto fail_1;
5429 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005430
Steve Dowerbce26262016-11-19 19:17:26 -08005431 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005432#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005433 if (path->fd > -1)
5434 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005435 else
5436#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005437#ifdef HAVE_WEXECV
5438 _wexecve(path->wide, argvlist, envlist);
5439#else
Larry Hastings2f936352014-08-05 14:04:04 +10005440 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005441#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005442 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005443
5444 /* If we get here it's definitely an error */
5445
Alexey Izbyshev83460312018-10-20 03:28:22 +03005446 posix_path_error(path);
Saiyang Gou95f60012020-02-04 16:15:00 -08005447 fail_1:
Steve Dowercc16be82016-09-08 10:35:16 -07005448 free_string_array(envlist, envc);
Saiyang Gou95f60012020-02-04 16:15:00 -08005449 fail_0:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005450 if (argvlist)
5451 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005452 return NULL;
5453}
Steve Dowercc16be82016-09-08 10:35:16 -07005454
Larry Hastings9cf065c2012-06-22 16:30:09 -07005455#endif /* HAVE_EXECV */
5456
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005457#ifdef HAVE_POSIX_SPAWN
5458
5459enum posix_spawn_file_actions_identifier {
5460 POSIX_SPAWN_OPEN,
5461 POSIX_SPAWN_CLOSE,
5462 POSIX_SPAWN_DUP2
5463};
5464
William Orr81574b82018-10-01 22:19:56 -07005465#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005466static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005467convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005468#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005469
5470static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005471parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005472 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005473 PyObject *setsigdef, PyObject *scheduler,
5474 posix_spawnattr_t *attrp)
5475{
5476 long all_flags = 0;
5477
5478 errno = posix_spawnattr_init(attrp);
5479 if (errno) {
5480 posix_error();
5481 return -1;
5482 }
5483
5484 if (setpgroup) {
5485 pid_t pgid = PyLong_AsPid(setpgroup);
5486 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5487 goto fail;
5488 }
5489 errno = posix_spawnattr_setpgroup(attrp, pgid);
5490 if (errno) {
5491 posix_error();
5492 goto fail;
5493 }
5494 all_flags |= POSIX_SPAWN_SETPGROUP;
5495 }
5496
5497 if (resetids) {
5498 all_flags |= POSIX_SPAWN_RESETIDS;
5499 }
5500
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005501 if (setsid) {
5502#ifdef POSIX_SPAWN_SETSID
5503 all_flags |= POSIX_SPAWN_SETSID;
5504#elif defined(POSIX_SPAWN_SETSID_NP)
5505 all_flags |= POSIX_SPAWN_SETSID_NP;
5506#else
5507 argument_unavailable_error(func_name, "setsid");
5508 return -1;
5509#endif
5510 }
5511
Pablo Galindo254a4662018-09-07 16:44:24 +01005512 if (setsigmask) {
5513 sigset_t set;
5514 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5515 goto fail;
5516 }
5517 errno = posix_spawnattr_setsigmask(attrp, &set);
5518 if (errno) {
5519 posix_error();
5520 goto fail;
5521 }
5522 all_flags |= POSIX_SPAWN_SETSIGMASK;
5523 }
5524
5525 if (setsigdef) {
5526 sigset_t set;
5527 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5528 goto fail;
5529 }
5530 errno = posix_spawnattr_setsigdefault(attrp, &set);
5531 if (errno) {
5532 posix_error();
5533 goto fail;
5534 }
5535 all_flags |= POSIX_SPAWN_SETSIGDEF;
5536 }
5537
5538 if (scheduler) {
5539#ifdef POSIX_SPAWN_SETSCHEDULER
5540 PyObject *py_schedpolicy;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005541 PyObject *schedparam_obj;
Pablo Galindo254a4662018-09-07 16:44:24 +01005542 struct sched_param schedparam;
5543
Victor Stinner1c2fa782020-05-10 11:05:29 +02005544 if (!PyArg_ParseTuple(scheduler, "OO"
Pablo Galindo254a4662018-09-07 16:44:24 +01005545 ";A scheduler tuple must have two elements",
Victor Stinner1c2fa782020-05-10 11:05:29 +02005546 &py_schedpolicy, &schedparam_obj)) {
5547 goto fail;
5548 }
5549 if (!convert_sched_param(module, schedparam_obj, &schedparam)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005550 goto fail;
5551 }
5552 if (py_schedpolicy != Py_None) {
5553 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5554
5555 if (schedpolicy == -1 && PyErr_Occurred()) {
5556 goto fail;
5557 }
5558 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5559 if (errno) {
5560 posix_error();
5561 goto fail;
5562 }
5563 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5564 }
5565 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5566 if (errno) {
5567 posix_error();
5568 goto fail;
5569 }
5570 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5571#else
5572 PyErr_SetString(PyExc_NotImplementedError,
5573 "The scheduler option is not supported in this system.");
5574 goto fail;
5575#endif
5576 }
5577
5578 errno = posix_spawnattr_setflags(attrp, all_flags);
5579 if (errno) {
5580 posix_error();
5581 goto fail;
5582 }
5583
5584 return 0;
5585
5586fail:
5587 (void)posix_spawnattr_destroy(attrp);
5588 return -1;
5589}
5590
5591static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005592parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005593 posix_spawn_file_actions_t *file_actionsp,
5594 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005595{
5596 PyObject *seq;
5597 PyObject *file_action = NULL;
5598 PyObject *tag_obj;
5599
5600 seq = PySequence_Fast(file_actions,
5601 "file_actions must be a sequence or None");
5602 if (seq == NULL) {
5603 return -1;
5604 }
5605
5606 errno = posix_spawn_file_actions_init(file_actionsp);
5607 if (errno) {
5608 posix_error();
5609 Py_DECREF(seq);
5610 return -1;
5611 }
5612
Zackery Spytzd52a83a2019-06-26 14:54:20 -06005613 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03005614 file_action = PySequence_Fast_GET_ITEM(seq, i);
5615 Py_INCREF(file_action);
5616 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5617 PyErr_SetString(PyExc_TypeError,
5618 "Each file_actions element must be a non-empty tuple");
5619 goto fail;
5620 }
5621 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5622 if (tag == -1 && PyErr_Occurred()) {
5623 goto fail;
5624 }
5625
5626 /* Populate the file_actions object */
5627 switch (tag) {
5628 case POSIX_SPAWN_OPEN: {
5629 int fd, oflag;
5630 PyObject *path;
5631 unsigned long mode;
5632 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5633 ";A open file_action tuple must have 5 elements",
5634 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5635 &oflag, &mode))
5636 {
5637 goto fail;
5638 }
Pablo Galindocb970732018-06-19 09:19:50 +01005639 if (PyList_Append(temp_buffer, path)) {
5640 Py_DECREF(path);
5641 goto fail;
5642 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005643 errno = posix_spawn_file_actions_addopen(file_actionsp,
5644 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005645 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005646 if (errno) {
5647 posix_error();
5648 goto fail;
5649 }
5650 break;
5651 }
5652 case POSIX_SPAWN_CLOSE: {
5653 int fd;
5654 if (!PyArg_ParseTuple(file_action, "Oi"
5655 ";A close file_action tuple must have 2 elements",
5656 &tag_obj, &fd))
5657 {
5658 goto fail;
5659 }
5660 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5661 if (errno) {
5662 posix_error();
5663 goto fail;
5664 }
5665 break;
5666 }
5667 case POSIX_SPAWN_DUP2: {
5668 int fd1, fd2;
5669 if (!PyArg_ParseTuple(file_action, "Oii"
5670 ";A dup2 file_action tuple must have 3 elements",
5671 &tag_obj, &fd1, &fd2))
5672 {
5673 goto fail;
5674 }
5675 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5676 fd1, fd2);
5677 if (errno) {
5678 posix_error();
5679 goto fail;
5680 }
5681 break;
5682 }
5683 default: {
5684 PyErr_SetString(PyExc_TypeError,
5685 "Unknown file_actions identifier");
5686 goto fail;
5687 }
5688 }
5689 Py_DECREF(file_action);
5690 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005691
Serhiy Storchakaef347532018-05-01 16:45:04 +03005692 Py_DECREF(seq);
5693 return 0;
5694
5695fail:
5696 Py_DECREF(seq);
5697 Py_DECREF(file_action);
5698 (void)posix_spawn_file_actions_destroy(file_actionsp);
5699 return -1;
5700}
5701
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005702
5703static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005704py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5705 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005706 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005707 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005708{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005709 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005710 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005711 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005712 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005713 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005714 posix_spawnattr_t attr;
5715 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005716 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005717 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005718 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005719 pid_t pid;
5720 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005721
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005722 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005723 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005724 like posix.environ. */
5725
Serhiy Storchakaef347532018-05-01 16:45:04 +03005726 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005727 PyErr_Format(PyExc_TypeError,
5728 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005729 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005730 }
5731 argc = PySequence_Size(argv);
5732 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005733 PyErr_Format(PyExc_ValueError,
5734 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005735 return NULL;
5736 }
5737
5738 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005739 PyErr_Format(PyExc_TypeError,
5740 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005741 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005742 }
5743
5744 argvlist = parse_arglist(argv, &argc);
5745 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005746 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005747 }
5748 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005749 PyErr_Format(PyExc_ValueError,
5750 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005751 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005752 }
5753
5754 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005755 if (envlist == NULL) {
5756 goto exit;
5757 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005758
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005759 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005760 /* There is a bug in old versions of glibc that makes some of the
5761 * helper functions for manipulating file actions not copy the provided
5762 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5763 * copy the value of path for some old versions of glibc (<2.20).
5764 * The use of temp_buffer here is a workaround that keeps the
5765 * python objects that own the buffers alive until posix_spawn gets called.
5766 * Check https://bugs.python.org/issue33630 and
5767 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5768 temp_buffer = PyList_New(0);
5769 if (!temp_buffer) {
5770 goto exit;
5771 }
5772 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005773 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005774 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005775 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005776 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005777
Victor Stinner1c2fa782020-05-10 11:05:29 +02005778 if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005779 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005780 goto exit;
5781 }
5782 attrp = &attr;
5783
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005784 if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005785 goto exit;
5786 }
5787
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005788 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005789#ifdef HAVE_POSIX_SPAWNP
5790 if (use_posix_spawnp) {
5791 err_code = posix_spawnp(&pid, path->narrow,
5792 file_actionsp, attrp, argvlist, envlist);
5793 }
5794 else
5795#endif /* HAVE_POSIX_SPAWNP */
5796 {
5797 err_code = posix_spawn(&pid, path->narrow,
5798 file_actionsp, attrp, argvlist, envlist);
5799 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005800 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005801
Serhiy Storchakaef347532018-05-01 16:45:04 +03005802 if (err_code) {
5803 errno = err_code;
5804 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005805 goto exit;
5806 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005807#ifdef _Py_MEMORY_SANITIZER
5808 __msan_unpoison(&pid, sizeof(pid));
5809#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005810 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005811
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005812exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005813 if (file_actionsp) {
5814 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005815 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005816 if (attrp) {
5817 (void)posix_spawnattr_destroy(attrp);
5818 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005819 if (envlist) {
5820 free_string_array(envlist, envc);
5821 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005822 if (argvlist) {
5823 free_string_array(argvlist, argc);
5824 }
Pablo Galindocb970732018-06-19 09:19:50 +01005825 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005826 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005827}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005828
5829
5830/*[clinic input]
5831
5832os.posix_spawn
5833 path: path_t
5834 Path of executable file.
5835 argv: object
5836 Tuple or list of strings.
5837 env: object
5838 Dictionary of strings mapping to strings.
5839 /
5840 *
5841 file_actions: object(c_default='NULL') = ()
5842 A sequence of file action tuples.
5843 setpgroup: object = NULL
5844 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5845 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005846 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5847 setsid: bool(accept={int}) = False
5848 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005849 setsigmask: object(c_default='NULL') = ()
5850 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5851 setsigdef: object(c_default='NULL') = ()
5852 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5853 scheduler: object = NULL
5854 A tuple with the scheduler policy (optional) and parameters.
5855
5856Execute the program specified by path in a new process.
5857[clinic start generated code]*/
5858
5859static PyObject *
5860os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5861 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005862 PyObject *setpgroup, int resetids, int setsid,
5863 PyObject *setsigmask, PyObject *setsigdef,
5864 PyObject *scheduler)
5865/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005866{
5867 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005868 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005869 scheduler);
5870}
5871 #endif /* HAVE_POSIX_SPAWN */
5872
5873
5874
5875#ifdef HAVE_POSIX_SPAWNP
5876/*[clinic input]
5877
5878os.posix_spawnp
5879 path: path_t
5880 Path of executable file.
5881 argv: object
5882 Tuple or list of strings.
5883 env: object
5884 Dictionary of strings mapping to strings.
5885 /
5886 *
5887 file_actions: object(c_default='NULL') = ()
5888 A sequence of file action tuples.
5889 setpgroup: object = NULL
5890 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5891 resetids: bool(accept={int}) = False
5892 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005893 setsid: bool(accept={int}) = False
5894 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005895 setsigmask: object(c_default='NULL') = ()
5896 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5897 setsigdef: object(c_default='NULL') = ()
5898 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5899 scheduler: object = NULL
5900 A tuple with the scheduler policy (optional) and parameters.
5901
5902Execute the program specified by path in a new process.
5903[clinic start generated code]*/
5904
5905static PyObject *
5906os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5907 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005908 PyObject *setpgroup, int resetids, int setsid,
5909 PyObject *setsigmask, PyObject *setsigdef,
5910 PyObject *scheduler)
5911/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005912{
5913 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005914 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005915 scheduler);
5916}
5917#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005918
pxinwrf2d7ac72019-05-21 18:46:37 +08005919#ifdef HAVE_RTPSPAWN
5920static intptr_t
5921_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5922 const char *envp[])
5923{
5924 RTP_ID rtpid;
5925 int status;
5926 pid_t res;
5927 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005928
pxinwrf2d7ac72019-05-21 18:46:37 +08005929 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5930 uStackSize=0 cannot be used, the default stack size is too small for
5931 Python. */
5932 if (envp) {
5933 rtpid = rtpSpawn(rtpFileName, argv, envp,
5934 100, 0x1000000, 0, VX_FP_TASK);
5935 }
5936 else {
5937 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5938 100, 0x1000000, 0, VX_FP_TASK);
5939 }
5940 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5941 do {
5942 res = waitpid((pid_t)rtpid, &status, 0);
5943 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5944
5945 if (res < 0)
5946 return RTP_ID_ERROR;
5947 return ((intptr_t)status);
5948 }
5949 return ((intptr_t)rtpid);
5950}
5951#endif
5952
5953#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10005954/*[clinic input]
5955os.spawnv
5956
5957 mode: int
5958 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005959 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005960 Path of executable file.
5961 argv: object
5962 Tuple or list of strings.
5963 /
5964
5965Execute the program specified by path in a new process.
5966[clinic start generated code]*/
5967
Larry Hastings2f936352014-08-05 14:04:04 +10005968static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005969os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5970/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005971{
Steve Dowercc16be82016-09-08 10:35:16 -07005972 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005973 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005974 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005975 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005976 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005977
Victor Stinner8c62be82010-05-06 00:08:46 +00005978 /* spawnv has three arguments: (mode, path, argv), where
5979 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005980
Victor Stinner8c62be82010-05-06 00:08:46 +00005981 if (PyList_Check(argv)) {
5982 argc = PyList_Size(argv);
5983 getitem = PyList_GetItem;
5984 }
5985 else if (PyTuple_Check(argv)) {
5986 argc = PyTuple_Size(argv);
5987 getitem = PyTuple_GetItem;
5988 }
5989 else {
5990 PyErr_SetString(PyExc_TypeError,
5991 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005992 return NULL;
5993 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005994 if (argc == 0) {
5995 PyErr_SetString(PyExc_ValueError,
5996 "spawnv() arg 2 cannot be empty");
5997 return NULL;
5998 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005999
Steve Dowercc16be82016-09-08 10:35:16 -07006000 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006001 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 return PyErr_NoMemory();
6003 }
6004 for (i = 0; i < argc; i++) {
6005 if (!fsconvert_strdup((*getitem)(argv, i),
6006 &argvlist[i])) {
6007 free_string_array(argvlist, i);
6008 PyErr_SetString(
6009 PyExc_TypeError,
6010 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00006011 return NULL;
6012 }
Steve Dower93ff8722016-11-19 19:03:54 -08006013 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02006014 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08006015 PyErr_SetString(
6016 PyExc_ValueError,
6017 "spawnv() arg 2 first element cannot be empty");
6018 return NULL;
6019 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006020 }
6021 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006022
pxinwrf2d7ac72019-05-21 18:46:37 +08006023#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006024 if (mode == _OLD_P_OVERLAY)
6025 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006026#endif
Tim Peters5aa91602002-01-30 05:46:57 +00006027
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006028 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
Saiyang Gou95f60012020-02-04 16:15:00 -08006029 Py_None) < 0) {
6030 free_string_array(argvlist, argc);
6031 return NULL;
6032 }
6033
Victor Stinner8c62be82010-05-06 00:08:46 +00006034 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006035 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006036#ifdef HAVE_WSPAWNV
6037 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006038#elif defined(HAVE_RTPSPAWN)
6039 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07006040#else
6041 spawnval = _spawnv(mode, path->narrow, argvlist);
6042#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006043 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006044 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00006045
Victor Stinner8c62be82010-05-06 00:08:46 +00006046 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00006047
Victor Stinner8c62be82010-05-06 00:08:46 +00006048 if (spawnval == -1)
6049 return posix_error();
6050 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006051 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006052}
6053
Larry Hastings2f936352014-08-05 14:04:04 +10006054/*[clinic input]
6055os.spawnve
6056
6057 mode: int
6058 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006059 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006060 Path of executable file.
6061 argv: object
6062 Tuple or list of strings.
6063 env: object
6064 Dictionary of strings mapping to strings.
6065 /
6066
6067Execute the program specified by path in a new process.
6068[clinic start generated code]*/
6069
Larry Hastings2f936352014-08-05 14:04:04 +10006070static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006071os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006072 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07006073/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006074{
Steve Dowercc16be82016-09-08 10:35:16 -07006075 EXECV_CHAR **argvlist;
6076 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006078 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006079 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006080 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006081 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006082
Victor Stinner8c62be82010-05-06 00:08:46 +00006083 /* spawnve has four arguments: (mode, path, argv, env), where
6084 argv is a list or tuple of strings and env is a dictionary
6085 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006086
Victor Stinner8c62be82010-05-06 00:08:46 +00006087 if (PyList_Check(argv)) {
6088 argc = PyList_Size(argv);
6089 getitem = PyList_GetItem;
6090 }
6091 else if (PyTuple_Check(argv)) {
6092 argc = PyTuple_Size(argv);
6093 getitem = PyTuple_GetItem;
6094 }
6095 else {
6096 PyErr_SetString(PyExc_TypeError,
6097 "spawnve() arg 2 must be a tuple or list");
6098 goto fail_0;
6099 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006100 if (argc == 0) {
6101 PyErr_SetString(PyExc_ValueError,
6102 "spawnve() arg 2 cannot be empty");
6103 goto fail_0;
6104 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006105 if (!PyMapping_Check(env)) {
6106 PyErr_SetString(PyExc_TypeError,
6107 "spawnve() arg 3 must be a mapping object");
6108 goto fail_0;
6109 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006110
Steve Dowercc16be82016-09-08 10:35:16 -07006111 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 if (argvlist == NULL) {
6113 PyErr_NoMemory();
6114 goto fail_0;
6115 }
6116 for (i = 0; i < argc; i++) {
6117 if (!fsconvert_strdup((*getitem)(argv, i),
6118 &argvlist[i]))
6119 {
6120 lastarg = i;
6121 goto fail_1;
6122 }
Steve Dowerbce26262016-11-19 19:17:26 -08006123 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006124 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006125 PyErr_SetString(
6126 PyExc_ValueError,
6127 "spawnv() arg 2 first element cannot be empty");
6128 goto fail_1;
6129 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006130 }
6131 lastarg = argc;
6132 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006133
Victor Stinner8c62be82010-05-06 00:08:46 +00006134 envlist = parse_envlist(env, &envc);
6135 if (envlist == NULL)
6136 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006137
pxinwrf2d7ac72019-05-21 18:46:37 +08006138#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006139 if (mode == _OLD_P_OVERLAY)
6140 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006141#endif
Tim Peters25059d32001-12-07 20:35:43 +00006142
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006143 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006144 goto fail_2;
6145 }
6146
Victor Stinner8c62be82010-05-06 00:08:46 +00006147 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006148 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006149#ifdef HAVE_WSPAWNV
6150 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006151#elif defined(HAVE_RTPSPAWN)
6152 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6153 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006154#else
6155 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6156#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006157 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006158 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006159
Victor Stinner8c62be82010-05-06 00:08:46 +00006160 if (spawnval == -1)
6161 (void) posix_error();
6162 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006163 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006164
Saiyang Gou95f60012020-02-04 16:15:00 -08006165 fail_2:
Victor Stinner8c62be82010-05-06 00:08:46 +00006166 while (--envc >= 0)
6167 PyMem_DEL(envlist[envc]);
6168 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006169 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006170 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006171 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006172 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006173}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006174
Guido van Rossuma1065681999-01-25 23:20:23 +00006175#endif /* HAVE_SPAWNV */
6176
6177
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006178#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006179
6180/* Helper function to validate arguments.
6181 Returns 0 on success. non-zero on failure with a TypeError raised.
6182 If obj is non-NULL it must be callable. */
6183static int
6184check_null_or_callable(PyObject *obj, const char* obj_name)
6185{
6186 if (obj && !PyCallable_Check(obj)) {
6187 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006188 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006189 return -1;
6190 }
6191 return 0;
6192}
6193
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006194/*[clinic input]
6195os.register_at_fork
6196
Gregory P. Smith163468a2017-05-29 10:03:41 -07006197 *
6198 before: object=NULL
6199 A callable to be called in the parent before the fork() syscall.
6200 after_in_child: object=NULL
6201 A callable to be called in the child after fork().
6202 after_in_parent: object=NULL
6203 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006204
Gregory P. Smith163468a2017-05-29 10:03:41 -07006205Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006206
Gregory P. Smith163468a2017-05-29 10:03:41 -07006207'before' callbacks are called in reverse order.
6208'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006209
6210[clinic start generated code]*/
6211
6212static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006213os_register_at_fork_impl(PyObject *module, PyObject *before,
6214 PyObject *after_in_child, PyObject *after_in_parent)
6215/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006216{
6217 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006218
Gregory P. Smith163468a2017-05-29 10:03:41 -07006219 if (!before && !after_in_child && !after_in_parent) {
6220 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6221 return NULL;
6222 }
6223 if (check_null_or_callable(before, "before") ||
6224 check_null_or_callable(after_in_child, "after_in_child") ||
6225 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006226 return NULL;
6227 }
Victor Stinner81a7be32020-04-14 15:14:01 +02006228 interp = _PyInterpreterState_GET();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006229
Gregory P. Smith163468a2017-05-29 10:03:41 -07006230 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006231 return NULL;
6232 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006233 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006234 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006235 }
6236 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6237 return NULL;
6238 }
6239 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006240}
6241#endif /* HAVE_FORK */
6242
6243
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006244#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006245/*[clinic input]
6246os.fork1
6247
6248Fork a child process with a single multiplexed (i.e., not bound) thread.
6249
6250Return 0 to child process and PID of child to parent process.
6251[clinic start generated code]*/
6252
Larry Hastings2f936352014-08-05 14:04:04 +10006253static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006254os_fork1_impl(PyObject *module)
6255/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006256{
Victor Stinner8c62be82010-05-06 00:08:46 +00006257 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006258
Victor Stinner81a7be32020-04-14 15:14:01 +02006259 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006260 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6261 return NULL;
6262 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006263 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006264 pid = fork1();
6265 if (pid == 0) {
6266 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006267 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006268 } else {
6269 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006270 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006271 }
6272 if (pid == -1)
6273 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006274 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006275}
Larry Hastings2f936352014-08-05 14:04:04 +10006276#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006277
6278
Guido van Rossumad0ee831995-03-01 10:34:45 +00006279#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006280/*[clinic input]
6281os.fork
6282
6283Fork a child process.
6284
6285Return 0 to child process and PID of child to parent process.
6286[clinic start generated code]*/
6287
Larry Hastings2f936352014-08-05 14:04:04 +10006288static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006289os_fork_impl(PyObject *module)
6290/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006291{
Victor Stinner8c62be82010-05-06 00:08:46 +00006292 pid_t pid;
Victor Stinner252346a2020-05-01 11:33:44 +02006293 PyInterpreterState *interp = _PyInterpreterState_GET();
6294 if (interp->config._isolated_interpreter) {
6295 PyErr_SetString(PyExc_RuntimeError,
6296 "fork not supported for isolated subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -07006297 return NULL;
6298 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006299 if (PySys_Audit("os.fork", NULL) < 0) {
6300 return NULL;
6301 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006302 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006303 pid = fork();
6304 if (pid == 0) {
6305 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006306 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006307 } else {
6308 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006309 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006310 }
6311 if (pid == -1)
6312 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006314}
Larry Hastings2f936352014-08-05 14:04:04 +10006315#endif /* HAVE_FORK */
6316
Guido van Rossum85e3b011991-06-03 12:42:10 +00006317
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006318#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006319#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006320/*[clinic input]
6321os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006322
Larry Hastings2f936352014-08-05 14:04:04 +10006323 policy: int
6324
6325Get the maximum scheduling priority for policy.
6326[clinic start generated code]*/
6327
Larry Hastings2f936352014-08-05 14:04:04 +10006328static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006329os_sched_get_priority_max_impl(PyObject *module, int policy)
6330/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006331{
6332 int max;
6333
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006334 max = sched_get_priority_max(policy);
6335 if (max < 0)
6336 return posix_error();
6337 return PyLong_FromLong(max);
6338}
6339
Larry Hastings2f936352014-08-05 14:04:04 +10006340
6341/*[clinic input]
6342os.sched_get_priority_min
6343
6344 policy: int
6345
6346Get the minimum scheduling priority for policy.
6347[clinic start generated code]*/
6348
Larry Hastings2f936352014-08-05 14:04:04 +10006349static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006350os_sched_get_priority_min_impl(PyObject *module, int policy)
6351/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006352{
6353 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006354 if (min < 0)
6355 return posix_error();
6356 return PyLong_FromLong(min);
6357}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006358#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6359
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006360
Larry Hastings2f936352014-08-05 14:04:04 +10006361#ifdef HAVE_SCHED_SETSCHEDULER
6362/*[clinic input]
6363os.sched_getscheduler
6364 pid: pid_t
6365 /
6366
Min ho Kimc4cacc82019-07-31 08:16:13 +10006367Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006368
6369Passing 0 for pid returns the scheduling policy for the calling process.
6370[clinic start generated code]*/
6371
Larry Hastings2f936352014-08-05 14:04:04 +10006372static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006373os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006374/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006375{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006376 int policy;
6377
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006378 policy = sched_getscheduler(pid);
6379 if (policy < 0)
6380 return posix_error();
6381 return PyLong_FromLong(policy);
6382}
Larry Hastings2f936352014-08-05 14:04:04 +10006383#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006384
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006385
William Orr81574b82018-10-01 22:19:56 -07006386#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006387/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006388class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006389
6390@classmethod
6391os.sched_param.__new__
6392
6393 sched_priority: object
6394 A scheduling parameter.
6395
Eddie Elizondob3966632019-11-05 07:16:14 -08006396Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006397[clinic start generated code]*/
6398
Larry Hastings2f936352014-08-05 14:04:04 +10006399static PyObject *
6400os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006401/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006402{
6403 PyObject *res;
6404
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006405 res = PyStructSequence_New(type);
6406 if (!res)
6407 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006408 Py_INCREF(sched_priority);
6409 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006410 return res;
6411}
6412
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006413PyDoc_VAR(os_sched_param__doc__);
6414
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006415static PyStructSequence_Field sched_param_fields[] = {
6416 {"sched_priority", "the scheduling priority"},
6417 {0}
6418};
6419
6420static PyStructSequence_Desc sched_param_desc = {
6421 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006422 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006423 sched_param_fields,
6424 1
6425};
6426
6427static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006428convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006429{
6430 long priority;
6431
Victor Stinner1c2fa782020-05-10 11:05:29 +02006432 if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006433 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6434 return 0;
6435 }
6436 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6437 if (priority == -1 && PyErr_Occurred())
6438 return 0;
6439 if (priority > INT_MAX || priority < INT_MIN) {
6440 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6441 return 0;
6442 }
6443 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6444 return 1;
6445}
William Orr81574b82018-10-01 22:19:56 -07006446#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006447
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006448
6449#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006450/*[clinic input]
6451os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006452
Larry Hastings2f936352014-08-05 14:04:04 +10006453 pid: pid_t
6454 policy: int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006455 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006456 /
6457
6458Set the scheduling policy for the process identified by pid.
6459
6460If pid is 0, the calling process is changed.
6461param is an instance of sched_param.
6462[clinic start generated code]*/
6463
Larry Hastings2f936352014-08-05 14:04:04 +10006464static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006465os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Victor Stinner1c2fa782020-05-10 11:05:29 +02006466 PyObject *param_obj)
6467/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006468{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006469 struct sched_param param;
6470 if (!convert_sched_param(module, param_obj, &param)) {
6471 return NULL;
6472 }
6473
Jesus Cea9c822272011-09-10 01:40:52 +02006474 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006475 ** sched_setscheduler() returns 0 in Linux, but the previous
6476 ** scheduling policy under Solaris/Illumos, and others.
6477 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006478 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02006479 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006480 return posix_error();
6481 Py_RETURN_NONE;
6482}
Larry Hastings2f936352014-08-05 14:04:04 +10006483#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006484
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006485
6486#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006487/*[clinic input]
6488os.sched_getparam
6489 pid: pid_t
6490 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006491
Larry Hastings2f936352014-08-05 14:04:04 +10006492Returns scheduling parameters for the process identified by pid.
6493
6494If pid is 0, returns parameters for the calling process.
6495Return value is an instance of sched_param.
6496[clinic start generated code]*/
6497
Larry Hastings2f936352014-08-05 14:04:04 +10006498static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006499os_sched_getparam_impl(PyObject *module, pid_t pid)
6500/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006501{
6502 struct sched_param param;
6503 PyObject *result;
6504 PyObject *priority;
6505
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006506 if (sched_getparam(pid, &param))
6507 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02006508 PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -08006509 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006510 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006511 return NULL;
6512 priority = PyLong_FromLong(param.sched_priority);
6513 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006514 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006515 return NULL;
6516 }
Larry Hastings2f936352014-08-05 14:04:04 +10006517 PyStructSequence_SET_ITEM(result, 0, priority);
6518 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006519}
6520
Larry Hastings2f936352014-08-05 14:04:04 +10006521
6522/*[clinic input]
6523os.sched_setparam
6524 pid: pid_t
Victor Stinner1c2fa782020-05-10 11:05:29 +02006525 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006526 /
6527
6528Set scheduling parameters for the process identified by pid.
6529
6530If pid is 0, sets parameters for the calling process.
6531param should be an instance of sched_param.
6532[clinic start generated code]*/
6533
Larry Hastings2f936352014-08-05 14:04:04 +10006534static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02006535os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
6536/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006537{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006538 struct sched_param param;
6539 if (!convert_sched_param(module, param_obj, &param)) {
6540 return NULL;
6541 }
6542
6543 if (sched_setparam(pid, &param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006544 return posix_error();
6545 Py_RETURN_NONE;
6546}
Larry Hastings2f936352014-08-05 14:04:04 +10006547#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006548
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006549
6550#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006551/*[clinic input]
6552os.sched_rr_get_interval -> double
6553 pid: pid_t
6554 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006555
Larry Hastings2f936352014-08-05 14:04:04 +10006556Return the round-robin quantum for the process identified by pid, in seconds.
6557
6558Value returned is a float.
6559[clinic start generated code]*/
6560
Larry Hastings2f936352014-08-05 14:04:04 +10006561static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006562os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6563/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006564{
6565 struct timespec interval;
6566 if (sched_rr_get_interval(pid, &interval)) {
6567 posix_error();
6568 return -1.0;
6569 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006570#ifdef _Py_MEMORY_SANITIZER
6571 __msan_unpoison(&interval, sizeof(interval));
6572#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006573 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6574}
6575#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006576
Larry Hastings2f936352014-08-05 14:04:04 +10006577
6578/*[clinic input]
6579os.sched_yield
6580
6581Voluntarily relinquish the CPU.
6582[clinic start generated code]*/
6583
Larry Hastings2f936352014-08-05 14:04:04 +10006584static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006585os_sched_yield_impl(PyObject *module)
6586/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006587{
6588 if (sched_yield())
6589 return posix_error();
6590 Py_RETURN_NONE;
6591}
6592
Benjamin Peterson2740af82011-08-02 17:41:34 -05006593#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006594/* The minimum number of CPUs allocated in a cpu_set_t */
6595static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006596
Larry Hastings2f936352014-08-05 14:04:04 +10006597/*[clinic input]
6598os.sched_setaffinity
6599 pid: pid_t
6600 mask : object
6601 /
6602
6603Set the CPU affinity of the process identified by pid to mask.
6604
6605mask should be an iterable of integers identifying CPUs.
6606[clinic start generated code]*/
6607
Larry Hastings2f936352014-08-05 14:04:04 +10006608static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006609os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6610/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006611{
Antoine Pitrou84869872012-08-04 16:16:35 +02006612 int ncpus;
6613 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006614 cpu_set_t *cpu_set = NULL;
6615 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006616
Larry Hastings2f936352014-08-05 14:04:04 +10006617 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006618 if (iterator == NULL)
6619 return NULL;
6620
6621 ncpus = NCPUS_START;
6622 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006623 cpu_set = CPU_ALLOC(ncpus);
6624 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006625 PyErr_NoMemory();
6626 goto error;
6627 }
Larry Hastings2f936352014-08-05 14:04:04 +10006628 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006629
6630 while ((item = PyIter_Next(iterator))) {
6631 long cpu;
6632 if (!PyLong_Check(item)) {
6633 PyErr_Format(PyExc_TypeError,
6634 "expected an iterator of ints, "
6635 "but iterator yielded %R",
6636 Py_TYPE(item));
6637 Py_DECREF(item);
6638 goto error;
6639 }
6640 cpu = PyLong_AsLong(item);
6641 Py_DECREF(item);
6642 if (cpu < 0) {
6643 if (!PyErr_Occurred())
6644 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6645 goto error;
6646 }
6647 if (cpu > INT_MAX - 1) {
6648 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6649 goto error;
6650 }
6651 if (cpu >= ncpus) {
6652 /* Grow CPU mask to fit the CPU number */
6653 int newncpus = ncpus;
6654 cpu_set_t *newmask;
6655 size_t newsetsize;
6656 while (newncpus <= cpu) {
6657 if (newncpus > INT_MAX / 2)
6658 newncpus = cpu + 1;
6659 else
6660 newncpus = newncpus * 2;
6661 }
6662 newmask = CPU_ALLOC(newncpus);
6663 if (newmask == NULL) {
6664 PyErr_NoMemory();
6665 goto error;
6666 }
6667 newsetsize = CPU_ALLOC_SIZE(newncpus);
6668 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006669 memcpy(newmask, cpu_set, setsize);
6670 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006671 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006672 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006673 ncpus = newncpus;
6674 }
Larry Hastings2f936352014-08-05 14:04:04 +10006675 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006676 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07006677 if (PyErr_Occurred()) {
6678 goto error;
6679 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006680 Py_CLEAR(iterator);
6681
Larry Hastings2f936352014-08-05 14:04:04 +10006682 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006683 posix_error();
6684 goto error;
6685 }
Larry Hastings2f936352014-08-05 14:04:04 +10006686 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006687 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006688
6689error:
Larry Hastings2f936352014-08-05 14:04:04 +10006690 if (cpu_set)
6691 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006692 Py_XDECREF(iterator);
6693 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006694}
6695
Larry Hastings2f936352014-08-05 14:04:04 +10006696
6697/*[clinic input]
6698os.sched_getaffinity
6699 pid: pid_t
6700 /
6701
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006702Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006703
6704The affinity is returned as a set of CPU identifiers.
6705[clinic start generated code]*/
6706
Larry Hastings2f936352014-08-05 14:04:04 +10006707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006708os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006709/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006710{
Antoine Pitrou84869872012-08-04 16:16:35 +02006711 int cpu, ncpus, count;
6712 size_t setsize;
6713 cpu_set_t *mask = NULL;
6714 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006715
Antoine Pitrou84869872012-08-04 16:16:35 +02006716 ncpus = NCPUS_START;
6717 while (1) {
6718 setsize = CPU_ALLOC_SIZE(ncpus);
6719 mask = CPU_ALLOC(ncpus);
6720 if (mask == NULL)
6721 return PyErr_NoMemory();
6722 if (sched_getaffinity(pid, setsize, mask) == 0)
6723 break;
6724 CPU_FREE(mask);
6725 if (errno != EINVAL)
6726 return posix_error();
6727 if (ncpus > INT_MAX / 2) {
6728 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6729 "a large enough CPU set");
6730 return NULL;
6731 }
6732 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006733 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006734
6735 res = PySet_New(NULL);
6736 if (res == NULL)
6737 goto error;
6738 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6739 if (CPU_ISSET_S(cpu, setsize, mask)) {
6740 PyObject *cpu_num = PyLong_FromLong(cpu);
6741 --count;
6742 if (cpu_num == NULL)
6743 goto error;
6744 if (PySet_Add(res, cpu_num)) {
6745 Py_DECREF(cpu_num);
6746 goto error;
6747 }
6748 Py_DECREF(cpu_num);
6749 }
6750 }
6751 CPU_FREE(mask);
6752 return res;
6753
6754error:
6755 if (mask)
6756 CPU_FREE(mask);
6757 Py_XDECREF(res);
6758 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006759}
6760
Benjamin Peterson2740af82011-08-02 17:41:34 -05006761#endif /* HAVE_SCHED_SETAFFINITY */
6762
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006763#endif /* HAVE_SCHED_H */
6764
Larry Hastings2f936352014-08-05 14:04:04 +10006765
Neal Norwitzb59798b2003-03-21 01:43:31 +00006766/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006767/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6768#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006769#define DEV_PTY_FILE "/dev/ptc"
6770#define HAVE_DEV_PTMX
6771#else
6772#define DEV_PTY_FILE "/dev/ptmx"
6773#endif
6774
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006775#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006776#ifdef HAVE_PTY_H
6777#include <pty.h>
6778#else
6779#ifdef HAVE_LIBUTIL_H
6780#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006781#else
6782#ifdef HAVE_UTIL_H
6783#include <util.h>
6784#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006785#endif /* HAVE_LIBUTIL_H */
6786#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006787#ifdef HAVE_STROPTS_H
6788#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006789#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006790#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006791
Larry Hastings2f936352014-08-05 14:04:04 +10006792
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006793#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006794/*[clinic input]
6795os.openpty
6796
6797Open a pseudo-terminal.
6798
6799Return a tuple of (master_fd, slave_fd) containing open file descriptors
6800for both the master and slave ends.
6801[clinic start generated code]*/
6802
Larry Hastings2f936352014-08-05 14:04:04 +10006803static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006804os_openpty_impl(PyObject *module)
6805/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006806{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006807 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006808#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006810#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006811#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006813#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006815#endif
6816#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006817
Thomas Wouters70c21a12000-07-14 14:28:33 +00006818#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006820 goto posix_error;
6821
6822 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6823 goto error;
6824 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6825 goto error;
6826
Neal Norwitzb59798b2003-03-21 01:43:31 +00006827#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006828 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6829 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006830 goto posix_error;
6831 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6832 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006833
Victor Stinnerdaf45552013-08-28 00:53:59 +02006834 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006836 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006837
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006838#else
Victor Stinner000de532013-11-25 23:19:58 +01006839 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006841 goto posix_error;
6842
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006844
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 /* change permission of slave */
6846 if (grantpt(master_fd) < 0) {
6847 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006848 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006849 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006850
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 /* unlock slave */
6852 if (unlockpt(master_fd) < 0) {
6853 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006854 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006855 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006856
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006858
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 slave_name = ptsname(master_fd); /* get name of slave */
6860 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006861 goto posix_error;
6862
6863 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006864 if (slave_fd == -1)
6865 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006866
6867 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6868 goto posix_error;
6869
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006870#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6872 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006873#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006875#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006876#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006877#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006878
Victor Stinner8c62be82010-05-06 00:08:46 +00006879 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006880
Victor Stinnerdaf45552013-08-28 00:53:59 +02006881posix_error:
6882 posix_error();
6883error:
6884 if (master_fd != -1)
6885 close(master_fd);
6886 if (slave_fd != -1)
6887 close(slave_fd);
6888 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006889}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006890#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006891
Larry Hastings2f936352014-08-05 14:04:04 +10006892
Fred Drake8cef4cf2000-06-28 16:40:38 +00006893#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006894/*[clinic input]
6895os.forkpty
6896
6897Fork a new process with a new pseudo-terminal as controlling tty.
6898
6899Returns a tuple of (pid, master_fd).
6900Like fork(), return pid of 0 to the child process,
6901and pid of child to the parent process.
6902To both, return fd of newly opened pseudo-terminal.
6903[clinic start generated code]*/
6904
Larry Hastings2f936352014-08-05 14:04:04 +10006905static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006906os_forkpty_impl(PyObject *module)
6907/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006908{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006909 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006911
Victor Stinner81a7be32020-04-14 15:14:01 +02006912 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006913 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6914 return NULL;
6915 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006916 if (PySys_Audit("os.forkpty", NULL) < 0) {
6917 return NULL;
6918 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006919 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006920 pid = forkpty(&master_fd, NULL, NULL, NULL);
6921 if (pid == 0) {
6922 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006923 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006924 } else {
6925 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006926 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006927 }
6928 if (pid == -1)
6929 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006930 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006931}
Larry Hastings2f936352014-08-05 14:04:04 +10006932#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006933
Ross Lagerwall7807c352011-03-17 20:20:30 +02006934
Guido van Rossumad0ee831995-03-01 10:34:45 +00006935#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006936/*[clinic input]
6937os.getegid
6938
6939Return the current process's effective group id.
6940[clinic start generated code]*/
6941
Larry Hastings2f936352014-08-05 14:04:04 +10006942static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006943os_getegid_impl(PyObject *module)
6944/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006945{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006946 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006947}
Larry Hastings2f936352014-08-05 14:04:04 +10006948#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006949
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006950
Guido van Rossumad0ee831995-03-01 10:34:45 +00006951#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006952/*[clinic input]
6953os.geteuid
6954
6955Return the current process's effective user id.
6956[clinic start generated code]*/
6957
Larry Hastings2f936352014-08-05 14:04:04 +10006958static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006959os_geteuid_impl(PyObject *module)
6960/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006961{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006962 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006963}
Larry Hastings2f936352014-08-05 14:04:04 +10006964#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006966
Guido van Rossumad0ee831995-03-01 10:34:45 +00006967#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006968/*[clinic input]
6969os.getgid
6970
6971Return the current process's group id.
6972[clinic start generated code]*/
6973
Larry Hastings2f936352014-08-05 14:04:04 +10006974static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006975os_getgid_impl(PyObject *module)
6976/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006977{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006978 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006979}
Larry Hastings2f936352014-08-05 14:04:04 +10006980#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006982
Berker Peksag39404992016-09-15 20:45:16 +03006983#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006984/*[clinic input]
6985os.getpid
6986
6987Return the current process id.
6988[clinic start generated code]*/
6989
Larry Hastings2f936352014-08-05 14:04:04 +10006990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006991os_getpid_impl(PyObject *module)
6992/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006993{
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006995}
Berker Peksag39404992016-09-15 20:45:16 +03006996#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006997
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006998#ifdef NGROUPS_MAX
6999#define MAX_GROUPS NGROUPS_MAX
7000#else
7001 /* defined to be 16 on Solaris7, so this should be a small number */
7002#define MAX_GROUPS 64
7003#endif
7004
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007005#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10007006
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007007#ifdef __APPLE__
7008/*[clinic input]
7009os.getgrouplist
7010
7011 user: str
7012 username to lookup
7013 group as basegid: int
7014 base group id of the user
7015 /
7016
7017Returns a list of groups to which a user belongs.
7018[clinic start generated code]*/
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007019
7020static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007021os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
7022/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
7023#else
7024/*[clinic input]
7025os.getgrouplist
7026
7027 user: str
7028 username to lookup
7029 group as basegid: gid_t
7030 base group id of the user
7031 /
7032
7033Returns a list of groups to which a user belongs.
7034[clinic start generated code]*/
7035
7036static PyObject *
7037os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
7038/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
7039#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007040{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007041 int i, ngroups;
7042 PyObject *list;
7043#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007044 int *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007045#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007046 gid_t *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007047#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007048
7049 /*
7050 * NGROUPS_MAX is defined by POSIX.1 as the maximum
7051 * number of supplimental groups a users can belong to.
7052 * We have to increment it by one because
7053 * getgrouplist() returns both the supplemental groups
7054 * and the primary group, i.e. all of the groups the
7055 * user belongs to.
7056 */
7057 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007058
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007059 while (1) {
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007060#ifdef __APPLE__
Victor Stinner8ec73702020-03-23 20:00:57 +01007061 groups = PyMem_New(int, ngroups);
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007062#else
7063 groups = PyMem_New(gid_t, ngroups);
7064#endif
Victor Stinner8ec73702020-03-23 20:00:57 +01007065 if (groups == NULL) {
7066 return PyErr_NoMemory();
7067 }
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007068
7069 int old_ngroups = ngroups;
7070 if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
7071 /* Success */
7072 break;
7073 }
7074
7075 /* getgrouplist() fails if the group list is too small */
7076 PyMem_Free(groups);
7077
7078 if (ngroups > old_ngroups) {
7079 /* If the group list is too small, the glibc implementation of
7080 getgrouplist() sets ngroups to the total number of groups and
7081 returns -1. */
7082 }
7083 else {
7084 /* Double the group list size */
7085 if (ngroups > INT_MAX / 2) {
7086 return PyErr_NoMemory();
7087 }
7088 ngroups *= 2;
7089 }
7090
7091 /* Retry getgrouplist() with a larger group list */
Victor Stinner8ec73702020-03-23 20:00:57 +01007092 }
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007093
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007094#ifdef _Py_MEMORY_SANITIZER
7095 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7096 __msan_unpoison(&ngroups, sizeof(ngroups));
7097 __msan_unpoison(groups, ngroups*sizeof(*groups));
7098#endif
7099
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007100 list = PyList_New(ngroups);
7101 if (list == NULL) {
7102 PyMem_Del(groups);
7103 return NULL;
7104 }
7105
7106 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007107#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007108 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007109#else
7110 PyObject *o = _PyLong_FromGid(groups[i]);
7111#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007112 if (o == NULL) {
7113 Py_DECREF(list);
7114 PyMem_Del(groups);
7115 return NULL;
7116 }
7117 PyList_SET_ITEM(list, i, o);
7118 }
7119
7120 PyMem_Del(groups);
7121
7122 return list;
7123}
Larry Hastings2f936352014-08-05 14:04:04 +10007124#endif /* HAVE_GETGROUPLIST */
7125
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007126
Fred Drakec9680921999-12-13 16:37:25 +00007127#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007128/*[clinic input]
7129os.getgroups
7130
7131Return list of supplemental group IDs for the process.
7132[clinic start generated code]*/
7133
Larry Hastings2f936352014-08-05 14:04:04 +10007134static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007135os_getgroups_impl(PyObject *module)
7136/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007137{
7138 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007140
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007141 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007142 * This is a helper variable to store the intermediate result when
7143 * that happens.
7144 *
7145 * To keep the code readable the OSX behaviour is unconditional,
7146 * according to the POSIX spec this should be safe on all unix-y
7147 * systems.
7148 */
7149 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007150 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007151
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007152#ifdef __APPLE__
7153 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7154 * there are more groups than can fit in grouplist. Therefore, on OS X
7155 * always first call getgroups with length 0 to get the actual number
7156 * of groups.
7157 */
7158 n = getgroups(0, NULL);
7159 if (n < 0) {
7160 return posix_error();
7161 } else if (n <= MAX_GROUPS) {
7162 /* groups will fit in existing array */
7163 alt_grouplist = grouplist;
7164 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007165 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007166 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007167 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007168 }
7169 }
7170
7171 n = getgroups(n, alt_grouplist);
7172 if (n == -1) {
7173 if (alt_grouplist != grouplist) {
7174 PyMem_Free(alt_grouplist);
7175 }
7176 return posix_error();
7177 }
7178#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007179 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007180 if (n < 0) {
7181 if (errno == EINVAL) {
7182 n = getgroups(0, NULL);
7183 if (n == -1) {
7184 return posix_error();
7185 }
7186 if (n == 0) {
7187 /* Avoid malloc(0) */
7188 alt_grouplist = grouplist;
7189 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007190 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007191 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007192 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007193 }
7194 n = getgroups(n, alt_grouplist);
7195 if (n == -1) {
7196 PyMem_Free(alt_grouplist);
7197 return posix_error();
7198 }
7199 }
7200 } else {
7201 return posix_error();
7202 }
7203 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007204#endif
7205
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007206 result = PyList_New(n);
7207 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007208 int i;
7209 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007210 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007211 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007212 Py_DECREF(result);
7213 result = NULL;
7214 break;
Fred Drakec9680921999-12-13 16:37:25 +00007215 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007216 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007217 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007218 }
7219
7220 if (alt_grouplist != grouplist) {
7221 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007222 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007223
Fred Drakec9680921999-12-13 16:37:25 +00007224 return result;
7225}
Larry Hastings2f936352014-08-05 14:04:04 +10007226#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007227
Antoine Pitroub7572f02009-12-02 20:46:48 +00007228#ifdef HAVE_INITGROUPS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007229#ifdef __APPLE__
7230/*[clinic input]
7231os.initgroups
Antoine Pitroub7572f02009-12-02 20:46:48 +00007232
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007233 username as oname: FSConverter
7234 gid: int
7235 /
7236
7237Initialize the group access list.
7238
7239Call the system initgroups() to initialize the group access list with all of
7240the groups of which the specified username is a member, plus the specified
7241group id.
7242[clinic start generated code]*/
7243
Antoine Pitroub7572f02009-12-02 20:46:48 +00007244static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007245os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7246/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7247#else
7248/*[clinic input]
7249os.initgroups
7250
7251 username as oname: FSConverter
7252 gid: gid_t
7253 /
7254
7255Initialize the group access list.
7256
7257Call the system initgroups() to initialize the group access list with all of
7258the groups of which the specified username is a member, plus the specified
7259group id.
7260[clinic start generated code]*/
7261
7262static PyObject *
7263os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7264/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7265#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007266{
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007267 const char *username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007268
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007269 if (initgroups(username, gid) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007270 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007271
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007272 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007273}
Larry Hastings2f936352014-08-05 14:04:04 +10007274#endif /* HAVE_INITGROUPS */
7275
Antoine Pitroub7572f02009-12-02 20:46:48 +00007276
Martin v. Löwis606edc12002-06-13 21:09:11 +00007277#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007278/*[clinic input]
7279os.getpgid
7280
7281 pid: pid_t
7282
7283Call the system call getpgid(), and return the result.
7284[clinic start generated code]*/
7285
Larry Hastings2f936352014-08-05 14:04:04 +10007286static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007287os_getpgid_impl(PyObject *module, pid_t pid)
7288/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007289{
7290 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007291 if (pgid < 0)
7292 return posix_error();
7293 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007294}
7295#endif /* HAVE_GETPGID */
7296
7297
Guido van Rossumb6775db1994-08-01 11:34:53 +00007298#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007299/*[clinic input]
7300os.getpgrp
7301
7302Return the current process group id.
7303[clinic start generated code]*/
7304
Larry Hastings2f936352014-08-05 14:04:04 +10007305static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007306os_getpgrp_impl(PyObject *module)
7307/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007308{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007309#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007310 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007311#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007312 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007313#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007314}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007315#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007316
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007317
Guido van Rossumb6775db1994-08-01 11:34:53 +00007318#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007319/*[clinic input]
7320os.setpgrp
7321
7322Make the current process the leader of its process group.
7323[clinic start generated code]*/
7324
Larry Hastings2f936352014-08-05 14:04:04 +10007325static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007326os_setpgrp_impl(PyObject *module)
7327/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007328{
Guido van Rossum64933891994-10-20 21:56:42 +00007329#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007330 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007331#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007332 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007333#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007334 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007335 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007336}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007337#endif /* HAVE_SETPGRP */
7338
Guido van Rossumad0ee831995-03-01 10:34:45 +00007339#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007340
7341#ifdef MS_WINDOWS
7342#include <tlhelp32.h>
7343
7344static PyObject*
7345win32_getppid()
7346{
7347 HANDLE snapshot;
7348 pid_t mypid;
7349 PyObject* result = NULL;
7350 BOOL have_record;
7351 PROCESSENTRY32 pe;
7352
7353 mypid = getpid(); /* This function never fails */
7354
7355 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7356 if (snapshot == INVALID_HANDLE_VALUE)
7357 return PyErr_SetFromWindowsErr(GetLastError());
7358
7359 pe.dwSize = sizeof(pe);
7360 have_record = Process32First(snapshot, &pe);
7361 while (have_record) {
7362 if (mypid == (pid_t)pe.th32ProcessID) {
7363 /* We could cache the ulong value in a static variable. */
7364 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7365 break;
7366 }
7367
7368 have_record = Process32Next(snapshot, &pe);
7369 }
7370
7371 /* If our loop exits and our pid was not found (result will be NULL)
7372 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7373 * error anyway, so let's raise it. */
7374 if (!result)
7375 result = PyErr_SetFromWindowsErr(GetLastError());
7376
7377 CloseHandle(snapshot);
7378
7379 return result;
7380}
7381#endif /*MS_WINDOWS*/
7382
Larry Hastings2f936352014-08-05 14:04:04 +10007383
7384/*[clinic input]
7385os.getppid
7386
7387Return the parent's process id.
7388
7389If the parent process has already exited, Windows machines will still
7390return its id; others systems will return the id of the 'init' process (1).
7391[clinic start generated code]*/
7392
Larry Hastings2f936352014-08-05 14:04:04 +10007393static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007394os_getppid_impl(PyObject *module)
7395/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007396{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007397#ifdef MS_WINDOWS
7398 return win32_getppid();
7399#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007400 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007401#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007402}
7403#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007404
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007405
Fred Drake12c6e2d1999-12-14 21:25:03 +00007406#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007407/*[clinic input]
7408os.getlogin
7409
7410Return the actual login name.
7411[clinic start generated code]*/
7412
Larry Hastings2f936352014-08-05 14:04:04 +10007413static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007414os_getlogin_impl(PyObject *module)
7415/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007416{
Victor Stinner8c62be82010-05-06 00:08:46 +00007417 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007418#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007419 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007420 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007421
7422 if (GetUserNameW(user_name, &num_chars)) {
7423 /* num_chars is the number of unicode chars plus null terminator */
7424 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007425 }
7426 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007427 result = PyErr_SetFromWindowsErr(GetLastError());
7428#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007429 char *name;
7430 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007431
Victor Stinner8c62be82010-05-06 00:08:46 +00007432 errno = 0;
7433 name = getlogin();
7434 if (name == NULL) {
7435 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007436 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007437 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007438 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007439 }
7440 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007441 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007442 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007443#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007444 return result;
7445}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007446#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007447
Larry Hastings2f936352014-08-05 14:04:04 +10007448
Guido van Rossumad0ee831995-03-01 10:34:45 +00007449#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007450/*[clinic input]
7451os.getuid
7452
7453Return the current process's user id.
7454[clinic start generated code]*/
7455
Larry Hastings2f936352014-08-05 14:04:04 +10007456static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007457os_getuid_impl(PyObject *module)
7458/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007459{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007460 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007461}
Larry Hastings2f936352014-08-05 14:04:04 +10007462#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007463
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007464
Brian Curtineb24d742010-04-12 17:16:38 +00007465#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007466#define HAVE_KILL
7467#endif /* MS_WINDOWS */
7468
7469#ifdef HAVE_KILL
7470/*[clinic input]
7471os.kill
7472
7473 pid: pid_t
7474 signal: Py_ssize_t
7475 /
7476
7477Kill a process with a signal.
7478[clinic start generated code]*/
7479
Larry Hastings2f936352014-08-05 14:04:04 +10007480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007481os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7482/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007483{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007484 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7485 return NULL;
7486 }
7487#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007488 if (kill(pid, (int)signal) == -1)
7489 return posix_error();
7490 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007491#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007492 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007493 DWORD sig = (DWORD)signal;
7494 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007495 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007496
Victor Stinner8c62be82010-05-06 00:08:46 +00007497 /* Console processes which share a common console can be sent CTRL+C or
7498 CTRL+BREAK events, provided they handle said events. */
7499 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007500 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007501 err = GetLastError();
7502 PyErr_SetFromWindowsErr(err);
7503 }
7504 else
7505 Py_RETURN_NONE;
7506 }
Brian Curtineb24d742010-04-12 17:16:38 +00007507
Victor Stinner8c62be82010-05-06 00:08:46 +00007508 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7509 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007510 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007511 if (handle == NULL) {
7512 err = GetLastError();
7513 return PyErr_SetFromWindowsErr(err);
7514 }
Brian Curtineb24d742010-04-12 17:16:38 +00007515
Victor Stinner8c62be82010-05-06 00:08:46 +00007516 if (TerminateProcess(handle, sig) == 0) {
7517 err = GetLastError();
7518 result = PyErr_SetFromWindowsErr(err);
7519 } else {
7520 Py_INCREF(Py_None);
7521 result = Py_None;
7522 }
Brian Curtineb24d742010-04-12 17:16:38 +00007523
Victor Stinner8c62be82010-05-06 00:08:46 +00007524 CloseHandle(handle);
7525 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007526#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007527}
Larry Hastings2f936352014-08-05 14:04:04 +10007528#endif /* HAVE_KILL */
7529
7530
7531#ifdef HAVE_KILLPG
7532/*[clinic input]
7533os.killpg
7534
7535 pgid: pid_t
7536 signal: int
7537 /
7538
7539Kill a process group with a signal.
7540[clinic start generated code]*/
7541
Larry Hastings2f936352014-08-05 14:04:04 +10007542static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007543os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7544/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007545{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007546 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7547 return NULL;
7548 }
Larry Hastings2f936352014-08-05 14:04:04 +10007549 /* XXX some man pages make the `pgid` parameter an int, others
7550 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7551 take the same type. Moreover, pid_t is always at least as wide as
7552 int (else compilation of this module fails), which is safe. */
7553 if (killpg(pgid, signal) == -1)
7554 return posix_error();
7555 Py_RETURN_NONE;
7556}
7557#endif /* HAVE_KILLPG */
7558
Brian Curtineb24d742010-04-12 17:16:38 +00007559
Guido van Rossumc0125471996-06-28 18:55:32 +00007560#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007561#ifdef HAVE_SYS_LOCK_H
7562#include <sys/lock.h>
7563#endif
7564
Larry Hastings2f936352014-08-05 14:04:04 +10007565/*[clinic input]
7566os.plock
7567 op: int
7568 /
7569
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007570Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007571[clinic start generated code]*/
7572
Larry Hastings2f936352014-08-05 14:04:04 +10007573static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007574os_plock_impl(PyObject *module, int op)
7575/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007576{
Victor Stinner8c62be82010-05-06 00:08:46 +00007577 if (plock(op) == -1)
7578 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007579 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007580}
Larry Hastings2f936352014-08-05 14:04:04 +10007581#endif /* HAVE_PLOCK */
7582
Guido van Rossumc0125471996-06-28 18:55:32 +00007583
Guido van Rossumb6775db1994-08-01 11:34:53 +00007584#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007585/*[clinic input]
7586os.setuid
7587
7588 uid: uid_t
7589 /
7590
7591Set the current process's user id.
7592[clinic start generated code]*/
7593
Larry Hastings2f936352014-08-05 14:04:04 +10007594static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007595os_setuid_impl(PyObject *module, uid_t uid)
7596/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007597{
Victor Stinner8c62be82010-05-06 00:08:46 +00007598 if (setuid(uid) < 0)
7599 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007600 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007601}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007602#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007603
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007604
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007605#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007606/*[clinic input]
7607os.seteuid
7608
7609 euid: uid_t
7610 /
7611
7612Set the current process's effective user id.
7613[clinic start generated code]*/
7614
Larry Hastings2f936352014-08-05 14:04:04 +10007615static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007616os_seteuid_impl(PyObject *module, uid_t euid)
7617/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007618{
7619 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007620 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007621 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007622}
7623#endif /* HAVE_SETEUID */
7624
Larry Hastings2f936352014-08-05 14:04:04 +10007625
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007626#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007627/*[clinic input]
7628os.setegid
7629
7630 egid: gid_t
7631 /
7632
7633Set the current process's effective group id.
7634[clinic start generated code]*/
7635
Larry Hastings2f936352014-08-05 14:04:04 +10007636static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007637os_setegid_impl(PyObject *module, gid_t egid)
7638/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007639{
7640 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007641 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007642 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007643}
7644#endif /* HAVE_SETEGID */
7645
Larry Hastings2f936352014-08-05 14:04:04 +10007646
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007647#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007648/*[clinic input]
7649os.setreuid
7650
7651 ruid: uid_t
7652 euid: uid_t
7653 /
7654
7655Set the current process's real and effective user ids.
7656[clinic start generated code]*/
7657
Larry Hastings2f936352014-08-05 14:04:04 +10007658static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007659os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7660/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007661{
Victor Stinner8c62be82010-05-06 00:08:46 +00007662 if (setreuid(ruid, euid) < 0) {
7663 return posix_error();
7664 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007665 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007666 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007667}
7668#endif /* HAVE_SETREUID */
7669
Larry Hastings2f936352014-08-05 14:04:04 +10007670
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007671#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007672/*[clinic input]
7673os.setregid
7674
7675 rgid: gid_t
7676 egid: gid_t
7677 /
7678
7679Set the current process's real and effective group ids.
7680[clinic start generated code]*/
7681
Larry Hastings2f936352014-08-05 14:04:04 +10007682static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007683os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7684/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007685{
7686 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007687 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007688 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007689}
7690#endif /* HAVE_SETREGID */
7691
Larry Hastings2f936352014-08-05 14:04:04 +10007692
Guido van Rossumb6775db1994-08-01 11:34:53 +00007693#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007694/*[clinic input]
7695os.setgid
7696 gid: gid_t
7697 /
7698
7699Set the current process's group id.
7700[clinic start generated code]*/
7701
Larry Hastings2f936352014-08-05 14:04:04 +10007702static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007703os_setgid_impl(PyObject *module, gid_t gid)
7704/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007705{
Victor Stinner8c62be82010-05-06 00:08:46 +00007706 if (setgid(gid) < 0)
7707 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007708 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007709}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007710#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007711
Larry Hastings2f936352014-08-05 14:04:04 +10007712
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007713#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007714/*[clinic input]
7715os.setgroups
7716
7717 groups: object
7718 /
7719
7720Set the groups of the current process to list.
7721[clinic start generated code]*/
7722
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007723static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007724os_setgroups(PyObject *module, PyObject *groups)
7725/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007726{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007727 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007729
Victor Stinner8c62be82010-05-06 00:08:46 +00007730 if (!PySequence_Check(groups)) {
7731 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7732 return NULL;
7733 }
7734 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007735 if (len < 0) {
7736 return NULL;
7737 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007738 if (len > MAX_GROUPS) {
7739 PyErr_SetString(PyExc_ValueError, "too many groups");
7740 return NULL;
7741 }
7742 for(i = 0; i < len; i++) {
7743 PyObject *elem;
7744 elem = PySequence_GetItem(groups, i);
7745 if (!elem)
7746 return NULL;
7747 if (!PyLong_Check(elem)) {
7748 PyErr_SetString(PyExc_TypeError,
7749 "groups must be integers");
7750 Py_DECREF(elem);
7751 return NULL;
7752 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007753 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 Py_DECREF(elem);
7755 return NULL;
7756 }
7757 }
7758 Py_DECREF(elem);
7759 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007760
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 if (setgroups(len, grouplist) < 0)
7762 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007763 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007764}
7765#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007766
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007767#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7768static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02007769wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007770{
Victor Stinner8c62be82010-05-06 00:08:46 +00007771 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08007772 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007773
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 if (pid == -1)
7775 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007776
Zackery Spytz682107c2019-09-09 09:48:32 -06007777 // If wait succeeded but no child was ready to report status, ru will not
7778 // have been populated.
7779 if (pid == 0) {
7780 memset(ru, 0, sizeof(*ru));
7781 }
7782
Eddie Elizondob3966632019-11-05 07:16:14 -08007783 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7784 if (m == NULL)
7785 return NULL;
Victor Stinner1c2fa782020-05-10 11:05:29 +02007786 struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08007787 Py_DECREF(m);
7788 if (struct_rusage == NULL)
7789 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007790
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7792 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08007793 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 if (!result)
7795 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007796
7797#ifndef doubletime
7798#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7799#endif
7800
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007802 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007803 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007804 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007805#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007806 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7807 SET_INT(result, 2, ru->ru_maxrss);
7808 SET_INT(result, 3, ru->ru_ixrss);
7809 SET_INT(result, 4, ru->ru_idrss);
7810 SET_INT(result, 5, ru->ru_isrss);
7811 SET_INT(result, 6, ru->ru_minflt);
7812 SET_INT(result, 7, ru->ru_majflt);
7813 SET_INT(result, 8, ru->ru_nswap);
7814 SET_INT(result, 9, ru->ru_inblock);
7815 SET_INT(result, 10, ru->ru_oublock);
7816 SET_INT(result, 11, ru->ru_msgsnd);
7817 SET_INT(result, 12, ru->ru_msgrcv);
7818 SET_INT(result, 13, ru->ru_nsignals);
7819 SET_INT(result, 14, ru->ru_nvcsw);
7820 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007821#undef SET_INT
7822
Victor Stinner8c62be82010-05-06 00:08:46 +00007823 if (PyErr_Occurred()) {
7824 Py_DECREF(result);
7825 return NULL;
7826 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007827
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007829}
7830#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7831
Larry Hastings2f936352014-08-05 14:04:04 +10007832
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007833#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007834/*[clinic input]
7835os.wait3
7836
7837 options: int
7838Wait for completion of a child process.
7839
7840Returns a tuple of information about the child process:
7841 (pid, status, rusage)
7842[clinic start generated code]*/
7843
Larry Hastings2f936352014-08-05 14:04:04 +10007844static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007845os_wait3_impl(PyObject *module, int options)
7846/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007847{
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007849 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007850 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007851 WAIT_TYPE status;
7852 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007853
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007854 do {
7855 Py_BEGIN_ALLOW_THREADS
7856 pid = wait3(&status, options, &ru);
7857 Py_END_ALLOW_THREADS
7858 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7859 if (pid < 0)
7860 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007861
Victor Stinner1c2fa782020-05-10 11:05:29 +02007862 return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007863}
7864#endif /* HAVE_WAIT3 */
7865
Larry Hastings2f936352014-08-05 14:04:04 +10007866
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007867#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007868/*[clinic input]
7869
7870os.wait4
7871
7872 pid: pid_t
7873 options: int
7874
7875Wait for completion of a specific child process.
7876
7877Returns a tuple of information about the child process:
7878 (pid, status, rusage)
7879[clinic start generated code]*/
7880
Larry Hastings2f936352014-08-05 14:04:04 +10007881static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007882os_wait4_impl(PyObject *module, pid_t pid, int options)
7883/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007884{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007885 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007886 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007887 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007888 WAIT_TYPE status;
7889 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007890
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007891 do {
7892 Py_BEGIN_ALLOW_THREADS
7893 res = wait4(pid, &status, options, &ru);
7894 Py_END_ALLOW_THREADS
7895 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7896 if (res < 0)
7897 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007898
Victor Stinner1c2fa782020-05-10 11:05:29 +02007899 return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007900}
7901#endif /* HAVE_WAIT4 */
7902
Larry Hastings2f936352014-08-05 14:04:04 +10007903
Ross Lagerwall7807c352011-03-17 20:20:30 +02007904#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007905/*[clinic input]
7906os.waitid
7907
7908 idtype: idtype_t
7909 Must be one of be P_PID, P_PGID or P_ALL.
7910 id: id_t
7911 The id to wait on.
7912 options: int
7913 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7914 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7915 /
7916
7917Returns the result of waiting for a process or processes.
7918
7919Returns either waitid_result or None if WNOHANG is specified and there are
7920no children in a waitable state.
7921[clinic start generated code]*/
7922
Larry Hastings2f936352014-08-05 14:04:04 +10007923static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007924os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7925/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007926{
7927 PyObject *result;
7928 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007929 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007930 siginfo_t si;
7931 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007932
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007933 do {
7934 Py_BEGIN_ALLOW_THREADS
7935 res = waitid(idtype, id, &si, options);
7936 Py_END_ALLOW_THREADS
7937 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7938 if (res < 0)
7939 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007940
7941 if (si.si_pid == 0)
7942 Py_RETURN_NONE;
7943
Hai Shif707d942020-03-16 21:15:01 +08007944 PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08007945 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007946 if (!result)
7947 return NULL;
7948
7949 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007950 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007951 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7952 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7953 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7954 if (PyErr_Occurred()) {
7955 Py_DECREF(result);
7956 return NULL;
7957 }
7958
7959 return result;
7960}
Larry Hastings2f936352014-08-05 14:04:04 +10007961#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007962
Larry Hastings2f936352014-08-05 14:04:04 +10007963
7964#if defined(HAVE_WAITPID)
7965/*[clinic input]
7966os.waitpid
7967 pid: pid_t
7968 options: int
7969 /
7970
7971Wait for completion of a given child process.
7972
7973Returns a tuple of information regarding the child process:
7974 (pid, status)
7975
7976The options argument is ignored on Windows.
7977[clinic start generated code]*/
7978
Larry Hastings2f936352014-08-05 14:04:04 +10007979static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007980os_waitpid_impl(PyObject *module, pid_t pid, int options)
7981/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007982{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007983 pid_t res;
7984 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 WAIT_TYPE status;
7986 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007987
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007988 do {
7989 Py_BEGIN_ALLOW_THREADS
7990 res = waitpid(pid, &status, options);
7991 Py_END_ALLOW_THREADS
7992 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7993 if (res < 0)
7994 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007995
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007996 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007997}
Tim Petersab034fa2002-02-01 11:27:43 +00007998#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007999/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10008000/*[clinic input]
8001os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07008002 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10008003 options: int
8004 /
8005
8006Wait for completion of a given process.
8007
8008Returns a tuple of information regarding the process:
8009 (pid, status << 8)
8010
8011The options argument is ignored on Windows.
8012[clinic start generated code]*/
8013
Larry Hastings2f936352014-08-05 14:04:04 +10008014static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07008015os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07008016/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008017{
8018 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07008019 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008020 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008021
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008022 do {
8023 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08008024 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008025 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08008026 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008027 Py_END_ALLOW_THREADS
8028 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008029 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008030 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008031
Victor Stinner9bee32b2020-04-22 16:30:35 +02008032 unsigned long long ustatus = (unsigned int)status;
8033
Victor Stinner8c62be82010-05-06 00:08:46 +00008034 /* shift the status left a byte so this is more like the POSIX waitpid */
Victor Stinner9bee32b2020-04-22 16:30:35 +02008035 return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00008036}
Larry Hastings2f936352014-08-05 14:04:04 +10008037#endif
8038
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008039
Guido van Rossumad0ee831995-03-01 10:34:45 +00008040#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10008041/*[clinic input]
8042os.wait
8043
8044Wait for completion of a child process.
8045
8046Returns a tuple of information about the child process:
8047 (pid, status)
8048[clinic start generated code]*/
8049
Larry Hastings2f936352014-08-05 14:04:04 +10008050static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008051os_wait_impl(PyObject *module)
8052/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00008053{
Victor Stinner8c62be82010-05-06 00:08:46 +00008054 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008055 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008056 WAIT_TYPE status;
8057 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00008058
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008059 do {
8060 Py_BEGIN_ALLOW_THREADS
8061 pid = wait(&status);
8062 Py_END_ALLOW_THREADS
8063 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8064 if (pid < 0)
8065 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008066
Victor Stinner8c62be82010-05-06 00:08:46 +00008067 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00008068}
Larry Hastings2f936352014-08-05 14:04:04 +10008069#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008070
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08008071#if defined(__linux__) && defined(__NR_pidfd_open)
8072/*[clinic input]
8073os.pidfd_open
8074 pid: pid_t
8075 flags: unsigned_int = 0
8076
8077Return a file descriptor referring to the process *pid*.
8078
8079The descriptor can be used to perform process management without races and
8080signals.
8081[clinic start generated code]*/
8082
8083static PyObject *
8084os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8085/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8086{
8087 int fd = syscall(__NR_pidfd_open, pid, flags);
8088 if (fd < 0) {
8089 return posix_error();
8090 }
8091 return PyLong_FromLong(fd);
8092}
8093#endif
8094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008095
Larry Hastings9cf065c2012-06-22 16:30:09 -07008096#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008097/*[clinic input]
8098os.readlink
8099
8100 path: path_t
8101 *
8102 dir_fd: dir_fd(requires='readlinkat') = None
8103
8104Return a string representing the path to which the symbolic link points.
8105
8106If dir_fd is not None, it should be a file descriptor open to a directory,
8107and path should be relative; path will then be relative to that directory.
8108
8109dir_fd may not be implemented on your platform. If it is unavailable,
8110using it will raise a NotImplementedError.
8111[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008112
Barry Warsaw53699e91996-12-10 23:23:01 +00008113static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008114os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8115/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008116{
Berker Peksage0b5b202018-08-15 13:03:41 +03008117#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008118 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008119 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008120
8121 Py_BEGIN_ALLOW_THREADS
8122#ifdef HAVE_READLINKAT
8123 if (dir_fd != DEFAULT_DIR_FD)
8124 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8125 else
8126#endif
8127 length = readlink(path->narrow, buffer, MAXPATHLEN);
8128 Py_END_ALLOW_THREADS
8129
8130 if (length < 0) {
8131 return path_error(path);
8132 }
8133 buffer[length] = '\0';
8134
8135 if (PyUnicode_Check(path->object))
8136 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8137 else
8138 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008139#elif defined(MS_WINDOWS)
8140 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008141 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008142 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008143 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8144 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008145 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008146
Larry Hastings2f936352014-08-05 14:04:04 +10008147 /* First get a handle to the reparse point */
8148 Py_BEGIN_ALLOW_THREADS
8149 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008150 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008151 0,
8152 0,
8153 0,
8154 OPEN_EXISTING,
8155 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8156 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008157 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8158 /* New call DeviceIoControl to read the reparse point */
8159 io_result = DeviceIoControl(
8160 reparse_point_handle,
8161 FSCTL_GET_REPARSE_POINT,
8162 0, 0, /* in buffer */
8163 target_buffer, sizeof(target_buffer),
8164 &n_bytes_returned,
8165 0 /* we're not using OVERLAPPED_IO */
8166 );
8167 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008168 }
Larry Hastings2f936352014-08-05 14:04:04 +10008169 Py_END_ALLOW_THREADS
8170
Berker Peksage0b5b202018-08-15 13:03:41 +03008171 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008172 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008173 }
Larry Hastings2f936352014-08-05 14:04:04 +10008174
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008175 wchar_t *name = NULL;
8176 Py_ssize_t nameLen = 0;
8177 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008178 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008179 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8180 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8181 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008182 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008183 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8184 {
8185 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8186 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8187 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8188 }
8189 else
8190 {
8191 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8192 }
8193 if (name) {
8194 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8195 /* Our buffer is mutable, so this is okay */
8196 name[1] = L'\\';
8197 }
8198 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008199 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008200 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8201 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008202 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008203 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008204#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008205}
Berker Peksage0b5b202018-08-15 13:03:41 +03008206#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008207
Larry Hastings9cf065c2012-06-22 16:30:09 -07008208#if defined(MS_WINDOWS)
8209
Steve Dower6921e732018-03-05 14:26:08 -08008210/* Remove the last portion of the path - return 0 on success */
8211static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008212_dirnameW(WCHAR *path)
8213{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008214 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008215 size_t length = wcsnlen_s(path, MAX_PATH);
8216 if (length == MAX_PATH) {
8217 return -1;
8218 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008219
8220 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008221 for(ptr = path + length; ptr != path; ptr--) {
8222 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008223 break;
Steve Dower6921e732018-03-05 14:26:08 -08008224 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008225 }
8226 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008227 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008228}
8229
Minmin Gong7f21c9a2020-05-18 09:17:19 -07008230#endif
8231
8232#ifdef HAVE_SYMLINK
8233
8234#if defined(MS_WINDOWS)
8235
Victor Stinner31b3b922013-06-05 01:49:17 +02008236/* Is this path absolute? */
8237static int
8238_is_absW(const WCHAR *path)
8239{
Steve Dower6921e732018-03-05 14:26:08 -08008240 return path[0] == L'\\' || path[0] == L'/' ||
8241 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008242}
8243
Steve Dower6921e732018-03-05 14:26:08 -08008244/* join root and rest with a backslash - return 0 on success */
8245static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008246_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8247{
Victor Stinner31b3b922013-06-05 01:49:17 +02008248 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008249 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008250 }
8251
Steve Dower6921e732018-03-05 14:26:08 -08008252 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8253 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008254 }
Steve Dower6921e732018-03-05 14:26:08 -08008255
8256 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8257 return -1;
8258 }
8259
8260 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008261}
8262
Victor Stinner31b3b922013-06-05 01:49:17 +02008263/* Return True if the path at src relative to dest is a directory */
8264static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008265_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008266{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008267 WIN32_FILE_ATTRIBUTE_DATA src_info;
8268 WCHAR dest_parent[MAX_PATH];
8269 WCHAR src_resolved[MAX_PATH] = L"";
8270
8271 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008272 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8273 _dirnameW(dest_parent)) {
8274 return 0;
8275 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008276 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008277 if (_joinW(src_resolved, dest_parent, src)) {
8278 return 0;
8279 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008280 return (
8281 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8282 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8283 );
8284}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008285#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008286
Larry Hastings2f936352014-08-05 14:04:04 +10008287
8288/*[clinic input]
8289os.symlink
8290 src: path_t
8291 dst: path_t
8292 target_is_directory: bool = False
8293 *
8294 dir_fd: dir_fd(requires='symlinkat')=None
8295
8296# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8297
8298Create a symbolic link pointing to src named dst.
8299
8300target_is_directory is required on Windows if the target is to be
8301 interpreted as a directory. (On Windows, symlink requires
8302 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8303 target_is_directory is ignored on non-Windows platforms.
8304
8305If dir_fd is not None, it should be a file descriptor open to a directory,
8306 and path should be relative; path will then be relative to that directory.
8307dir_fd may not be implemented on your platform.
8308 If it is unavailable, using it will raise a NotImplementedError.
8309
8310[clinic start generated code]*/
8311
Larry Hastings2f936352014-08-05 14:04:04 +10008312static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008313os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008314 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008315/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008316{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008317#ifdef MS_WINDOWS
8318 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008319 DWORD flags = 0;
8320
8321 /* Assumed true, set to false if detected to not be available. */
8322 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008323#else
8324 int result;
8325#endif
8326
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008327 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8328 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8329 return NULL;
8330 }
8331
Larry Hastings9cf065c2012-06-22 16:30:09 -07008332#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008333
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008334 if (windows_has_symlink_unprivileged_flag) {
8335 /* Allow non-admin symlinks if system allows it. */
8336 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8337 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008338
Larry Hastings9cf065c2012-06-22 16:30:09 -07008339 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008340 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008341 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8342 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8343 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8344 }
8345
8346 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008347 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008348 Py_END_ALLOW_THREADS
8349
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008350 if (windows_has_symlink_unprivileged_flag && !result &&
8351 ERROR_INVALID_PARAMETER == GetLastError()) {
8352
8353 Py_BEGIN_ALLOW_THREADS
8354 _Py_BEGIN_SUPPRESS_IPH
8355 /* This error might be caused by
8356 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8357 Try again, and update windows_has_symlink_unprivileged_flag if we
8358 are successful this time.
8359
8360 NOTE: There is a risk of a race condition here if there are other
8361 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8362 another process (or thread) changes that condition in between our
8363 calls to CreateSymbolicLink.
8364 */
8365 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8366 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8367 _Py_END_SUPPRESS_IPH
8368 Py_END_ALLOW_THREADS
8369
8370 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8371 windows_has_symlink_unprivileged_flag = FALSE;
8372 }
8373 }
8374
Larry Hastings2f936352014-08-05 14:04:04 +10008375 if (!result)
8376 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008377
8378#else
8379
Steve Dower6921e732018-03-05 14:26:08 -08008380 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8381 PyErr_SetString(PyExc_ValueError,
8382 "symlink: src and dst must be the same type");
8383 return NULL;
8384 }
8385
Larry Hastings9cf065c2012-06-22 16:30:09 -07008386 Py_BEGIN_ALLOW_THREADS
8387#if HAVE_SYMLINKAT
8388 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10008389 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008390 else
8391#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008392 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008393 Py_END_ALLOW_THREADS
8394
Larry Hastings2f936352014-08-05 14:04:04 +10008395 if (result)
8396 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008397#endif
8398
Larry Hastings2f936352014-08-05 14:04:04 +10008399 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008400}
8401#endif /* HAVE_SYMLINK */
8402
Larry Hastings9cf065c2012-06-22 16:30:09 -07008403
Brian Curtind40e6f72010-07-08 21:39:08 +00008404
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008405
Larry Hastings605a62d2012-06-24 04:33:36 -07008406static PyStructSequence_Field times_result_fields[] = {
8407 {"user", "user time"},
8408 {"system", "system time"},
8409 {"children_user", "user time of children"},
8410 {"children_system", "system time of children"},
8411 {"elapsed", "elapsed time since an arbitrary point in the past"},
8412 {NULL}
8413};
8414
8415PyDoc_STRVAR(times_result__doc__,
8416"times_result: Result from os.times().\n\n\
8417This object may be accessed either as a tuple of\n\
8418 (user, system, children_user, children_system, elapsed),\n\
8419or via the attributes user, system, children_user, children_system,\n\
8420and elapsed.\n\
8421\n\
8422See os.times for more information.");
8423
8424static PyStructSequence_Desc times_result_desc = {
8425 "times_result", /* name */
8426 times_result__doc__, /* doc */
8427 times_result_fields,
8428 5
8429};
8430
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008431#ifdef MS_WINDOWS
8432#define HAVE_TIMES /* mandatory, for the method table */
8433#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008434
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008435#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008436
8437static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008438build_times_result(PyObject *module, double user, double system,
Larry Hastings605a62d2012-06-24 04:33:36 -07008439 double children_user, double children_system,
8440 double elapsed)
8441{
Victor Stinner1c2fa782020-05-10 11:05:29 +02008442 PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008443 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008444 if (value == NULL)
8445 return NULL;
8446
8447#define SET(i, field) \
8448 { \
8449 PyObject *o = PyFloat_FromDouble(field); \
8450 if (!o) { \
8451 Py_DECREF(value); \
8452 return NULL; \
8453 } \
8454 PyStructSequence_SET_ITEM(value, i, o); \
8455 } \
8456
8457 SET(0, user);
8458 SET(1, system);
8459 SET(2, children_user);
8460 SET(3, children_system);
8461 SET(4, elapsed);
8462
8463#undef SET
8464
8465 return value;
8466}
8467
Larry Hastings605a62d2012-06-24 04:33:36 -07008468
Larry Hastings2f936352014-08-05 14:04:04 +10008469#ifndef MS_WINDOWS
8470#define NEED_TICKS_PER_SECOND
8471static long ticks_per_second = -1;
8472#endif /* MS_WINDOWS */
8473
8474/*[clinic input]
8475os.times
8476
8477Return a collection containing process timing information.
8478
8479The object returned behaves like a named tuple with these fields:
8480 (utime, stime, cutime, cstime, elapsed_time)
8481All fields are floating point numbers.
8482[clinic start generated code]*/
8483
Larry Hastings2f936352014-08-05 14:04:04 +10008484static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008485os_times_impl(PyObject *module)
8486/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008487#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008488{
Victor Stinner8c62be82010-05-06 00:08:46 +00008489 FILETIME create, exit, kernel, user;
8490 HANDLE hProc;
8491 hProc = GetCurrentProcess();
8492 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8493 /* The fields of a FILETIME structure are the hi and lo part
8494 of a 64-bit value expressed in 100 nanosecond units.
8495 1e7 is one second in such units; 1e-7 the inverse.
8496 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8497 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02008498 return build_times_result(module,
Victor Stinner8c62be82010-05-06 00:08:46 +00008499 (double)(user.dwHighDateTime*429.4967296 +
8500 user.dwLowDateTime*1e-7),
8501 (double)(kernel.dwHighDateTime*429.4967296 +
8502 kernel.dwLowDateTime*1e-7),
8503 (double)0,
8504 (double)0,
8505 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008506}
Larry Hastings2f936352014-08-05 14:04:04 +10008507#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008508{
Larry Hastings2f936352014-08-05 14:04:04 +10008509
8510
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008511 struct tms t;
8512 clock_t c;
8513 errno = 0;
8514 c = times(&t);
8515 if (c == (clock_t) -1)
8516 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02008517 return build_times_result(module,
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008518 (double)t.tms_utime / ticks_per_second,
8519 (double)t.tms_stime / ticks_per_second,
8520 (double)t.tms_cutime / ticks_per_second,
8521 (double)t.tms_cstime / ticks_per_second,
8522 (double)c / ticks_per_second);
8523}
Larry Hastings2f936352014-08-05 14:04:04 +10008524#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008525#endif /* HAVE_TIMES */
8526
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008527
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008528#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008529/*[clinic input]
8530os.getsid
8531
8532 pid: pid_t
8533 /
8534
8535Call the system call getsid(pid) and return the result.
8536[clinic start generated code]*/
8537
Larry Hastings2f936352014-08-05 14:04:04 +10008538static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008539os_getsid_impl(PyObject *module, pid_t pid)
8540/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008541{
Victor Stinner8c62be82010-05-06 00:08:46 +00008542 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008543 sid = getsid(pid);
8544 if (sid < 0)
8545 return posix_error();
8546 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008547}
8548#endif /* HAVE_GETSID */
8549
8550
Guido van Rossumb6775db1994-08-01 11:34:53 +00008551#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008552/*[clinic input]
8553os.setsid
8554
8555Call the system call setsid().
8556[clinic start generated code]*/
8557
Larry Hastings2f936352014-08-05 14:04:04 +10008558static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008559os_setsid_impl(PyObject *module)
8560/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008561{
Victor Stinner8c62be82010-05-06 00:08:46 +00008562 if (setsid() < 0)
8563 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008564 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008565}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008566#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008567
Larry Hastings2f936352014-08-05 14:04:04 +10008568
Guido van Rossumb6775db1994-08-01 11:34:53 +00008569#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008570/*[clinic input]
8571os.setpgid
8572
8573 pid: pid_t
8574 pgrp: pid_t
8575 /
8576
8577Call the system call setpgid(pid, pgrp).
8578[clinic start generated code]*/
8579
Larry Hastings2f936352014-08-05 14:04:04 +10008580static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008581os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8582/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008583{
Victor Stinner8c62be82010-05-06 00:08:46 +00008584 if (setpgid(pid, pgrp) < 0)
8585 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008586 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008587}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008588#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008589
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008590
Guido van Rossumb6775db1994-08-01 11:34:53 +00008591#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008592/*[clinic input]
8593os.tcgetpgrp
8594
8595 fd: int
8596 /
8597
8598Return the process group associated with the terminal specified by fd.
8599[clinic start generated code]*/
8600
Larry Hastings2f936352014-08-05 14:04:04 +10008601static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008602os_tcgetpgrp_impl(PyObject *module, int fd)
8603/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008604{
8605 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008606 if (pgid < 0)
8607 return posix_error();
8608 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008609}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008610#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008611
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008612
Guido van Rossumb6775db1994-08-01 11:34:53 +00008613#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008614/*[clinic input]
8615os.tcsetpgrp
8616
8617 fd: int
8618 pgid: pid_t
8619 /
8620
8621Set the process group associated with the terminal specified by fd.
8622[clinic start generated code]*/
8623
Larry Hastings2f936352014-08-05 14:04:04 +10008624static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008625os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8626/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008627{
Victor Stinner8c62be82010-05-06 00:08:46 +00008628 if (tcsetpgrp(fd, pgid) < 0)
8629 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008630 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008631}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008632#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008633
Guido van Rossum687dd131993-05-17 08:34:16 +00008634/* Functions acting on file descriptors */
8635
Victor Stinnerdaf45552013-08-28 00:53:59 +02008636#ifdef O_CLOEXEC
8637extern int _Py_open_cloexec_works;
8638#endif
8639
Larry Hastings2f936352014-08-05 14:04:04 +10008640
8641/*[clinic input]
8642os.open -> int
8643 path: path_t
8644 flags: int
8645 mode: int = 0o777
8646 *
8647 dir_fd: dir_fd(requires='openat') = None
8648
8649# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8650
8651Open a file for low level IO. Returns a file descriptor (integer).
8652
8653If dir_fd is not None, it should be a file descriptor open to a directory,
8654 and path should be relative; path will then be relative to that directory.
8655dir_fd may not be implemented on your platform.
8656 If it is unavailable, using it will raise a NotImplementedError.
8657[clinic start generated code]*/
8658
Larry Hastings2f936352014-08-05 14:04:04 +10008659static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008660os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8661/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008662{
8663 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008664 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008665
Victor Stinnerdaf45552013-08-28 00:53:59 +02008666#ifdef O_CLOEXEC
8667 int *atomic_flag_works = &_Py_open_cloexec_works;
8668#elif !defined(MS_WINDOWS)
8669 int *atomic_flag_works = NULL;
8670#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008671
Victor Stinnerdaf45552013-08-28 00:53:59 +02008672#ifdef MS_WINDOWS
8673 flags |= O_NOINHERIT;
8674#elif defined(O_CLOEXEC)
8675 flags |= O_CLOEXEC;
8676#endif
8677
Steve Dowerb82e17e2019-05-23 08:45:22 -07008678 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
8679 return -1;
8680 }
8681
Steve Dower8fc89802015-04-12 00:26:27 -04008682 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008683 do {
8684 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008685#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008686 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008687#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008688#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008689 if (dir_fd != DEFAULT_DIR_FD)
8690 fd = openat(dir_fd, path->narrow, flags, mode);
8691 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008692#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008693 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008694#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008695 Py_END_ALLOW_THREADS
8696 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008697 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008698
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008699 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008700 if (!async_err)
8701 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008702 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008703 }
8704
Victor Stinnerdaf45552013-08-28 00:53:59 +02008705#ifndef MS_WINDOWS
8706 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8707 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008708 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008709 }
8710#endif
8711
Larry Hastings2f936352014-08-05 14:04:04 +10008712 return fd;
8713}
8714
8715
8716/*[clinic input]
8717os.close
8718
8719 fd: int
8720
8721Close a file descriptor.
8722[clinic start generated code]*/
8723
Barry Warsaw53699e91996-12-10 23:23:01 +00008724static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008725os_close_impl(PyObject *module, int fd)
8726/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008727{
Larry Hastings2f936352014-08-05 14:04:04 +10008728 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008729 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8730 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8731 * for more details.
8732 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008733 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008734 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008735 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008736 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008737 Py_END_ALLOW_THREADS
8738 if (res < 0)
8739 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008740 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008741}
8742
Kyle Evansc230fde2020-10-11 13:54:11 -05008743/* Our selection logic for which function to use is as follows:
8744 * 1. If closefrom(2) is available, we'll attempt to use that next if we're
8745 * closing up to sysconf(_SC_OPEN_MAX).
8746 * 1a. Fallback to fdwalk(3) if we're not closing up to sysconf(_SC_OPEN_MAX),
8747 * as that will be more performant if the range happens to have any chunk of
8748 * non-opened fd in the middle.
8749 * 1b. If fdwalk(3) isn't available, just do a plain close(2) loop.
8750 */
8751#ifdef __FreeBSD__
8752#define USE_CLOSEFROM
8753#endif /* __FreeBSD__ */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008754
Jakub Kulíke20134f2019-09-11 17:11:57 +02008755#ifdef HAVE_FDWALK
Kyle Evansc230fde2020-10-11 13:54:11 -05008756#define USE_FDWALK
8757#endif /* HAVE_FDWALK */
8758
8759#ifdef USE_FDWALK
Jakub Kulíke20134f2019-09-11 17:11:57 +02008760static int
8761_fdwalk_close_func(void *lohi, int fd)
8762{
8763 int lo = ((int *)lohi)[0];
8764 int hi = ((int *)lohi)[1];
8765
Victor Stinner162c5672020-04-24 12:00:51 +02008766 if (fd >= hi) {
Jakub Kulíke20134f2019-09-11 17:11:57 +02008767 return 1;
Victor Stinner162c5672020-04-24 12:00:51 +02008768 }
8769 else if (fd >= lo) {
8770 /* Ignore errors */
8771 (void)close(fd);
8772 }
Jakub Kulíke20134f2019-09-11 17:11:57 +02008773 return 0;
8774}
Kyle Evansc230fde2020-10-11 13:54:11 -05008775#endif /* USE_FDWALK */
8776
8777/* Closes all file descriptors in [first, last], ignoring errors. */
8778void
8779_Py_closerange(int first, int last)
8780{
8781 first = Py_MAX(first, 0);
8782#ifdef USE_CLOSEFROM
8783 if (last >= sysconf(_SC_OPEN_MAX)) {
8784 /* Any errors encountered while closing file descriptors are ignored */
8785 closefrom(first);
8786 }
8787 else
8788#endif /* USE_CLOSEFROM */
8789#ifdef USE_FDWALK
8790 {
8791 int lohi[2];
8792 lohi[0] = first;
8793 lohi[1] = last + 1;
8794 fdwalk(_fdwalk_close_func, lohi);
8795 }
8796#else
8797 {
8798 for (int i = first; i <= last; i++) {
8799 /* Ignore errors */
8800 (void)close(i);
8801 }
8802 }
8803#endif /* USE_FDWALK */
8804}
Jakub Kulíke20134f2019-09-11 17:11:57 +02008805
Larry Hastings2f936352014-08-05 14:04:04 +10008806/*[clinic input]
8807os.closerange
8808
8809 fd_low: int
8810 fd_high: int
8811 /
8812
8813Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8814[clinic start generated code]*/
8815
Larry Hastings2f936352014-08-05 14:04:04 +10008816static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008817os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8818/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008819{
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008821 _Py_BEGIN_SUPPRESS_IPH
Kyle Evansc230fde2020-10-11 13:54:11 -05008822 _Py_closerange(fd_low, fd_high - 1);
Steve Dower8fc89802015-04-12 00:26:27 -04008823 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008824 Py_END_ALLOW_THREADS
8825 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008826}
8827
8828
Larry Hastings2f936352014-08-05 14:04:04 +10008829/*[clinic input]
8830os.dup -> int
8831
8832 fd: int
8833 /
8834
8835Return a duplicate of a file descriptor.
8836[clinic start generated code]*/
8837
Larry Hastings2f936352014-08-05 14:04:04 +10008838static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008839os_dup_impl(PyObject *module, int fd)
8840/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008841{
8842 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008843}
8844
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008845
Larry Hastings2f936352014-08-05 14:04:04 +10008846/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008847os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008848 fd: int
8849 fd2: int
8850 inheritable: bool=True
8851
8852Duplicate file descriptor.
8853[clinic start generated code]*/
8854
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008855static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008856os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008857/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008858{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008859 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008860#if defined(HAVE_DUP3) && \
8861 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8862 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008863 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008864#endif
8865
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008866 if (fd < 0 || fd2 < 0) {
8867 posix_error();
8868 return -1;
8869 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008870
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008871 /* dup2() can fail with EINTR if the target FD is already open, because it
8872 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8873 * upon close(), and therefore below.
8874 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008875#ifdef MS_WINDOWS
8876 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008877 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008878 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008879 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008880 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008881 if (res < 0) {
8882 posix_error();
8883 return -1;
8884 }
8885 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008886
8887 /* Character files like console cannot be make non-inheritable */
8888 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8889 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008890 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008891 }
8892
8893#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8894 Py_BEGIN_ALLOW_THREADS
8895 if (!inheritable)
8896 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8897 else
8898 res = dup2(fd, fd2);
8899 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008900 if (res < 0) {
8901 posix_error();
8902 return -1;
8903 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008904
8905#else
8906
8907#ifdef HAVE_DUP3
8908 if (!inheritable && dup3_works != 0) {
8909 Py_BEGIN_ALLOW_THREADS
8910 res = dup3(fd, fd2, O_CLOEXEC);
8911 Py_END_ALLOW_THREADS
8912 if (res < 0) {
8913 if (dup3_works == -1)
8914 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008915 if (dup3_works) {
8916 posix_error();
8917 return -1;
8918 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008919 }
8920 }
8921
8922 if (inheritable || dup3_works == 0)
8923 {
8924#endif
8925 Py_BEGIN_ALLOW_THREADS
8926 res = dup2(fd, fd2);
8927 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008928 if (res < 0) {
8929 posix_error();
8930 return -1;
8931 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008932
8933 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8934 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008935 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008936 }
8937#ifdef HAVE_DUP3
8938 }
8939#endif
8940
8941#endif
8942
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008943 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008944}
8945
Larry Hastings2f936352014-08-05 14:04:04 +10008946
Ross Lagerwall7807c352011-03-17 20:20:30 +02008947#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008948/*[clinic input]
8949os.lockf
8950
8951 fd: int
8952 An open file descriptor.
8953 command: int
8954 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8955 length: Py_off_t
8956 The number of bytes to lock, starting at the current position.
8957 /
8958
8959Apply, test or remove a POSIX lock on an open file descriptor.
8960
8961[clinic start generated code]*/
8962
Larry Hastings2f936352014-08-05 14:04:04 +10008963static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008964os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8965/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008966{
8967 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008968
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008969 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
8970 return NULL;
8971 }
8972
Ross Lagerwall7807c352011-03-17 20:20:30 +02008973 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008974 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008975 Py_END_ALLOW_THREADS
8976
8977 if (res < 0)
8978 return posix_error();
8979
8980 Py_RETURN_NONE;
8981}
Larry Hastings2f936352014-08-05 14:04:04 +10008982#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008984
Larry Hastings2f936352014-08-05 14:04:04 +10008985/*[clinic input]
8986os.lseek -> Py_off_t
8987
8988 fd: int
8989 position: Py_off_t
8990 how: int
8991 /
8992
8993Set the position of a file descriptor. Return the new position.
8994
8995Return the new cursor position in number of bytes
8996relative to the beginning of the file.
8997[clinic start generated code]*/
8998
Larry Hastings2f936352014-08-05 14:04:04 +10008999static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009000os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
9001/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009002{
9003 Py_off_t result;
9004
Guido van Rossum687dd131993-05-17 08:34:16 +00009005#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00009006 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
9007 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10009008 case 0: how = SEEK_SET; break;
9009 case 1: how = SEEK_CUR; break;
9010 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00009011 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009012#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009013
Victor Stinner8c62be82010-05-06 00:08:46 +00009014 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009015 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02009016#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009017 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009018#else
Larry Hastings2f936352014-08-05 14:04:04 +10009019 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009020#endif
Steve Dower8fc89802015-04-12 00:26:27 -04009021 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009022 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009023 if (result < 0)
9024 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00009025
Larry Hastings2f936352014-08-05 14:04:04 +10009026 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00009027}
9028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009029
Larry Hastings2f936352014-08-05 14:04:04 +10009030/*[clinic input]
9031os.read
9032 fd: int
9033 length: Py_ssize_t
9034 /
9035
9036Read from a file descriptor. Returns a bytes object.
9037[clinic start generated code]*/
9038
Larry Hastings2f936352014-08-05 14:04:04 +10009039static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009040os_read_impl(PyObject *module, int fd, Py_ssize_t length)
9041/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009042{
Victor Stinner8c62be82010-05-06 00:08:46 +00009043 Py_ssize_t n;
9044 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10009045
9046 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009047 errno = EINVAL;
9048 return posix_error();
9049 }
Larry Hastings2f936352014-08-05 14:04:04 +10009050
Victor Stinner9a0d7a72018-11-22 15:03:40 +01009051 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10009052
9053 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00009054 if (buffer == NULL)
9055 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009056
Victor Stinner66aab0c2015-03-19 22:53:20 +01009057 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
9058 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009059 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01009060 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009061 }
Larry Hastings2f936352014-08-05 14:04:04 +10009062
9063 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00009064 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10009065
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00009067}
9068
Ross Lagerwall7807c352011-03-17 20:20:30 +02009069#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009070 || defined(__APPLE__))) \
9071 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
9072 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9073static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009074iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009075{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009076 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009077
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009078 *iov = PyMem_New(struct iovec, cnt);
9079 if (*iov == NULL) {
9080 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009081 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009082 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009083
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009084 *buf = PyMem_New(Py_buffer, cnt);
9085 if (*buf == NULL) {
9086 PyMem_Del(*iov);
9087 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009088 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009089 }
9090
9091 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009092 PyObject *item = PySequence_GetItem(seq, i);
9093 if (item == NULL)
9094 goto fail;
9095 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
9096 Py_DECREF(item);
9097 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009098 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009099 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009100 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009101 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009102 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009103 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009104
9105fail:
9106 PyMem_Del(*iov);
9107 for (j = 0; j < i; j++) {
9108 PyBuffer_Release(&(*buf)[j]);
9109 }
9110 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01009111 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009112}
9113
9114static void
9115iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9116{
9117 int i;
9118 PyMem_Del(iov);
9119 for (i = 0; i < cnt; i++) {
9120 PyBuffer_Release(&buf[i]);
9121 }
9122 PyMem_Del(buf);
9123}
9124#endif
9125
Larry Hastings2f936352014-08-05 14:04:04 +10009126
Ross Lagerwall7807c352011-03-17 20:20:30 +02009127#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10009128/*[clinic input]
9129os.readv -> Py_ssize_t
9130
9131 fd: int
9132 buffers: object
9133 /
9134
9135Read from a file descriptor fd into an iterable of buffers.
9136
9137The buffers should be mutable buffers accepting bytes.
9138readv will transfer data into each buffer until it is full
9139and then move on to the next buffer in the sequence to hold
9140the rest of the data.
9141
9142readv returns the total number of bytes read,
9143which may be less than the total capacity of all the buffers.
9144[clinic start generated code]*/
9145
Larry Hastings2f936352014-08-05 14:04:04 +10009146static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009147os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9148/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009149{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009150 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009151 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009152 struct iovec *iov;
9153 Py_buffer *buf;
9154
Larry Hastings2f936352014-08-05 14:04:04 +10009155 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009156 PyErr_SetString(PyExc_TypeError,
9157 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009158 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009159 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009160
Larry Hastings2f936352014-08-05 14:04:04 +10009161 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009162 if (cnt < 0)
9163 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009164
9165 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9166 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009167
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009168 do {
9169 Py_BEGIN_ALLOW_THREADS
9170 n = readv(fd, iov, cnt);
9171 Py_END_ALLOW_THREADS
9172 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009173
9174 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009175 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009176 if (!async_err)
9177 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009178 return -1;
9179 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009180
Larry Hastings2f936352014-08-05 14:04:04 +10009181 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009182}
Larry Hastings2f936352014-08-05 14:04:04 +10009183#endif /* HAVE_READV */
9184
Ross Lagerwall7807c352011-03-17 20:20:30 +02009185
9186#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009187/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009188os.pread
9189
9190 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009191 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009192 offset: Py_off_t
9193 /
9194
9195Read a number of bytes from a file descriptor starting at a particular offset.
9196
9197Read length bytes from file descriptor fd, starting at offset bytes from
9198the beginning of the file. The file offset remains unchanged.
9199[clinic start generated code]*/
9200
Larry Hastings2f936352014-08-05 14:04:04 +10009201static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009202os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9203/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009204{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009205 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009206 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009207 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009208
Larry Hastings2f936352014-08-05 14:04:04 +10009209 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009210 errno = EINVAL;
9211 return posix_error();
9212 }
Larry Hastings2f936352014-08-05 14:04:04 +10009213 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009214 if (buffer == NULL)
9215 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009216
9217 do {
9218 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009219 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009220 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009221 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009222 Py_END_ALLOW_THREADS
9223 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9224
Ross Lagerwall7807c352011-03-17 20:20:30 +02009225 if (n < 0) {
9226 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009227 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009228 }
Larry Hastings2f936352014-08-05 14:04:04 +10009229 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009230 _PyBytes_Resize(&buffer, n);
9231 return buffer;
9232}
Larry Hastings2f936352014-08-05 14:04:04 +10009233#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009234
Pablo Galindo4defba32018-01-27 16:16:37 +00009235#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9236/*[clinic input]
9237os.preadv -> Py_ssize_t
9238
9239 fd: int
9240 buffers: object
9241 offset: Py_off_t
9242 flags: int = 0
9243 /
9244
9245Reads from a file descriptor into a number of mutable bytes-like objects.
9246
9247Combines the functionality of readv() and pread(). As readv(), it will
9248transfer data into each buffer until it is full and then move on to the next
9249buffer in the sequence to hold the rest of the data. Its fourth argument,
9250specifies the file offset at which the input operation is to be performed. It
9251will return the total number of bytes read (which can be less than the total
9252capacity of all the objects).
9253
9254The flags argument contains a bitwise OR of zero or more of the following flags:
9255
9256- RWF_HIPRI
9257- RWF_NOWAIT
9258
9259Using non-zero flags requires Linux 4.6 or newer.
9260[clinic start generated code]*/
9261
9262static Py_ssize_t
9263os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9264 int flags)
9265/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9266{
9267 Py_ssize_t cnt, n;
9268 int async_err = 0;
9269 struct iovec *iov;
9270 Py_buffer *buf;
9271
9272 if (!PySequence_Check(buffers)) {
9273 PyErr_SetString(PyExc_TypeError,
9274 "preadv2() arg 2 must be a sequence");
9275 return -1;
9276 }
9277
9278 cnt = PySequence_Size(buffers);
9279 if (cnt < 0) {
9280 return -1;
9281 }
9282
9283#ifndef HAVE_PREADV2
9284 if(flags != 0) {
9285 argument_unavailable_error("preadv2", "flags");
9286 return -1;
9287 }
9288#endif
9289
9290 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9291 return -1;
9292 }
9293#ifdef HAVE_PREADV2
9294 do {
9295 Py_BEGIN_ALLOW_THREADS
9296 _Py_BEGIN_SUPPRESS_IPH
9297 n = preadv2(fd, iov, cnt, offset, flags);
9298 _Py_END_SUPPRESS_IPH
9299 Py_END_ALLOW_THREADS
9300 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9301#else
9302 do {
9303 Py_BEGIN_ALLOW_THREADS
9304 _Py_BEGIN_SUPPRESS_IPH
9305 n = preadv(fd, iov, cnt, offset);
9306 _Py_END_SUPPRESS_IPH
9307 Py_END_ALLOW_THREADS
9308 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9309#endif
9310
9311 iov_cleanup(iov, buf, cnt);
9312 if (n < 0) {
9313 if (!async_err) {
9314 posix_error();
9315 }
9316 return -1;
9317 }
9318
9319 return n;
9320}
9321#endif /* HAVE_PREADV */
9322
Larry Hastings2f936352014-08-05 14:04:04 +10009323
9324/*[clinic input]
9325os.write -> Py_ssize_t
9326
9327 fd: int
9328 data: Py_buffer
9329 /
9330
9331Write a bytes object to a file descriptor.
9332[clinic start generated code]*/
9333
Larry Hastings2f936352014-08-05 14:04:04 +10009334static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009335os_write_impl(PyObject *module, int fd, Py_buffer *data)
9336/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009337{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009338 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009339}
9340
9341#ifdef HAVE_SENDFILE
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009342#ifdef __APPLE__
9343/*[clinic input]
9344os.sendfile
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009345
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009346 out_fd: int
9347 in_fd: int
9348 offset: Py_off_t
9349 count as sbytes: Py_off_t
9350 headers: object(c_default="NULL") = ()
9351 trailers: object(c_default="NULL") = ()
9352 flags: int = 0
9353
9354Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9355[clinic start generated code]*/
9356
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009357static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009358os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9359 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9360 int flags)
9361/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9362#elif defined(__FreeBSD__) || defined(__DragonFly__)
9363/*[clinic input]
9364os.sendfile
9365
9366 out_fd: int
9367 in_fd: int
9368 offset: Py_off_t
9369 count: Py_ssize_t
9370 headers: object(c_default="NULL") = ()
9371 trailers: object(c_default="NULL") = ()
9372 flags: int = 0
9373
9374Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9375[clinic start generated code]*/
9376
9377static PyObject *
9378os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9379 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9380 int flags)
9381/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9382#else
9383/*[clinic input]
9384os.sendfile
9385
9386 out_fd: int
9387 in_fd: int
9388 offset as offobj: object
9389 count: Py_ssize_t
9390
9391Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9392[clinic start generated code]*/
9393
9394static PyObject *
9395os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9396 Py_ssize_t count)
9397/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9398#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009399{
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009400 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009401 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009402
9403#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9404#ifndef __APPLE__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009405 off_t sbytes;
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009406#endif
9407 Py_buffer *hbuf, *tbuf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009408 struct sf_hdtr sf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009409
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009410 sf.headers = NULL;
9411 sf.trailers = NULL;
9412
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009413 if (headers != NULL) {
9414 if (!PySequence_Check(headers)) {
9415 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009416 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009417 return NULL;
9418 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009419 Py_ssize_t i = PySequence_Size(headers);
9420 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009421 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009422 if (i > INT_MAX) {
9423 PyErr_SetString(PyExc_OverflowError,
9424 "sendfile() header is too large");
9425 return NULL;
9426 }
9427 if (i > 0) {
9428 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009429 if (iov_setup(&(sf.headers), &hbuf,
9430 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009431 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009432#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009433 for (i = 0; i < sf.hdr_cnt; i++) {
9434 Py_ssize_t blen = sf.headers[i].iov_len;
9435# define OFF_T_MAX 0x7fffffffffffffff
9436 if (sbytes >= OFF_T_MAX - blen) {
9437 PyErr_SetString(PyExc_OverflowError,
9438 "sendfile() header is too large");
9439 return NULL;
9440 }
9441 sbytes += blen;
9442 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009443#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009444 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009445 }
9446 }
9447 if (trailers != NULL) {
9448 if (!PySequence_Check(trailers)) {
9449 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009450 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009451 return NULL;
9452 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009453 Py_ssize_t i = PySequence_Size(trailers);
9454 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009455 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009456 if (i > INT_MAX) {
9457 PyErr_SetString(PyExc_OverflowError,
9458 "sendfile() trailer is too large");
9459 return NULL;
9460 }
9461 if (i > 0) {
9462 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009463 if (iov_setup(&(sf.trailers), &tbuf,
9464 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009465 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009466 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009467 }
9468 }
9469
Steve Dower8fc89802015-04-12 00:26:27 -04009470 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009471 do {
9472 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009473#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009474 ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009475#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009476 ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009477#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009478 Py_END_ALLOW_THREADS
9479 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009480 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009481
9482 if (sf.headers != NULL)
9483 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9484 if (sf.trailers != NULL)
9485 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9486
9487 if (ret < 0) {
9488 if ((errno == EAGAIN) || (errno == EBUSY)) {
9489 if (sbytes != 0) {
9490 // some data has been sent
9491 goto done;
9492 }
9493 else {
9494 // no data has been sent; upper application is supposed
9495 // to retry on EAGAIN or EBUSY
9496 return posix_error();
9497 }
9498 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009499 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009500 }
9501 goto done;
9502
9503done:
9504 #if !defined(HAVE_LARGEFILE_SUPPORT)
9505 return Py_BuildValue("l", sbytes);
9506 #else
9507 return Py_BuildValue("L", sbytes);
9508 #endif
9509
9510#else
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009511#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009512 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009513 do {
9514 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009515 ret = sendfile(out_fd, in_fd, NULL, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009516 Py_END_ALLOW_THREADS
9517 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009518 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009519 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009520 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009521 }
9522#endif
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009523 off_t offset;
Larry Hastings2f936352014-08-05 14:04:04 +10009524 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009525 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009526
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009527#if defined(__sun) && defined(__SVR4)
9528 // On Solaris, sendfile raises EINVAL rather than returning 0
9529 // when the offset is equal or bigger than the in_fd size.
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009530 struct stat st;
9531
9532 do {
9533 Py_BEGIN_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009534 ret = fstat(in_fd, &st);
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009535 Py_END_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009536 } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009537 if (ret < 0)
9538 return (!async_err) ? posix_error() : NULL;
9539
9540 if (offset >= st.st_size) {
9541 return Py_BuildValue("i", 0);
9542 }
9543#endif
9544
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009545 do {
9546 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009547 ret = sendfile(out_fd, in_fd, &offset, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009548 Py_END_ALLOW_THREADS
9549 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009550 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009551 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009552 return Py_BuildValue("n", ret);
9553#endif
9554}
Larry Hastings2f936352014-08-05 14:04:04 +10009555#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009556
Larry Hastings2f936352014-08-05 14:04:04 +10009557
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009558#if defined(__APPLE__)
9559/*[clinic input]
9560os._fcopyfile
9561
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009562 in_fd: int
9563 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009564 flags: int
9565 /
9566
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009567Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009568[clinic start generated code]*/
9569
9570static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009571os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9572/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009573{
9574 int ret;
9575
9576 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009577 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009578 Py_END_ALLOW_THREADS
9579 if (ret < 0)
9580 return posix_error();
9581 Py_RETURN_NONE;
9582}
9583#endif
9584
9585
Larry Hastings2f936352014-08-05 14:04:04 +10009586/*[clinic input]
9587os.fstat
9588
9589 fd : int
9590
9591Perform a stat system call on the given file descriptor.
9592
9593Like stat(), but for an open file descriptor.
9594Equivalent to os.stat(fd).
9595[clinic start generated code]*/
9596
Larry Hastings2f936352014-08-05 14:04:04 +10009597static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009598os_fstat_impl(PyObject *module, int fd)
9599/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009600{
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 STRUCT_STAT st;
9602 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009603 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009604
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009605 do {
9606 Py_BEGIN_ALLOW_THREADS
9607 res = FSTAT(fd, &st);
9608 Py_END_ALLOW_THREADS
9609 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009611#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009612 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009613#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009614 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009615#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 }
Tim Peters5aa91602002-01-30 05:46:57 +00009617
Victor Stinner1c2fa782020-05-10 11:05:29 +02009618 return _pystat_fromstructstat(module, &st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009619}
9620
Larry Hastings2f936352014-08-05 14:04:04 +10009621
9622/*[clinic input]
9623os.isatty -> bool
9624 fd: int
9625 /
9626
9627Return True if the fd is connected to a terminal.
9628
9629Return True if the file descriptor is an open file descriptor
9630connected to the slave end of a terminal.
9631[clinic start generated code]*/
9632
Larry Hastings2f936352014-08-05 14:04:04 +10009633static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009634os_isatty_impl(PyObject *module, int fd)
9635/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009636{
Steve Dower8fc89802015-04-12 00:26:27 -04009637 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009638 _Py_BEGIN_SUPPRESS_IPH
9639 return_value = isatty(fd);
9640 _Py_END_SUPPRESS_IPH
9641 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009642}
9643
9644
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009645#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009646/*[clinic input]
9647os.pipe
9648
9649Create a pipe.
9650
9651Returns a tuple of two file descriptors:
9652 (read_fd, write_fd)
9653[clinic start generated code]*/
9654
Larry Hastings2f936352014-08-05 14:04:04 +10009655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009656os_pipe_impl(PyObject *module)
9657/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009658{
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009660#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009662 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009664#else
9665 int res;
9666#endif
9667
9668#ifdef MS_WINDOWS
9669 attr.nLength = sizeof(attr);
9670 attr.lpSecurityDescriptor = NULL;
9671 attr.bInheritHandle = FALSE;
9672
9673 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009674 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009675 ok = CreatePipe(&read, &write, &attr, 0);
9676 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009677 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9678 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009679 if (fds[0] == -1 || fds[1] == -1) {
9680 CloseHandle(read);
9681 CloseHandle(write);
9682 ok = 0;
9683 }
9684 }
Steve Dowerc3630612016-11-19 18:41:16 -08009685 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009686 Py_END_ALLOW_THREADS
9687
Victor Stinner8c62be82010-05-06 00:08:46 +00009688 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009689 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009690#else
9691
9692#ifdef HAVE_PIPE2
9693 Py_BEGIN_ALLOW_THREADS
9694 res = pipe2(fds, O_CLOEXEC);
9695 Py_END_ALLOW_THREADS
9696
9697 if (res != 0 && errno == ENOSYS)
9698 {
9699#endif
9700 Py_BEGIN_ALLOW_THREADS
9701 res = pipe(fds);
9702 Py_END_ALLOW_THREADS
9703
9704 if (res == 0) {
9705 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9706 close(fds[0]);
9707 close(fds[1]);
9708 return NULL;
9709 }
9710 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9711 close(fds[0]);
9712 close(fds[1]);
9713 return NULL;
9714 }
9715 }
9716#ifdef HAVE_PIPE2
9717 }
9718#endif
9719
9720 if (res != 0)
9721 return PyErr_SetFromErrno(PyExc_OSError);
9722#endif /* !MS_WINDOWS */
9723 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009724}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009725#endif /* HAVE_PIPE */
9726
Larry Hastings2f936352014-08-05 14:04:04 +10009727
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009728#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009729/*[clinic input]
9730os.pipe2
9731
9732 flags: int
9733 /
9734
9735Create a pipe with flags set atomically.
9736
9737Returns a tuple of two file descriptors:
9738 (read_fd, write_fd)
9739
9740flags can be constructed by ORing together one or more of these values:
9741O_NONBLOCK, O_CLOEXEC.
9742[clinic start generated code]*/
9743
Larry Hastings2f936352014-08-05 14:04:04 +10009744static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009745os_pipe2_impl(PyObject *module, int flags)
9746/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009747{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009748 int fds[2];
9749 int res;
9750
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009751 res = pipe2(fds, flags);
9752 if (res != 0)
9753 return posix_error();
9754 return Py_BuildValue("(ii)", fds[0], fds[1]);
9755}
9756#endif /* HAVE_PIPE2 */
9757
Larry Hastings2f936352014-08-05 14:04:04 +10009758
Ross Lagerwall7807c352011-03-17 20:20:30 +02009759#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009760/*[clinic input]
9761os.writev -> Py_ssize_t
9762 fd: int
9763 buffers: object
9764 /
9765
9766Iterate over buffers, and write the contents of each to a file descriptor.
9767
9768Returns the total number of bytes written.
9769buffers must be a sequence of bytes-like objects.
9770[clinic start generated code]*/
9771
Larry Hastings2f936352014-08-05 14:04:04 +10009772static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009773os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9774/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009775{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009776 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009777 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009778 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009779 struct iovec *iov;
9780 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009781
9782 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009783 PyErr_SetString(PyExc_TypeError,
9784 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009785 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009786 }
Larry Hastings2f936352014-08-05 14:04:04 +10009787 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009788 if (cnt < 0)
9789 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009790
Larry Hastings2f936352014-08-05 14:04:04 +10009791 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9792 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009793 }
9794
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009795 do {
9796 Py_BEGIN_ALLOW_THREADS
9797 result = writev(fd, iov, cnt);
9798 Py_END_ALLOW_THREADS
9799 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009800
9801 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009802 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009803 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009804
Georg Brandl306336b2012-06-24 12:55:33 +02009805 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009806}
Larry Hastings2f936352014-08-05 14:04:04 +10009807#endif /* HAVE_WRITEV */
9808
9809
9810#ifdef HAVE_PWRITE
9811/*[clinic input]
9812os.pwrite -> Py_ssize_t
9813
9814 fd: int
9815 buffer: Py_buffer
9816 offset: Py_off_t
9817 /
9818
9819Write bytes to a file descriptor starting at a particular offset.
9820
9821Write buffer to fd, starting at offset bytes from the beginning of
9822the file. Returns the number of bytes writte. Does not change the
9823current file offset.
9824[clinic start generated code]*/
9825
Larry Hastings2f936352014-08-05 14:04:04 +10009826static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009827os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9828/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009829{
9830 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009831 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009832
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009833 do {
9834 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009835 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009836 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009837 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009838 Py_END_ALLOW_THREADS
9839 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009840
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009841 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009842 posix_error();
9843 return size;
9844}
9845#endif /* HAVE_PWRITE */
9846
Pablo Galindo4defba32018-01-27 16:16:37 +00009847#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9848/*[clinic input]
9849os.pwritev -> Py_ssize_t
9850
9851 fd: int
9852 buffers: object
9853 offset: Py_off_t
9854 flags: int = 0
9855 /
9856
9857Writes the contents of bytes-like objects to a file descriptor at a given offset.
9858
9859Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9860of bytes-like objects. Buffers are processed in array order. Entire contents of first
9861buffer is written before proceeding to second, and so on. The operating system may
9862set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9863This function writes the contents of each object to the file descriptor and returns
9864the total number of bytes written.
9865
9866The flags argument contains a bitwise OR of zero or more of the following flags:
9867
9868- RWF_DSYNC
9869- RWF_SYNC
YoSTEALTH76ef2552020-05-27 15:32:22 -06009870- RWF_APPEND
Pablo Galindo4defba32018-01-27 16:16:37 +00009871
9872Using non-zero flags requires Linux 4.7 or newer.
9873[clinic start generated code]*/
9874
9875static Py_ssize_t
9876os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9877 int flags)
YoSTEALTH76ef2552020-05-27 15:32:22 -06009878/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=35358c327e1a2a8e]*/
Pablo Galindo4defba32018-01-27 16:16:37 +00009879{
9880 Py_ssize_t cnt;
9881 Py_ssize_t result;
9882 int async_err = 0;
9883 struct iovec *iov;
9884 Py_buffer *buf;
9885
9886 if (!PySequence_Check(buffers)) {
9887 PyErr_SetString(PyExc_TypeError,
9888 "pwritev() arg 2 must be a sequence");
9889 return -1;
9890 }
9891
9892 cnt = PySequence_Size(buffers);
9893 if (cnt < 0) {
9894 return -1;
9895 }
9896
9897#ifndef HAVE_PWRITEV2
9898 if(flags != 0) {
9899 argument_unavailable_error("pwritev2", "flags");
9900 return -1;
9901 }
9902#endif
9903
9904 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9905 return -1;
9906 }
9907#ifdef HAVE_PWRITEV2
9908 do {
9909 Py_BEGIN_ALLOW_THREADS
9910 _Py_BEGIN_SUPPRESS_IPH
9911 result = pwritev2(fd, iov, cnt, offset, flags);
9912 _Py_END_SUPPRESS_IPH
9913 Py_END_ALLOW_THREADS
9914 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9915#else
9916 do {
9917 Py_BEGIN_ALLOW_THREADS
9918 _Py_BEGIN_SUPPRESS_IPH
9919 result = pwritev(fd, iov, cnt, offset);
9920 _Py_END_SUPPRESS_IPH
9921 Py_END_ALLOW_THREADS
9922 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9923#endif
9924
9925 iov_cleanup(iov, buf, cnt);
9926 if (result < 0) {
9927 if (!async_err) {
9928 posix_error();
9929 }
9930 return -1;
9931 }
9932
9933 return result;
9934}
9935#endif /* HAVE_PWRITEV */
9936
Pablo Galindoaac4d032019-05-31 19:39:47 +01009937#ifdef HAVE_COPY_FILE_RANGE
9938/*[clinic input]
9939
9940os.copy_file_range
9941 src: int
9942 Source file descriptor.
9943 dst: int
9944 Destination file descriptor.
9945 count: Py_ssize_t
9946 Number of bytes to copy.
9947 offset_src: object = None
9948 Starting offset in src.
9949 offset_dst: object = None
9950 Starting offset in dst.
9951
9952Copy count bytes from one file descriptor to another.
9953
9954If offset_src is None, then src is read from the current position;
9955respectively for offset_dst.
9956[clinic start generated code]*/
9957
9958static PyObject *
9959os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
9960 PyObject *offset_src, PyObject *offset_dst)
9961/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
9962{
9963 off_t offset_src_val, offset_dst_val;
9964 off_t *p_offset_src = NULL;
9965 off_t *p_offset_dst = NULL;
9966 Py_ssize_t ret;
9967 int async_err = 0;
9968 /* The flags argument is provided to allow
9969 * for future extensions and currently must be to 0. */
9970 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +00009971
9972
Pablo Galindoaac4d032019-05-31 19:39:47 +01009973 if (count < 0) {
9974 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
9975 return NULL;
9976 }
9977
9978 if (offset_src != Py_None) {
9979 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
9980 return NULL;
9981 }
9982 p_offset_src = &offset_src_val;
9983 }
9984
9985 if (offset_dst != Py_None) {
9986 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
9987 return NULL;
9988 }
9989 p_offset_dst = &offset_dst_val;
9990 }
9991
9992 do {
9993 Py_BEGIN_ALLOW_THREADS
9994 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
9995 Py_END_ALLOW_THREADS
9996 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9997
9998 if (ret < 0) {
9999 return (!async_err) ? posix_error() : NULL;
10000 }
10001
10002 return PyLong_FromSsize_t(ret);
10003}
10004#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +100010005
10006#ifdef HAVE_MKFIFO
10007/*[clinic input]
10008os.mkfifo
10009
10010 path: path_t
10011 mode: int=0o666
10012 *
10013 dir_fd: dir_fd(requires='mkfifoat')=None
10014
10015Create a "fifo" (a POSIX named pipe).
10016
10017If dir_fd is not None, it should be a file descriptor open to a directory,
10018 and path should be relative; path will then be relative to that directory.
10019dir_fd may not be implemented on your platform.
10020 If it is unavailable, using it will raise a NotImplementedError.
10021[clinic start generated code]*/
10022
Larry Hastings2f936352014-08-05 14:04:04 +100010023static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010024os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
10025/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010026{
10027 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010028 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010029
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010030 do {
10031 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010032#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010033 if (dir_fd != DEFAULT_DIR_FD)
10034 result = mkfifoat(dir_fd, path->narrow, mode);
10035 else
Ross Lagerwall7807c352011-03-17 20:20:30 +020010036#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010037 result = mkfifo(path->narrow, mode);
10038 Py_END_ALLOW_THREADS
10039 } while (result != 0 && errno == EINTR &&
10040 !(async_err = PyErr_CheckSignals()));
10041 if (result != 0)
10042 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010043
10044 Py_RETURN_NONE;
10045}
10046#endif /* HAVE_MKFIFO */
10047
10048
10049#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
10050/*[clinic input]
10051os.mknod
10052
10053 path: path_t
10054 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010055 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +100010056 *
10057 dir_fd: dir_fd(requires='mknodat')=None
10058
10059Create a node in the file system.
10060
10061Create a node in the file system (file, device special file or named pipe)
10062at path. mode specifies both the permissions to use and the
10063type of node to be created, being combined (bitwise OR) with one of
10064S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
10065device defines the newly created device special file (probably using
10066os.makedev()). Otherwise device is ignored.
10067
10068If dir_fd is not None, it should be a file descriptor open to a directory,
10069 and path should be relative; path will then be relative to that directory.
10070dir_fd may not be implemented on your platform.
10071 If it is unavailable, using it will raise a NotImplementedError.
10072[clinic start generated code]*/
10073
Larry Hastings2f936352014-08-05 14:04:04 +100010074static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010075os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -040010076 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010077/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010078{
10079 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010080 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010081
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010082 do {
10083 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010084#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010085 if (dir_fd != DEFAULT_DIR_FD)
10086 result = mknodat(dir_fd, path->narrow, mode, device);
10087 else
Larry Hastings2f936352014-08-05 14:04:04 +100010088#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010089 result = mknod(path->narrow, mode, device);
10090 Py_END_ALLOW_THREADS
10091 } while (result != 0 && errno == EINTR &&
10092 !(async_err = PyErr_CheckSignals()));
10093 if (result != 0)
10094 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010095
10096 Py_RETURN_NONE;
10097}
10098#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10099
10100
10101#ifdef HAVE_DEVICE_MACROS
10102/*[clinic input]
10103os.major -> unsigned_int
10104
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010105 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010106 /
10107
10108Extracts a device major number from a raw device number.
10109[clinic start generated code]*/
10110
Larry Hastings2f936352014-08-05 14:04:04 +100010111static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010112os_major_impl(PyObject *module, dev_t device)
10113/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010114{
10115 return major(device);
10116}
10117
10118
10119/*[clinic input]
10120os.minor -> unsigned_int
10121
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010122 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010123 /
10124
10125Extracts a device minor number from a raw device number.
10126[clinic start generated code]*/
10127
Larry Hastings2f936352014-08-05 14:04:04 +100010128static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010129os_minor_impl(PyObject *module, dev_t device)
10130/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010131{
10132 return minor(device);
10133}
10134
10135
10136/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010137os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010138
10139 major: int
10140 minor: int
10141 /
10142
10143Composes a raw device number from the major and minor device numbers.
10144[clinic start generated code]*/
10145
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010146static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010147os_makedev_impl(PyObject *module, int major, int minor)
10148/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010149{
10150 return makedev(major, minor);
10151}
10152#endif /* HAVE_DEVICE_MACROS */
10153
10154
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010155#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010156/*[clinic input]
10157os.ftruncate
10158
10159 fd: int
10160 length: Py_off_t
10161 /
10162
10163Truncate a file, specified by file descriptor, to a specific length.
10164[clinic start generated code]*/
10165
Larry Hastings2f936352014-08-05 14:04:04 +100010166static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010167os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10168/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010169{
10170 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010171 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010172
Steve Dowerb82e17e2019-05-23 08:45:22 -070010173 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
10174 return NULL;
10175 }
10176
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010177 do {
10178 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010179 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010180#ifdef MS_WINDOWS
10181 result = _chsize_s(fd, length);
10182#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010183 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010184#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010185 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010186 Py_END_ALLOW_THREADS
10187 } while (result != 0 && errno == EINTR &&
10188 !(async_err = PyErr_CheckSignals()));
10189 if (result != 0)
10190 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010191 Py_RETURN_NONE;
10192}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010193#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010194
10195
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010196#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010197/*[clinic input]
10198os.truncate
10199 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10200 length: Py_off_t
10201
10202Truncate a file, specified by path, to a specific length.
10203
10204On some platforms, path may also be specified as an open file descriptor.
10205 If this functionality is unavailable, using it raises an exception.
10206[clinic start generated code]*/
10207
Larry Hastings2f936352014-08-05 14:04:04 +100010208static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010209os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10210/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010211{
10212 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010213#ifdef MS_WINDOWS
10214 int fd;
10215#endif
10216
10217 if (path->fd != -1)
10218 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010219
Steve Dowerb82e17e2019-05-23 08:45:22 -070010220 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10221 return NULL;
10222 }
10223
Larry Hastings2f936352014-08-05 14:04:04 +100010224 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010225 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010226#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010227 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010228 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010229 result = -1;
10230 else {
10231 result = _chsize_s(fd, length);
10232 close(fd);
10233 if (result < 0)
10234 errno = result;
10235 }
10236#else
10237 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010238#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010239 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010240 Py_END_ALLOW_THREADS
10241 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010242 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010243
10244 Py_RETURN_NONE;
10245}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010246#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010247
Ross Lagerwall7807c352011-03-17 20:20:30 +020010248
Victor Stinnerd6b17692014-09-30 12:20:05 +020010249/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10250 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10251 defined, which is the case in Python on AIX. AIX bug report:
10252 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10253#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10254# define POSIX_FADVISE_AIX_BUG
10255#endif
10256
Victor Stinnerec39e262014-09-30 12:35:58 +020010257
Victor Stinnerd6b17692014-09-30 12:20:05 +020010258#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010259/*[clinic input]
10260os.posix_fallocate
10261
10262 fd: int
10263 offset: Py_off_t
10264 length: Py_off_t
10265 /
10266
10267Ensure a file has allocated at least a particular number of bytes on disk.
10268
10269Ensure that the file specified by fd encompasses a range of bytes
10270starting at offset bytes from the beginning and continuing for length bytes.
10271[clinic start generated code]*/
10272
Larry Hastings2f936352014-08-05 14:04:04 +100010273static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010274os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010275 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010276/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010277{
10278 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010279 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010280
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010281 do {
10282 Py_BEGIN_ALLOW_THREADS
10283 result = posix_fallocate(fd, offset, length);
10284 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010285 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10286
10287 if (result == 0)
10288 Py_RETURN_NONE;
10289
10290 if (async_err)
10291 return NULL;
10292
10293 errno = result;
10294 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010295}
Victor Stinnerec39e262014-09-30 12:35:58 +020010296#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010297
Ross Lagerwall7807c352011-03-17 20:20:30 +020010298
Victor Stinnerd6b17692014-09-30 12:20:05 +020010299#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010300/*[clinic input]
10301os.posix_fadvise
10302
10303 fd: int
10304 offset: Py_off_t
10305 length: Py_off_t
10306 advice: int
10307 /
10308
10309Announce an intention to access data in a specific pattern.
10310
10311Announce an intention to access data in a specific pattern, thus allowing
10312the kernel to make optimizations.
10313The advice applies to the region of the file specified by fd starting at
10314offset and continuing for length bytes.
10315advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10316POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10317POSIX_FADV_DONTNEED.
10318[clinic start generated code]*/
10319
Larry Hastings2f936352014-08-05 14:04:04 +100010320static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010321os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010322 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010323/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010324{
10325 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010326 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010327
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010328 do {
10329 Py_BEGIN_ALLOW_THREADS
10330 result = posix_fadvise(fd, offset, length, advice);
10331 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010332 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10333
10334 if (result == 0)
10335 Py_RETURN_NONE;
10336
10337 if (async_err)
10338 return NULL;
10339
10340 errno = result;
10341 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010342}
Victor Stinnerec39e262014-09-30 12:35:58 +020010343#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010344
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010345
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010346#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010347static PyObject*
10348win32_putenv(PyObject *name, PyObject *value)
10349{
10350 /* Search from index 1 because on Windows starting '=' is allowed for
10351 defining hidden environment variables. */
10352 if (PyUnicode_GET_LENGTH(name) == 0 ||
10353 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10354 {
10355 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10356 return NULL;
10357 }
10358 PyObject *unicode;
10359 if (value != NULL) {
10360 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10361 }
10362 else {
10363 unicode = PyUnicode_FromFormat("%U=", name);
10364 }
10365 if (unicode == NULL) {
10366 return NULL;
10367 }
10368
10369 Py_ssize_t size;
10370 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10371 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10372 Py_DECREF(unicode);
10373
10374 if (env == NULL) {
10375 return NULL;
10376 }
10377 if (size > _MAX_ENV) {
10378 PyErr_Format(PyExc_ValueError,
10379 "the environment variable is longer than %u characters",
10380 _MAX_ENV);
10381 PyMem_Free(env);
10382 return NULL;
10383 }
10384
10385 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10386 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10387 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10388
10389 Prefer _wputenv() to be compatible with C libraries using CRT
10390 variables and CRT functions using these variables (ex: getenv()). */
10391 int err = _wputenv(env);
10392 PyMem_Free(env);
10393
10394 if (err) {
10395 posix_error();
10396 return NULL;
10397 }
10398
10399 Py_RETURN_NONE;
10400}
10401#endif
10402
10403
10404#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010405/*[clinic input]
10406os.putenv
10407
10408 name: unicode
10409 value: unicode
10410 /
10411
10412Change or add an environment variable.
10413[clinic start generated code]*/
10414
Larry Hastings2f936352014-08-05 14:04:04 +100010415static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010416os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10417/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010418{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010419 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10420 return NULL;
10421 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010422 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010423}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010424#else
Larry Hastings2f936352014-08-05 14:04:04 +100010425/*[clinic input]
10426os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010427
Larry Hastings2f936352014-08-05 14:04:04 +100010428 name: FSConverter
10429 value: FSConverter
10430 /
10431
10432Change or add an environment variable.
10433[clinic start generated code]*/
10434
Larry Hastings2f936352014-08-05 14:04:04 +100010435static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010436os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10437/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010438{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010439 const char *name_string = PyBytes_AS_STRING(name);
10440 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010441
Serhiy Storchaka77703942017-06-25 07:33:01 +030010442 if (strchr(name_string, '=') != NULL) {
10443 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10444 return NULL;
10445 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010446
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010447 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10448 return NULL;
10449 }
10450
Victor Stinnerb477d192020-01-22 22:48:16 +010010451 if (setenv(name_string, value_string, 1)) {
10452 return posix_error();
10453 }
Larry Hastings2f936352014-08-05 14:04:04 +100010454 Py_RETURN_NONE;
10455}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010456#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010457
10458
Victor Stinner161e7b32020-01-24 11:53:44 +010010459#ifdef MS_WINDOWS
10460/*[clinic input]
10461os.unsetenv
10462 name: unicode
10463 /
10464
10465Delete an environment variable.
10466[clinic start generated code]*/
10467
10468static PyObject *
10469os_unsetenv_impl(PyObject *module, PyObject *name)
10470/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10471{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010472 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10473 return NULL;
10474 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010475 return win32_putenv(name, NULL);
10476}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010477#else
Larry Hastings2f936352014-08-05 14:04:04 +100010478/*[clinic input]
10479os.unsetenv
10480 name: FSConverter
10481 /
10482
10483Delete an environment variable.
10484[clinic start generated code]*/
10485
Larry Hastings2f936352014-08-05 14:04:04 +100010486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010487os_unsetenv_impl(PyObject *module, PyObject *name)
10488/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010489{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010490 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10491 return NULL;
10492 }
Victor Stinner984890f2011-11-24 13:53:38 +010010493#ifdef HAVE_BROKEN_UNSETENV
10494 unsetenv(PyBytes_AS_STRING(name));
10495#else
Victor Stinner161e7b32020-01-24 11:53:44 +010010496 int err = unsetenv(PyBytes_AS_STRING(name));
10497 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010010498 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010010499 }
Victor Stinner984890f2011-11-24 13:53:38 +010010500#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010501
Victor Stinner84ae1182010-05-06 22:05:07 +000010502 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010503}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010504#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000010505
Larry Hastings2f936352014-08-05 14:04:04 +100010506
10507/*[clinic input]
10508os.strerror
10509
10510 code: int
10511 /
10512
10513Translate an error code to a message string.
10514[clinic start generated code]*/
10515
Larry Hastings2f936352014-08-05 14:04:04 +100010516static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010517os_strerror_impl(PyObject *module, int code)
10518/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010519{
10520 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010521 if (message == NULL) {
10522 PyErr_SetString(PyExc_ValueError,
10523 "strerror() argument out of range");
10524 return NULL;
10525 }
Victor Stinner1b579672011-12-17 05:47:23 +010010526 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010527}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010528
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010529
Guido van Rossumc9641791998-08-04 15:26:23 +000010530#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010531#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010532/*[clinic input]
10533os.WCOREDUMP -> bool
10534
10535 status: int
10536 /
10537
10538Return True if the process returning status was dumped to a core file.
10539[clinic start generated code]*/
10540
Larry Hastings2f936352014-08-05 14:04:04 +100010541static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010542os_WCOREDUMP_impl(PyObject *module, int status)
10543/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010544{
10545 WAIT_TYPE wait_status;
10546 WAIT_STATUS_INT(wait_status) = status;
10547 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010548}
10549#endif /* WCOREDUMP */
10550
Larry Hastings2f936352014-08-05 14:04:04 +100010551
Fred Drake106c1a02002-04-23 15:58:02 +000010552#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010553/*[clinic input]
10554os.WIFCONTINUED -> bool
10555
10556 status: int
10557
10558Return True if a particular process was continued from a job control stop.
10559
10560Return True if the process returning status was continued from a
10561job control stop.
10562[clinic start generated code]*/
10563
Larry Hastings2f936352014-08-05 14:04:04 +100010564static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010565os_WIFCONTINUED_impl(PyObject *module, int status)
10566/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010567{
10568 WAIT_TYPE wait_status;
10569 WAIT_STATUS_INT(wait_status) = status;
10570 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010571}
10572#endif /* WIFCONTINUED */
10573
Larry Hastings2f936352014-08-05 14:04:04 +100010574
Guido van Rossumc9641791998-08-04 15:26:23 +000010575#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010576/*[clinic input]
10577os.WIFSTOPPED -> bool
10578
10579 status: int
10580
10581Return True if the process returning status was stopped.
10582[clinic start generated code]*/
10583
Larry Hastings2f936352014-08-05 14:04:04 +100010584static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010585os_WIFSTOPPED_impl(PyObject *module, int status)
10586/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010587{
10588 WAIT_TYPE wait_status;
10589 WAIT_STATUS_INT(wait_status) = status;
10590 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010591}
10592#endif /* WIFSTOPPED */
10593
Larry Hastings2f936352014-08-05 14:04:04 +100010594
Guido van Rossumc9641791998-08-04 15:26:23 +000010595#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010596/*[clinic input]
10597os.WIFSIGNALED -> bool
10598
10599 status: int
10600
10601Return True if the process returning status was terminated by a signal.
10602[clinic start generated code]*/
10603
Larry Hastings2f936352014-08-05 14:04:04 +100010604static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010605os_WIFSIGNALED_impl(PyObject *module, int status)
10606/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010607{
10608 WAIT_TYPE wait_status;
10609 WAIT_STATUS_INT(wait_status) = status;
10610 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010611}
10612#endif /* WIFSIGNALED */
10613
Larry Hastings2f936352014-08-05 14:04:04 +100010614
Guido van Rossumc9641791998-08-04 15:26:23 +000010615#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010616/*[clinic input]
10617os.WIFEXITED -> bool
10618
10619 status: int
10620
10621Return True if the process returning status exited via the exit() system call.
10622[clinic start generated code]*/
10623
Larry Hastings2f936352014-08-05 14:04:04 +100010624static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010625os_WIFEXITED_impl(PyObject *module, int status)
10626/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010627{
10628 WAIT_TYPE wait_status;
10629 WAIT_STATUS_INT(wait_status) = status;
10630 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010631}
10632#endif /* WIFEXITED */
10633
Larry Hastings2f936352014-08-05 14:04:04 +100010634
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010635#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010636/*[clinic input]
10637os.WEXITSTATUS -> int
10638
10639 status: int
10640
10641Return the process return code from status.
10642[clinic start generated code]*/
10643
Larry Hastings2f936352014-08-05 14:04:04 +100010644static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010645os_WEXITSTATUS_impl(PyObject *module, int status)
10646/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010647{
10648 WAIT_TYPE wait_status;
10649 WAIT_STATUS_INT(wait_status) = status;
10650 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010651}
10652#endif /* WEXITSTATUS */
10653
Larry Hastings2f936352014-08-05 14:04:04 +100010654
Guido van Rossumc9641791998-08-04 15:26:23 +000010655#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010656/*[clinic input]
10657os.WTERMSIG -> int
10658
10659 status: int
10660
10661Return the signal that terminated the process that provided the status value.
10662[clinic start generated code]*/
10663
Larry Hastings2f936352014-08-05 14:04:04 +100010664static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010665os_WTERMSIG_impl(PyObject *module, int status)
10666/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010667{
10668 WAIT_TYPE wait_status;
10669 WAIT_STATUS_INT(wait_status) = status;
10670 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010671}
10672#endif /* WTERMSIG */
10673
Larry Hastings2f936352014-08-05 14:04:04 +100010674
Guido van Rossumc9641791998-08-04 15:26:23 +000010675#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010676/*[clinic input]
10677os.WSTOPSIG -> int
10678
10679 status: int
10680
10681Return the signal that stopped the process that provided the status value.
10682[clinic start generated code]*/
10683
Larry Hastings2f936352014-08-05 14:04:04 +100010684static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010685os_WSTOPSIG_impl(PyObject *module, int status)
10686/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010687{
10688 WAIT_TYPE wait_status;
10689 WAIT_STATUS_INT(wait_status) = status;
10690 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010691}
10692#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010693#endif /* HAVE_SYS_WAIT_H */
10694
10695
Thomas Wouters477c8d52006-05-27 19:21:47 +000010696#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010697#ifdef _SCO_DS
10698/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10699 needed definitions in sys/statvfs.h */
10700#define _SVID3
10701#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010702#include <sys/statvfs.h>
10703
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010704static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +020010705_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
10706 PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080010707 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 if (v == NULL)
10709 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010710
10711#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010712 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10713 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10714 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10715 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10716 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10717 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10718 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10719 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10720 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10721 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010722#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10724 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10725 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010726 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010727 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010728 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010730 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010731 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010732 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010733 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010734 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010736 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010737 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10738 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010739#endif
Michael Felt502d5512018-01-05 13:01:58 +010010740/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10741 * (issue #32390). */
10742#if defined(_AIX) && defined(_ALL_SOURCE)
10743 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10744#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010745 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010746#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010747 if (PyErr_Occurred()) {
10748 Py_DECREF(v);
10749 return NULL;
10750 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010751
Victor Stinner8c62be82010-05-06 00:08:46 +000010752 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010753}
10754
Larry Hastings2f936352014-08-05 14:04:04 +100010755
10756/*[clinic input]
10757os.fstatvfs
10758 fd: int
10759 /
10760
10761Perform an fstatvfs system call on the given fd.
10762
10763Equivalent to statvfs(fd).
10764[clinic start generated code]*/
10765
Larry Hastings2f936352014-08-05 14:04:04 +100010766static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010767os_fstatvfs_impl(PyObject *module, int fd)
10768/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010769{
10770 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010771 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010772 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010773
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010774 do {
10775 Py_BEGIN_ALLOW_THREADS
10776 result = fstatvfs(fd, &st);
10777 Py_END_ALLOW_THREADS
10778 } while (result != 0 && errno == EINTR &&
10779 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010780 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010781 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010782
Victor Stinner1c2fa782020-05-10 11:05:29 +020010783 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010784}
Larry Hastings2f936352014-08-05 14:04:04 +100010785#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010786
10787
Thomas Wouters477c8d52006-05-27 19:21:47 +000010788#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010789#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010790/*[clinic input]
10791os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010792
Larry Hastings2f936352014-08-05 14:04:04 +100010793 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10794
10795Perform a statvfs system call on the given path.
10796
10797path may always be specified as a string.
10798On some platforms, path may also be specified as an open file descriptor.
10799 If this functionality is unavailable, using it raises an exception.
10800[clinic start generated code]*/
10801
Larry Hastings2f936352014-08-05 14:04:04 +100010802static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010803os_statvfs_impl(PyObject *module, path_t *path)
10804/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010805{
10806 int result;
10807 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010808
10809 Py_BEGIN_ALLOW_THREADS
10810#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010811 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010812#ifdef __APPLE__
10813 /* handle weak-linking on Mac OS X 10.3 */
10814 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010815 fd_specified("statvfs", path->fd);
10816 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010817 }
10818#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010819 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010820 }
10821 else
10822#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010823 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010824 Py_END_ALLOW_THREADS
10825
10826 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010827 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010828 }
10829
Victor Stinner1c2fa782020-05-10 11:05:29 +020010830 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010831}
Larry Hastings2f936352014-08-05 14:04:04 +100010832#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10833
Guido van Rossum94f6f721999-01-06 18:42:14 +000010834
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010835#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010836/*[clinic input]
10837os._getdiskusage
10838
Steve Dower23ad6d02018-02-22 10:39:10 -080010839 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010840
10841Return disk usage statistics about the given path as a (total, free) tuple.
10842[clinic start generated code]*/
10843
Larry Hastings2f936352014-08-05 14:04:04 +100010844static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010845os__getdiskusage_impl(PyObject *module, path_t *path)
10846/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010847{
10848 BOOL retval;
10849 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010850 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010851
10852 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010853 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010854 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010855 if (retval == 0) {
10856 if (GetLastError() == ERROR_DIRECTORY) {
10857 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010858
Joe Pamerc8c02492018-09-25 10:57:36 -040010859 dir_path = PyMem_New(wchar_t, path->length + 1);
10860 if (dir_path == NULL) {
10861 return PyErr_NoMemory();
10862 }
10863
10864 wcscpy_s(dir_path, path->length + 1, path->wide);
10865
10866 if (_dirnameW(dir_path) != -1) {
10867 Py_BEGIN_ALLOW_THREADS
10868 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10869 Py_END_ALLOW_THREADS
10870 }
10871 /* Record the last error in case it's modified by PyMem_Free. */
10872 err = GetLastError();
10873 PyMem_Free(dir_path);
10874 if (retval) {
10875 goto success;
10876 }
10877 }
10878 return PyErr_SetFromWindowsErr(err);
10879 }
10880
10881success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010882 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10883}
Larry Hastings2f936352014-08-05 14:04:04 +100010884#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010885
10886
Fred Drakec9680921999-12-13 16:37:25 +000010887/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10888 * It maps strings representing configuration variable names to
10889 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010890 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010891 * rarely-used constants. There are three separate tables that use
10892 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010893 *
10894 * This code is always included, even if none of the interfaces that
10895 * need it are included. The #if hackery needed to avoid it would be
10896 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010897 */
10898struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010899 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010900 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010901};
10902
Fred Drake12c6e2d1999-12-14 21:25:03 +000010903static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010904conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010905 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010906{
Christian Heimes217cfd12007-12-02 14:31:20 +000010907 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010908 int value = _PyLong_AsInt(arg);
10909 if (value == -1 && PyErr_Occurred())
10910 return 0;
10911 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010912 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010913 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010914 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010915 /* look up the value in the table using a binary search */
10916 size_t lo = 0;
10917 size_t mid;
10918 size_t hi = tablesize;
10919 int cmp;
10920 const char *confname;
10921 if (!PyUnicode_Check(arg)) {
10922 PyErr_SetString(PyExc_TypeError,
10923 "configuration names must be strings or integers");
10924 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010925 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010926 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010927 if (confname == NULL)
10928 return 0;
10929 while (lo < hi) {
10930 mid = (lo + hi) / 2;
10931 cmp = strcmp(confname, table[mid].name);
10932 if (cmp < 0)
10933 hi = mid;
10934 else if (cmp > 0)
10935 lo = mid + 1;
10936 else {
10937 *valuep = table[mid].value;
10938 return 1;
10939 }
10940 }
10941 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10942 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010943 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010944}
10945
10946
10947#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10948static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010949#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010950 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010951#endif
10952#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010953 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010954#endif
Fred Drakec9680921999-12-13 16:37:25 +000010955#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010957#endif
10958#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010960#endif
10961#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010962 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010963#endif
10964#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010965 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010966#endif
10967#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010968 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010969#endif
10970#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010972#endif
10973#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010975#endif
10976#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010977 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010978#endif
10979#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010981#endif
10982#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010984#endif
10985#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010986 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010987#endif
10988#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010989 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010990#endif
10991#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010992 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010993#endif
10994#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010996#endif
10997#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010998 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010999#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000011000#ifdef _PC_ACL_ENABLED
11001 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
11002#endif
11003#ifdef _PC_MIN_HOLE_SIZE
11004 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
11005#endif
11006#ifdef _PC_ALLOC_SIZE_MIN
11007 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
11008#endif
11009#ifdef _PC_REC_INCR_XFER_SIZE
11010 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
11011#endif
11012#ifdef _PC_REC_MAX_XFER_SIZE
11013 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
11014#endif
11015#ifdef _PC_REC_MIN_XFER_SIZE
11016 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
11017#endif
11018#ifdef _PC_REC_XFER_ALIGN
11019 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
11020#endif
11021#ifdef _PC_SYMLINK_MAX
11022 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
11023#endif
11024#ifdef _PC_XATTR_ENABLED
11025 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
11026#endif
11027#ifdef _PC_XATTR_EXISTS
11028 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
11029#endif
11030#ifdef _PC_TIMESTAMP_RESOLUTION
11031 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
11032#endif
Fred Drakec9680921999-12-13 16:37:25 +000011033};
11034
Fred Drakec9680921999-12-13 16:37:25 +000011035static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011036conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011037{
11038 return conv_confname(arg, valuep, posix_constants_pathconf,
11039 sizeof(posix_constants_pathconf)
11040 / sizeof(struct constdef));
11041}
11042#endif
11043
Larry Hastings2f936352014-08-05 14:04:04 +100011044
Fred Drakec9680921999-12-13 16:37:25 +000011045#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011046/*[clinic input]
11047os.fpathconf -> long
11048
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011049 fd: fildes
Larry Hastings2f936352014-08-05 14:04:04 +100011050 name: path_confname
11051 /
11052
11053Return the configuration limit name for the file descriptor fd.
11054
11055If there is no limit, return -1.
11056[clinic start generated code]*/
11057
Larry Hastings2f936352014-08-05 14:04:04 +100011058static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011059os_fpathconf_impl(PyObject *module, int fd, int name)
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011060/*[clinic end generated code: output=d5b7042425fc3e21 input=5b8d2471cfaae186]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011061{
11062 long limit;
11063
11064 errno = 0;
11065 limit = fpathconf(fd, name);
11066 if (limit == -1 && errno != 0)
11067 posix_error();
11068
11069 return limit;
11070}
11071#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011072
11073
11074#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011075/*[clinic input]
11076os.pathconf -> long
11077 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
11078 name: path_confname
11079
11080Return the configuration limit name for the file or directory path.
11081
11082If there is no limit, return -1.
11083On some platforms, path may also be specified as an open file descriptor.
11084 If this functionality is unavailable, using it raises an exception.
11085[clinic start generated code]*/
11086
Larry Hastings2f936352014-08-05 14:04:04 +100011087static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011088os_pathconf_impl(PyObject *module, path_t *path, int name)
11089/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011090{
Victor Stinner8c62be82010-05-06 00:08:46 +000011091 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000011092
Victor Stinner8c62be82010-05-06 00:08:46 +000011093 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020011094#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011095 if (path->fd != -1)
11096 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020011097 else
11098#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011099 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000011100 if (limit == -1 && errno != 0) {
11101 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000011102 /* could be a path or name problem */
11103 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000011104 else
Larry Hastings2f936352014-08-05 14:04:04 +100011105 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000011106 }
Larry Hastings2f936352014-08-05 14:04:04 +100011107
11108 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000011109}
Larry Hastings2f936352014-08-05 14:04:04 +100011110#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011111
11112#ifdef HAVE_CONFSTR
11113static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011114#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000011115 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000011116#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000011117#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011118 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011119#endif
11120#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011121 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011122#endif
Fred Draked86ed291999-12-15 15:34:33 +000011123#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011124 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011125#endif
11126#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011127 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011128#endif
11129#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011130 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011131#endif
11132#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011133 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011134#endif
Fred Drakec9680921999-12-13 16:37:25 +000011135#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011136 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011137#endif
11138#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011139 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011140#endif
11141#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011142 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011143#endif
11144#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011145 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011146#endif
11147#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011149#endif
11150#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011151 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011152#endif
11153#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011155#endif
11156#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011158#endif
Fred Draked86ed291999-12-15 15:34:33 +000011159#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000011161#endif
Fred Drakec9680921999-12-13 16:37:25 +000011162#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000011164#endif
Fred Draked86ed291999-12-15 15:34:33 +000011165#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000011167#endif
11168#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000011170#endif
11171#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011173#endif
11174#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011175 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000011176#endif
Fred Drakec9680921999-12-13 16:37:25 +000011177#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011178 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011179#endif
11180#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011181 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011182#endif
11183#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011184 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011185#endif
11186#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011187 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011188#endif
11189#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011190 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011191#endif
11192#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011193 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011194#endif
11195#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011196 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011197#endif
11198#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011199 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011200#endif
11201#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011202 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011203#endif
11204#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011205 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011206#endif
11207#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011208 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011209#endif
11210#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011211 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011212#endif
11213#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011215#endif
11216#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011218#endif
11219#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011221#endif
11222#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011223 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011224#endif
Fred Draked86ed291999-12-15 15:34:33 +000011225#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011227#endif
11228#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011230#endif
11231#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011233#endif
11234#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011235 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011236#endif
11237#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011239#endif
11240#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011242#endif
11243#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011245#endif
11246#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011248#endif
11249#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011250 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011251#endif
11252#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011254#endif
11255#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011257#endif
11258#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011260#endif
11261#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011263#endif
Fred Drakec9680921999-12-13 16:37:25 +000011264};
11265
11266static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011267conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011268{
11269 return conv_confname(arg, valuep, posix_constants_confstr,
11270 sizeof(posix_constants_confstr)
11271 / sizeof(struct constdef));
11272}
11273
Larry Hastings2f936352014-08-05 14:04:04 +100011274
11275/*[clinic input]
11276os.confstr
11277
11278 name: confstr_confname
11279 /
11280
11281Return a string-valued system configuration variable.
11282[clinic start generated code]*/
11283
Larry Hastings2f936352014-08-05 14:04:04 +100011284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011285os_confstr_impl(PyObject *module, int name)
11286/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011287{
11288 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011289 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011290 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011291
Victor Stinnercb043522010-09-10 23:49:04 +000011292 errno = 0;
11293 len = confstr(name, buffer, sizeof(buffer));
11294 if (len == 0) {
11295 if (errno) {
11296 posix_error();
11297 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011298 }
11299 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011300 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011301 }
11302 }
Victor Stinnercb043522010-09-10 23:49:04 +000011303
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011304 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011305 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011306 char *buf = PyMem_Malloc(len);
11307 if (buf == NULL)
11308 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011309 len2 = confstr(name, buf, len);
11310 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011311 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011312 PyMem_Free(buf);
11313 }
11314 else
11315 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011316 return result;
11317}
Larry Hastings2f936352014-08-05 14:04:04 +100011318#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011319
11320
11321#ifdef HAVE_SYSCONF
11322static struct constdef posix_constants_sysconf[] = {
11323#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011324 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011325#endif
11326#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011327 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011328#endif
11329#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011330 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011331#endif
11332#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011334#endif
11335#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011336 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011337#endif
11338#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011339 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011340#endif
11341#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011342 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011343#endif
11344#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011345 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011346#endif
11347#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011348 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011349#endif
11350#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011351 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011352#endif
Fred Draked86ed291999-12-15 15:34:33 +000011353#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011354 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011355#endif
11356#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011357 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011358#endif
Fred Drakec9680921999-12-13 16:37:25 +000011359#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011361#endif
Fred Drakec9680921999-12-13 16:37:25 +000011362#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011363 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011364#endif
11365#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011366 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011367#endif
11368#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011369 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011370#endif
11371#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011373#endif
11374#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011376#endif
Fred Draked86ed291999-12-15 15:34:33 +000011377#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011379#endif
Fred Drakec9680921999-12-13 16:37:25 +000011380#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011382#endif
11383#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011384 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011385#endif
11386#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011388#endif
11389#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011391#endif
11392#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011394#endif
Fred Draked86ed291999-12-15 15:34:33 +000011395#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011397#endif
Fred Drakec9680921999-12-13 16:37:25 +000011398#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011399 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011400#endif
11401#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011402 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011403#endif
11404#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011406#endif
11407#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011408 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011409#endif
11410#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011412#endif
11413#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011415#endif
11416#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011417 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011418#endif
11419#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011420 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011421#endif
11422#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011424#endif
11425#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011427#endif
11428#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011429 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011430#endif
11431#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011432 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011433#endif
11434#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011435 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011436#endif
11437#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011438 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011439#endif
11440#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011442#endif
11443#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011445#endif
11446#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011447 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011448#endif
11449#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011450 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011451#endif
11452#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011453 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011454#endif
11455#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011456 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011457#endif
11458#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011459 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011460#endif
11461#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011462 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011463#endif
11464#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011466#endif
Fred Draked86ed291999-12-15 15:34:33 +000011467#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011468 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011469#endif
Fred Drakec9680921999-12-13 16:37:25 +000011470#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011472#endif
11473#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011474 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011475#endif
11476#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011477 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011478#endif
Fred Draked86ed291999-12-15 15:34:33 +000011479#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011480 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011481#endif
Fred Drakec9680921999-12-13 16:37:25 +000011482#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011484#endif
Fred Draked86ed291999-12-15 15:34:33 +000011485#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011486 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011487#endif
11488#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011489 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011490#endif
Fred Drakec9680921999-12-13 16:37:25 +000011491#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011492 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011493#endif
11494#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011495 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011496#endif
11497#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011498 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011499#endif
11500#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011501 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011502#endif
Fred Draked86ed291999-12-15 15:34:33 +000011503#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011504 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011505#endif
Fred Drakec9680921999-12-13 16:37:25 +000011506#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011507 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011508#endif
11509#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011510 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011511#endif
11512#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011513 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011514#endif
11515#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011516 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011517#endif
11518#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011519 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011520#endif
11521#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011522 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011523#endif
11524#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011525 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011526#endif
Fred Draked86ed291999-12-15 15:34:33 +000011527#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011529#endif
Fred Drakec9680921999-12-13 16:37:25 +000011530#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011531 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011532#endif
11533#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011535#endif
Fred Draked86ed291999-12-15 15:34:33 +000011536#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011537 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011538#endif
Fred Drakec9680921999-12-13 16:37:25 +000011539#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011540 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011541#endif
11542#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011544#endif
11545#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011547#endif
11548#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011549 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011550#endif
11551#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011553#endif
11554#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011556#endif
11557#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011559#endif
11560#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011561 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011562#endif
11563#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011564 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011565#endif
Fred Draked86ed291999-12-15 15:34:33 +000011566#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011567 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011568#endif
11569#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011570 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011571#endif
Fred Drakec9680921999-12-13 16:37:25 +000011572#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011573 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011574#endif
11575#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011576 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011577#endif
11578#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011579 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011580#endif
11581#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011582 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011583#endif
Batuhan Taşkaya909f4a32020-04-05 03:40:49 +030011584#ifdef _SC_AIX_REALMEM
11585 {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
11586#endif
Fred Drakec9680921999-12-13 16:37:25 +000011587#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011588 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011589#endif
11590#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011591 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011592#endif
11593#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011594 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011595#endif
11596#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011597 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011598#endif
11599#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011600 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011601#endif
11602#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011603 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011604#endif
11605#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011606 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011607#endif
11608#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011609 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011610#endif
11611#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011612 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011613#endif
11614#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011615 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011616#endif
11617#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011618 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011619#endif
11620#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011621 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011622#endif
11623#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011624 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011625#endif
11626#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011627 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011628#endif
11629#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011630 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011631#endif
11632#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011633 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011634#endif
11635#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011636 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011637#endif
11638#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011639 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011640#endif
11641#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011642 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011643#endif
11644#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011645 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011646#endif
11647#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011648 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011649#endif
11650#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011651 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011652#endif
11653#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011654 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011655#endif
11656#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011657 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011658#endif
11659#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011660 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011661#endif
11662#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011663 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011664#endif
11665#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011666 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011667#endif
11668#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011669 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011670#endif
11671#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011672 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011673#endif
11674#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011675 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011676#endif
11677#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011678 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011679#endif
Fred Draked86ed291999-12-15 15:34:33 +000011680#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011681 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011682#endif
Fred Drakec9680921999-12-13 16:37:25 +000011683#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011684 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011685#endif
11686#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011687 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011688#endif
11689#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011690 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011691#endif
11692#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011693 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011694#endif
11695#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011696 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011697#endif
11698#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011699 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011700#endif
11701#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011702 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011703#endif
11704#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011705 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011706#endif
11707#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011708 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011709#endif
11710#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011711 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011712#endif
11713#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011714 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011715#endif
11716#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011717 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011718#endif
11719#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011720 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011721#endif
11722#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011723 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011724#endif
11725#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011726 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011727#endif
11728#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011729 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011730#endif
11731#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011732 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011733#endif
11734#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011735 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011736#endif
11737#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011738 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011739#endif
11740#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011741 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011742#endif
11743#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011744 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011745#endif
11746#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011747 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011748#endif
11749#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011750 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011751#endif
11752#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011753 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011754#endif
11755#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011756 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011757#endif
11758#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011759 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011760#endif
11761#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011762 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011763#endif
11764#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011765 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011766#endif
11767#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011768 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011769#endif
11770#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011771 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011772#endif
11773#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011774 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011775#endif
11776#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011777 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011778#endif
11779#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011780 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011781#endif
11782#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011783 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011784#endif
11785#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011786 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011787#endif
11788#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011789 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011790#endif
11791#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011792 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011793#endif
11794#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011795 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011796#endif
11797#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011798 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011799#endif
11800#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011801 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011802#endif
11803#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011804 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011805#endif
11806#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011807 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011808#endif
11809#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011810 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011811#endif
11812#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011813 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011814#endif
11815#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011816 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011817#endif
11818};
11819
11820static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011821conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011822{
11823 return conv_confname(arg, valuep, posix_constants_sysconf,
11824 sizeof(posix_constants_sysconf)
11825 / sizeof(struct constdef));
11826}
11827
Larry Hastings2f936352014-08-05 14:04:04 +100011828
11829/*[clinic input]
11830os.sysconf -> long
11831 name: sysconf_confname
11832 /
11833
11834Return an integer-valued system configuration variable.
11835[clinic start generated code]*/
11836
Larry Hastings2f936352014-08-05 14:04:04 +100011837static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011838os_sysconf_impl(PyObject *module, int name)
11839/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011840{
11841 long value;
11842
11843 errno = 0;
11844 value = sysconf(name);
11845 if (value == -1 && errno != 0)
11846 posix_error();
11847 return value;
11848}
11849#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011850
11851
Fred Drakebec628d1999-12-15 18:31:10 +000011852/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011853 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011854 * the exported dictionaries that are used to publish information about the
11855 * names available on the host platform.
11856 *
11857 * Sorting the table at runtime ensures that the table is properly ordered
11858 * when used, even for platforms we're not able to test on. It also makes
11859 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011860 */
Fred Drakebec628d1999-12-15 18:31:10 +000011861
11862static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011863cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011864{
11865 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011866 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011867 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011868 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011869
11870 return strcmp(c1->name, c2->name);
11871}
11872
11873static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011874setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011875 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011876{
Fred Drakebec628d1999-12-15 18:31:10 +000011877 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011878 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011879
11880 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11881 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011882 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011883 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011884
Barry Warsaw3155db32000-04-13 15:20:40 +000011885 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011886 PyObject *o = PyLong_FromLong(table[i].value);
11887 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11888 Py_XDECREF(o);
11889 Py_DECREF(d);
11890 return -1;
11891 }
11892 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011893 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011894 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011895}
11896
Fred Drakebec628d1999-12-15 18:31:10 +000011897/* Return -1 on failure, 0 on success. */
11898static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011899setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011900{
11901#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011902 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011903 sizeof(posix_constants_pathconf)
11904 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011905 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011906 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011907#endif
11908#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011909 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011910 sizeof(posix_constants_confstr)
11911 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011912 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011913 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011914#endif
11915#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011916 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011917 sizeof(posix_constants_sysconf)
11918 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011919 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011920 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011921#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011922 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011923}
Fred Draked86ed291999-12-15 15:34:33 +000011924
11925
Larry Hastings2f936352014-08-05 14:04:04 +100011926/*[clinic input]
11927os.abort
11928
11929Abort the interpreter immediately.
11930
11931This function 'dumps core' or otherwise fails in the hardest way possible
11932on the hosting operating system. This function never returns.
11933[clinic start generated code]*/
11934
Larry Hastings2f936352014-08-05 14:04:04 +100011935static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011936os_abort_impl(PyObject *module)
11937/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011938{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011939 abort();
11940 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011941#ifndef __clang__
11942 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11943 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11944 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011945 Py_FatalError("abort() called from Python code didn't abort!");
11946 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011947#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011948}
Fred Drakebec628d1999-12-15 18:31:10 +000011949
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011950#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011951/* Grab ShellExecute dynamically from shell32 */
11952static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011953static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11954 LPCWSTR, INT);
11955static int
11956check_ShellExecute()
11957{
11958 HINSTANCE hShell32;
11959
11960 /* only recheck */
11961 if (-1 == has_ShellExecute) {
11962 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011963 /* Security note: this call is not vulnerable to "DLL hijacking".
11964 SHELL32 is part of "KnownDLLs" and so Windows always load
11965 the system SHELL32.DLL, even if there is another SHELL32.DLL
11966 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011967 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011968 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011969 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11970 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011971 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011972 } else {
11973 has_ShellExecute = 0;
11974 }
Tony Roberts4860f012019-02-02 18:16:42 +010011975 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011976 }
11977 return has_ShellExecute;
11978}
11979
11980
Steve Dowercc16be82016-09-08 10:35:16 -070011981/*[clinic input]
11982os.startfile
11983 filepath: path_t
11984 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011985
Steve Dowercc16be82016-09-08 10:35:16 -070011986Start a file with its associated application.
11987
11988When "operation" is not specified or "open", this acts like
11989double-clicking the file in Explorer, or giving the file name as an
11990argument to the DOS "start" command: the file is opened with whatever
11991application (if any) its extension is associated.
11992When another "operation" is given, it specifies what should be done with
11993the file. A typical operation is "print".
11994
11995startfile returns as soon as the associated application is launched.
11996There is no option to wait for the application to close, and no way
11997to retrieve the application's exit status.
11998
11999The filepath is relative to the current directory. If you want to use
12000an absolute path, make sure the first character is not a slash ("/");
12001the underlying Win32 ShellExecute function doesn't work if it is.
12002[clinic start generated code]*/
12003
12004static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020012005os_startfile_impl(PyObject *module, path_t *filepath,
12006 const Py_UNICODE *operation)
Serhiy Storchaka279f4462019-09-14 12:24:05 +030012007/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
Steve Dowercc16be82016-09-08 10:35:16 -070012008{
12009 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012010
12011 if(!check_ShellExecute()) {
12012 /* If the OS doesn't have ShellExecute, return a
12013 NotImplementedError. */
12014 return PyErr_Format(PyExc_NotImplementedError,
12015 "startfile not available on this platform");
12016 }
12017
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012018 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080012019 return NULL;
12020 }
12021
Victor Stinner8c62be82010-05-06 00:08:46 +000012022 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070012023 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080012024 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000012025 Py_END_ALLOW_THREADS
12026
Victor Stinner8c62be82010-05-06 00:08:46 +000012027 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070012028 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020012029 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012030 }
Steve Dowercc16be82016-09-08 10:35:16 -070012031 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000012032}
Larry Hastings2f936352014-08-05 14:04:04 +100012033#endif /* MS_WINDOWS */
12034
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012035
Martin v. Löwis438b5342002-12-27 10:16:42 +000012036#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100012037/*[clinic input]
12038os.getloadavg
12039
12040Return average recent system load information.
12041
12042Return the number of processes in the system run queue averaged over
12043the last 1, 5, and 15 minutes as a tuple of three floats.
12044Raises OSError if the load average was unobtainable.
12045[clinic start generated code]*/
12046
Larry Hastings2f936352014-08-05 14:04:04 +100012047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012048os_getloadavg_impl(PyObject *module)
12049/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000012050{
12051 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000012052 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000012053 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
12054 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000012055 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000012056 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000012057}
Larry Hastings2f936352014-08-05 14:04:04 +100012058#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000012059
Larry Hastings2f936352014-08-05 14:04:04 +100012060
12061/*[clinic input]
12062os.device_encoding
12063 fd: int
12064
12065Return a string describing the encoding of a terminal's file descriptor.
12066
12067The file descriptor must be attached to a terminal.
12068If the device is not a terminal, return None.
12069[clinic start generated code]*/
12070
Larry Hastings2f936352014-08-05 14:04:04 +100012071static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012072os_device_encoding_impl(PyObject *module, int fd)
12073/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012074{
Brett Cannonefb00c02012-02-29 18:31:31 -050012075 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000012076}
12077
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012078
Larry Hastings2f936352014-08-05 14:04:04 +100012079#ifdef HAVE_SETRESUID
12080/*[clinic input]
12081os.setresuid
12082
12083 ruid: uid_t
12084 euid: uid_t
12085 suid: uid_t
12086 /
12087
12088Set the current process's real, effective, and saved user ids.
12089[clinic start generated code]*/
12090
Larry Hastings2f936352014-08-05 14:04:04 +100012091static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012092os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
12093/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012094{
Victor Stinner8c62be82010-05-06 00:08:46 +000012095 if (setresuid(ruid, euid, suid) < 0)
12096 return posix_error();
12097 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012098}
Larry Hastings2f936352014-08-05 14:04:04 +100012099#endif /* HAVE_SETRESUID */
12100
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012101
12102#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012103/*[clinic input]
12104os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012105
Larry Hastings2f936352014-08-05 14:04:04 +100012106 rgid: gid_t
12107 egid: gid_t
12108 sgid: gid_t
12109 /
12110
12111Set the current process's real, effective, and saved group ids.
12112[clinic start generated code]*/
12113
Larry Hastings2f936352014-08-05 14:04:04 +100012114static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012115os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12116/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012117{
Victor Stinner8c62be82010-05-06 00:08:46 +000012118 if (setresgid(rgid, egid, sgid) < 0)
12119 return posix_error();
12120 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012121}
Larry Hastings2f936352014-08-05 14:04:04 +100012122#endif /* HAVE_SETRESGID */
12123
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012124
12125#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100012126/*[clinic input]
12127os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012128
Larry Hastings2f936352014-08-05 14:04:04 +100012129Return a tuple of the current process's real, effective, and saved user ids.
12130[clinic start generated code]*/
12131
Larry Hastings2f936352014-08-05 14:04:04 +100012132static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012133os_getresuid_impl(PyObject *module)
12134/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012135{
Victor Stinner8c62be82010-05-06 00:08:46 +000012136 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012137 if (getresuid(&ruid, &euid, &suid) < 0)
12138 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012139 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
12140 _PyLong_FromUid(euid),
12141 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012142}
Larry Hastings2f936352014-08-05 14:04:04 +100012143#endif /* HAVE_GETRESUID */
12144
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012145
12146#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012147/*[clinic input]
12148os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012149
Larry Hastings2f936352014-08-05 14:04:04 +100012150Return a tuple of the current process's real, effective, and saved group ids.
12151[clinic start generated code]*/
12152
Larry Hastings2f936352014-08-05 14:04:04 +100012153static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012154os_getresgid_impl(PyObject *module)
12155/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012156{
12157 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012158 if (getresgid(&rgid, &egid, &sgid) < 0)
12159 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012160 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
12161 _PyLong_FromGid(egid),
12162 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012163}
Larry Hastings2f936352014-08-05 14:04:04 +100012164#endif /* HAVE_GETRESGID */
12165
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012166
Benjamin Peterson9428d532011-09-14 11:45:52 -040012167#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100012168/*[clinic input]
12169os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040012170
Larry Hastings2f936352014-08-05 14:04:04 +100012171 path: path_t(allow_fd=True)
12172 attribute: path_t
12173 *
12174 follow_symlinks: bool = True
12175
12176Return the value of extended attribute attribute on path.
12177
BNMetricsb9427072018-11-02 15:20:19 +000012178path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012179If follow_symlinks is False, and the last element of the path is a symbolic
12180 link, getxattr will examine the symbolic link itself instead of the file
12181 the link points to.
12182
12183[clinic start generated code]*/
12184
Larry Hastings2f936352014-08-05 14:04:04 +100012185static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012186os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012187 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012188/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012189{
12190 Py_ssize_t i;
12191 PyObject *buffer = NULL;
12192
12193 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12194 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012195
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012196 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12197 return NULL;
12198 }
12199
Larry Hastings9cf065c2012-06-22 16:30:09 -070012200 for (i = 0; ; i++) {
12201 void *ptr;
12202 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012203 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012204 Py_ssize_t buffer_size = buffer_sizes[i];
12205 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012206 path_error(path);
12207 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012208 }
12209 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12210 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012211 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012212 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012213
Larry Hastings9cf065c2012-06-22 16:30:09 -070012214 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012215 if (path->fd >= 0)
12216 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012217 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012218 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012219 else
Larry Hastings2f936352014-08-05 14:04:04 +100012220 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012221 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012222
Larry Hastings9cf065c2012-06-22 16:30:09 -070012223 if (result < 0) {
12224 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012225 if (errno == ERANGE)
12226 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012227 path_error(path);
12228 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012229 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012230
Larry Hastings9cf065c2012-06-22 16:30:09 -070012231 if (result != buffer_size) {
12232 /* Can only shrink. */
12233 _PyBytes_Resize(&buffer, result);
12234 }
12235 break;
12236 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012237
Larry Hastings9cf065c2012-06-22 16:30:09 -070012238 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012239}
12240
Larry Hastings2f936352014-08-05 14:04:04 +100012241
12242/*[clinic input]
12243os.setxattr
12244
12245 path: path_t(allow_fd=True)
12246 attribute: path_t
12247 value: Py_buffer
12248 flags: int = 0
12249 *
12250 follow_symlinks: bool = True
12251
12252Set extended attribute attribute on path to value.
12253
BNMetricsb9427072018-11-02 15:20:19 +000012254path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012255If follow_symlinks is False, and the last element of the path is a symbolic
12256 link, setxattr will modify the symbolic link itself instead of the file
12257 the link points to.
12258
12259[clinic start generated code]*/
12260
Benjamin Peterson799bd802011-08-31 22:15:17 -040012261static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012262os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012263 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012264/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012265{
Larry Hastings2f936352014-08-05 14:04:04 +100012266 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012267
Larry Hastings2f936352014-08-05 14:04:04 +100012268 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012269 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012270
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012271 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12272 value->buf, value->len, flags) < 0) {
12273 return NULL;
12274 }
12275
Benjamin Peterson799bd802011-08-31 22:15:17 -040012276 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012277 if (path->fd > -1)
12278 result = fsetxattr(path->fd, attribute->narrow,
12279 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012280 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012281 result = setxattr(path->narrow, attribute->narrow,
12282 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012283 else
Larry Hastings2f936352014-08-05 14:04:04 +100012284 result = lsetxattr(path->narrow, attribute->narrow,
12285 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012286 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012287
Larry Hastings9cf065c2012-06-22 16:30:09 -070012288 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012289 path_error(path);
12290 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012291 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012292
Larry Hastings2f936352014-08-05 14:04:04 +100012293 Py_RETURN_NONE;
12294}
12295
12296
12297/*[clinic input]
12298os.removexattr
12299
12300 path: path_t(allow_fd=True)
12301 attribute: path_t
12302 *
12303 follow_symlinks: bool = True
12304
12305Remove extended attribute attribute on path.
12306
BNMetricsb9427072018-11-02 15:20:19 +000012307path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012308If follow_symlinks is False, and the last element of the path is a symbolic
12309 link, removexattr will modify the symbolic link itself instead of the file
12310 the link points to.
12311
12312[clinic start generated code]*/
12313
Larry Hastings2f936352014-08-05 14:04:04 +100012314static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012315os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012316 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012317/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012318{
12319 ssize_t result;
12320
12321 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12322 return NULL;
12323
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012324 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12325 return NULL;
12326 }
12327
Larry Hastings2f936352014-08-05 14:04:04 +100012328 Py_BEGIN_ALLOW_THREADS;
12329 if (path->fd > -1)
12330 result = fremovexattr(path->fd, attribute->narrow);
12331 else if (follow_symlinks)
12332 result = removexattr(path->narrow, attribute->narrow);
12333 else
12334 result = lremovexattr(path->narrow, attribute->narrow);
12335 Py_END_ALLOW_THREADS;
12336
12337 if (result) {
12338 return path_error(path);
12339 }
12340
12341 Py_RETURN_NONE;
12342}
12343
12344
12345/*[clinic input]
12346os.listxattr
12347
12348 path: path_t(allow_fd=True, nullable=True) = None
12349 *
12350 follow_symlinks: bool = True
12351
12352Return a list of extended attributes on path.
12353
BNMetricsb9427072018-11-02 15:20:19 +000012354path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012355if path is None, listxattr will examine the current directory.
12356If follow_symlinks is False, and the last element of the path is a symbolic
12357 link, listxattr will examine the symbolic link itself instead of the file
12358 the link points to.
12359[clinic start generated code]*/
12360
Larry Hastings2f936352014-08-05 14:04:04 +100012361static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012362os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012363/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012364{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012365 Py_ssize_t i;
12366 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012367 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012368 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012369
Larry Hastings2f936352014-08-05 14:04:04 +100012370 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012371 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012372
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012373 if (PySys_Audit("os.listxattr", "(O)",
12374 path->object ? path->object : Py_None) < 0) {
12375 return NULL;
12376 }
12377
Larry Hastings2f936352014-08-05 14:04:04 +100012378 name = path->narrow ? path->narrow : ".";
12379
Larry Hastings9cf065c2012-06-22 16:30:09 -070012380 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012381 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012382 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012383 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012384 Py_ssize_t buffer_size = buffer_sizes[i];
12385 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012386 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012387 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012388 break;
12389 }
12390 buffer = PyMem_MALLOC(buffer_size);
12391 if (!buffer) {
12392 PyErr_NoMemory();
12393 break;
12394 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012395
Larry Hastings9cf065c2012-06-22 16:30:09 -070012396 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012397 if (path->fd > -1)
12398 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012399 else if (follow_symlinks)
12400 length = listxattr(name, buffer, buffer_size);
12401 else
12402 length = llistxattr(name, buffer, buffer_size);
12403 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012404
Larry Hastings9cf065c2012-06-22 16:30:09 -070012405 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012406 if (errno == ERANGE) {
12407 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012408 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012409 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012410 }
Larry Hastings2f936352014-08-05 14:04:04 +100012411 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012412 break;
12413 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012414
Larry Hastings9cf065c2012-06-22 16:30:09 -070012415 result = PyList_New(0);
12416 if (!result) {
12417 goto exit;
12418 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012419
Larry Hastings9cf065c2012-06-22 16:30:09 -070012420 end = buffer + length;
12421 for (trace = start = buffer; trace != end; trace++) {
12422 if (!*trace) {
12423 int error;
12424 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12425 trace - start);
12426 if (!attribute) {
12427 Py_DECREF(result);
12428 result = NULL;
12429 goto exit;
12430 }
12431 error = PyList_Append(result, attribute);
12432 Py_DECREF(attribute);
12433 if (error) {
12434 Py_DECREF(result);
12435 result = NULL;
12436 goto exit;
12437 }
12438 start = trace + 1;
12439 }
12440 }
12441 break;
12442 }
12443exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012444 if (buffer)
12445 PyMem_FREE(buffer);
12446 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012447}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012448#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012449
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012450
Larry Hastings2f936352014-08-05 14:04:04 +100012451/*[clinic input]
12452os.urandom
12453
12454 size: Py_ssize_t
12455 /
12456
12457Return a bytes object containing random bytes suitable for cryptographic use.
12458[clinic start generated code]*/
12459
Larry Hastings2f936352014-08-05 14:04:04 +100012460static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012461os_urandom_impl(PyObject *module, Py_ssize_t size)
12462/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012463{
12464 PyObject *bytes;
12465 int result;
12466
Georg Brandl2fb477c2012-02-21 00:33:36 +010012467 if (size < 0)
12468 return PyErr_Format(PyExc_ValueError,
12469 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012470 bytes = PyBytes_FromStringAndSize(NULL, size);
12471 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012472 return NULL;
12473
Victor Stinnere66987e2016-09-06 16:33:52 -070012474 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012475 if (result == -1) {
12476 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012477 return NULL;
12478 }
Larry Hastings2f936352014-08-05 14:04:04 +100012479 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012480}
12481
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012482#ifdef HAVE_MEMFD_CREATE
12483/*[clinic input]
12484os.memfd_create
12485
12486 name: FSConverter
12487 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12488
12489[clinic start generated code]*/
12490
12491static PyObject *
12492os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12493/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12494{
12495 int fd;
12496 const char *bytes = PyBytes_AS_STRING(name);
12497 Py_BEGIN_ALLOW_THREADS
12498 fd = memfd_create(bytes, flags);
12499 Py_END_ALLOW_THREADS
12500 if (fd == -1) {
12501 return PyErr_SetFromErrno(PyExc_OSError);
12502 }
12503 return PyLong_FromLong(fd);
12504}
12505#endif
12506
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012507/* Terminal size querying */
12508
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012509PyDoc_STRVAR(TerminalSize_docstring,
12510 "A tuple of (columns, lines) for holding terminal window size");
12511
12512static PyStructSequence_Field TerminalSize_fields[] = {
12513 {"columns", "width of the terminal window in characters"},
12514 {"lines", "height of the terminal window in characters"},
12515 {NULL, NULL}
12516};
12517
12518static PyStructSequence_Desc TerminalSize_desc = {
12519 "os.terminal_size",
12520 TerminalSize_docstring,
12521 TerminalSize_fields,
12522 2,
12523};
12524
12525#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012526/*[clinic input]
12527os.get_terminal_size
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012528
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012529 fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
12530 /
12531
12532Return the size of the terminal window as (columns, lines).
12533
12534The optional argument fd (default standard output) specifies
12535which file descriptor should be queried.
12536
12537If the file descriptor is not connected to a terminal, an OSError
12538is thrown.
12539
12540This function will only be defined if an implementation is
12541available for this system.
12542
12543shutil.get_terminal_size is the high-level function which should
12544normally be used, os.get_terminal_size is the low-level implementation.
12545[clinic start generated code]*/
12546
12547static PyObject *
12548os_get_terminal_size_impl(PyObject *module, int fd)
12549/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012550{
12551 int columns, lines;
12552 PyObject *termsize;
12553
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012554 /* Under some conditions stdout may not be connected and
12555 * fileno(stdout) may point to an invalid file descriptor. For example
12556 * GUI apps don't have valid standard streams by default.
12557 *
12558 * If this happens, and the optional fd argument is not present,
12559 * the ioctl below will fail returning EBADF. This is what we want.
12560 */
12561
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012562#ifdef TERMSIZE_USE_IOCTL
12563 {
12564 struct winsize w;
12565 if (ioctl(fd, TIOCGWINSZ, &w))
12566 return PyErr_SetFromErrno(PyExc_OSError);
12567 columns = w.ws_col;
12568 lines = w.ws_row;
12569 }
12570#endif /* TERMSIZE_USE_IOCTL */
12571
12572#ifdef TERMSIZE_USE_CONIO
12573 {
12574 DWORD nhandle;
12575 HANDLE handle;
12576 CONSOLE_SCREEN_BUFFER_INFO csbi;
12577 switch (fd) {
12578 case 0: nhandle = STD_INPUT_HANDLE;
12579 break;
12580 case 1: nhandle = STD_OUTPUT_HANDLE;
12581 break;
12582 case 2: nhandle = STD_ERROR_HANDLE;
12583 break;
12584 default:
12585 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12586 }
12587 handle = GetStdHandle(nhandle);
12588 if (handle == NULL)
12589 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12590 if (handle == INVALID_HANDLE_VALUE)
12591 return PyErr_SetFromWindowsErr(0);
12592
12593 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12594 return PyErr_SetFromWindowsErr(0);
12595
12596 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12597 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12598 }
12599#endif /* TERMSIZE_USE_CONIO */
12600
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012601 PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080012602 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012603 if (termsize == NULL)
12604 return NULL;
12605 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12606 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12607 if (PyErr_Occurred()) {
12608 Py_DECREF(termsize);
12609 return NULL;
12610 }
12611 return termsize;
12612}
12613#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12614
Larry Hastings2f936352014-08-05 14:04:04 +100012615
12616/*[clinic input]
12617os.cpu_count
12618
Charles-François Natali80d62e62015-08-13 20:37:08 +010012619Return the number of CPUs in the system; return None if indeterminable.
12620
12621This number is not equivalent to the number of CPUs the current process can
12622use. The number of usable CPUs can be obtained with
12623``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012624[clinic start generated code]*/
12625
Larry Hastings2f936352014-08-05 14:04:04 +100012626static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012627os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012628/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012629{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012630 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012631#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010012632 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012633#elif defined(__hpux)
12634 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12635#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12636 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
pxinwr3405e052020-08-07 13:21:52 +080012637#elif defined(__VXWORKS__)
12638 ncpu = _Py_popcount32(vxCpuEnabledGet());
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012639#elif defined(__DragonFly__) || \
12640 defined(__OpenBSD__) || \
12641 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012642 defined(__NetBSD__) || \
12643 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012644 int mib[2];
12645 size_t len = sizeof(ncpu);
12646 mib[0] = CTL_HW;
12647 mib[1] = HW_NCPU;
12648 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12649 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012650#endif
12651 if (ncpu >= 1)
12652 return PyLong_FromLong(ncpu);
12653 else
12654 Py_RETURN_NONE;
12655}
12656
Victor Stinnerdaf45552013-08-28 00:53:59 +020012657
Larry Hastings2f936352014-08-05 14:04:04 +100012658/*[clinic input]
12659os.get_inheritable -> bool
12660
12661 fd: int
12662 /
12663
12664Get the close-on-exe flag of the specified file descriptor.
12665[clinic start generated code]*/
12666
Larry Hastings2f936352014-08-05 14:04:04 +100012667static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012668os_get_inheritable_impl(PyObject *module, int fd)
12669/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012670{
Steve Dower8fc89802015-04-12 00:26:27 -040012671 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012672 _Py_BEGIN_SUPPRESS_IPH
12673 return_value = _Py_get_inheritable(fd);
12674 _Py_END_SUPPRESS_IPH
12675 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012676}
12677
12678
12679/*[clinic input]
12680os.set_inheritable
12681 fd: int
12682 inheritable: int
12683 /
12684
12685Set the inheritable flag of the specified file descriptor.
12686[clinic start generated code]*/
12687
Larry Hastings2f936352014-08-05 14:04:04 +100012688static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012689os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12690/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012691{
Steve Dower8fc89802015-04-12 00:26:27 -040012692 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012693
Steve Dower8fc89802015-04-12 00:26:27 -040012694 _Py_BEGIN_SUPPRESS_IPH
12695 result = _Py_set_inheritable(fd, inheritable, NULL);
12696 _Py_END_SUPPRESS_IPH
12697 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012698 return NULL;
12699 Py_RETURN_NONE;
12700}
12701
12702
12703#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012704/*[clinic input]
12705os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012706 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012707 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012708
Larry Hastings2f936352014-08-05 14:04:04 +100012709Get the close-on-exe flag of the specified file descriptor.
12710[clinic start generated code]*/
12711
Larry Hastings2f936352014-08-05 14:04:04 +100012712static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012713os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012714/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012715{
12716 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012717
12718 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12719 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012720 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012721 }
12722
Larry Hastings2f936352014-08-05 14:04:04 +100012723 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012724}
12725
Victor Stinnerdaf45552013-08-28 00:53:59 +020012726
Larry Hastings2f936352014-08-05 14:04:04 +100012727/*[clinic input]
12728os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012729 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012730 inheritable: bool
12731 /
12732
12733Set the inheritable flag of the specified handle.
12734[clinic start generated code]*/
12735
Larry Hastings2f936352014-08-05 14:04:04 +100012736static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012737os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012738 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012739/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012740{
12741 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012742 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12743 PyErr_SetFromWindowsErr(0);
12744 return NULL;
12745 }
12746 Py_RETURN_NONE;
12747}
Larry Hastings2f936352014-08-05 14:04:04 +100012748#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012749
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012750#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012751/*[clinic input]
12752os.get_blocking -> bool
12753 fd: int
12754 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012755
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012756Get the blocking mode of the file descriptor.
12757
12758Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12759[clinic start generated code]*/
12760
12761static int
12762os_get_blocking_impl(PyObject *module, int fd)
12763/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012764{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012765 int blocking;
12766
Steve Dower8fc89802015-04-12 00:26:27 -040012767 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012768 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012769 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012770 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012771}
12772
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012773/*[clinic input]
12774os.set_blocking
12775 fd: int
12776 blocking: bool(accept={int})
12777 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012778
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012779Set the blocking mode of the specified file descriptor.
12780
12781Set the O_NONBLOCK flag if blocking is False,
12782clear the O_NONBLOCK flag otherwise.
12783[clinic start generated code]*/
12784
12785static PyObject *
12786os_set_blocking_impl(PyObject *module, int fd, int blocking)
12787/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012788{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012789 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012790
Steve Dower8fc89802015-04-12 00:26:27 -040012791 _Py_BEGIN_SUPPRESS_IPH
12792 result = _Py_set_blocking(fd, blocking);
12793 _Py_END_SUPPRESS_IPH
12794 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012795 return NULL;
12796 Py_RETURN_NONE;
12797}
12798#endif /* !MS_WINDOWS */
12799
12800
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012801/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080012802class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012803[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080012804/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012805
12806typedef struct {
12807 PyObject_HEAD
12808 PyObject *name;
12809 PyObject *path;
12810 PyObject *stat;
12811 PyObject *lstat;
12812#ifdef MS_WINDOWS
12813 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012814 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012815 int got_file_index;
12816#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012817#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012818 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012819#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012820 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012821 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012822#endif
12823} DirEntry;
12824
Eddie Elizondob3966632019-11-05 07:16:14 -080012825static PyObject *
12826_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
12827{
12828 PyErr_Format(PyExc_TypeError,
12829 "cannot create '%.100s' instances", _PyType_Name(type));
12830 return NULL;
12831}
12832
Victor Stinner6036e442015-03-08 01:58:04 +010012833static void
12834DirEntry_dealloc(DirEntry *entry)
12835{
Eddie Elizondob3966632019-11-05 07:16:14 -080012836 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010012837 Py_XDECREF(entry->name);
12838 Py_XDECREF(entry->path);
12839 Py_XDECREF(entry->stat);
12840 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080012841 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
12842 free_func(entry);
12843 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010012844}
12845
12846/* Forward reference */
12847static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012848DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
12849 int follow_symlinks, unsigned short mode_bits);
Victor Stinner6036e442015-03-08 01:58:04 +010012850
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012851/*[clinic input]
12852os.DirEntry.is_symlink -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020012853 defining_class: defining_class
12854 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012855
12856Return True if the entry is a symbolic link; cached per entry.
12857[clinic start generated code]*/
12858
Victor Stinner6036e442015-03-08 01:58:04 +010012859static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012860os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
12861/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012862{
12863#ifdef MS_WINDOWS
12864 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012865#elif defined(HAVE_DIRENT_D_TYPE)
12866 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012867 if (self->d_type != DT_UNKNOWN)
12868 return self->d_type == DT_LNK;
12869 else
Victor Stinner97f33c32020-05-14 18:05:58 +020012870 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012871#else
12872 /* POSIX without d_type */
Victor Stinner97f33c32020-05-14 18:05:58 +020012873 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012874#endif
12875}
12876
12877static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020012878DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
Victor Stinner6036e442015-03-08 01:58:04 +010012879{
12880 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012881 STRUCT_STAT st;
12882 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012883
12884#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012885 if (!PyUnicode_FSDecoder(self->path, &ub))
12886 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030012887#if USE_UNICODE_WCHAR_CACHE
12888_Py_COMP_DIAG_PUSH
12889_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012890 const wchar_t *path = PyUnicode_AsUnicode(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030012891_Py_COMP_DIAG_POP
12892#else /* USE_UNICODE_WCHAR_CACHE */
12893 wchar_t *path = PyUnicode_AsWideCharString(ub, NULL);
12894 Py_DECREF(ub);
12895#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010012896#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012897 if (!PyUnicode_FSConverter(self->path, &ub))
12898 return NULL;
12899 const char *path = PyBytes_AS_STRING(ub);
12900 if (self->dir_fd != DEFAULT_DIR_FD) {
12901#ifdef HAVE_FSTATAT
12902 result = fstatat(self->dir_fd, path, &st,
12903 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12904#else
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030012905 Py_DECREF(ub);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012906 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12907 return NULL;
12908#endif /* HAVE_FSTATAT */
12909 }
12910 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012911#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012912 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012913 if (follow_symlinks)
12914 result = STAT(path, &st);
12915 else
12916 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012917 }
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030012918#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE
12919 PyMem_Free(path);
12920#else /* USE_UNICODE_WCHAR_CACHE */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012921 Py_DECREF(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030012922#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010012923
12924 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012925 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012926
Victor Stinner97f33c32020-05-14 18:05:58 +020012927 return _pystat_fromstructstat(module, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010012928}
12929
12930static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020012931DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
Victor Stinner6036e442015-03-08 01:58:04 +010012932{
12933 if (!self->lstat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020012934 PyObject *module = PyType_GetModule(defining_class);
Victor Stinner6036e442015-03-08 01:58:04 +010012935#ifdef MS_WINDOWS
Victor Stinner97f33c32020-05-14 18:05:58 +020012936 self->lstat = _pystat_fromstructstat(module, &self->win32_lstat);
Victor Stinner6036e442015-03-08 01:58:04 +010012937#else /* POSIX */
Victor Stinner97f33c32020-05-14 18:05:58 +020012938 self->lstat = DirEntry_fetch_stat(module, self, 0);
Victor Stinner6036e442015-03-08 01:58:04 +010012939#endif
12940 }
12941 Py_XINCREF(self->lstat);
12942 return self->lstat;
12943}
12944
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012945/*[clinic input]
12946os.DirEntry.stat
Victor Stinner97f33c32020-05-14 18:05:58 +020012947 defining_class: defining_class
12948 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012949 *
12950 follow_symlinks: bool = True
12951
12952Return stat_result object for the entry; cached per entry.
12953[clinic start generated code]*/
12954
Victor Stinner6036e442015-03-08 01:58:04 +010012955static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020012956os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
12957 int follow_symlinks)
12958/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012959{
Victor Stinner97f33c32020-05-14 18:05:58 +020012960 if (!follow_symlinks) {
12961 return DirEntry_get_lstat(defining_class, self);
12962 }
Victor Stinner6036e442015-03-08 01:58:04 +010012963
12964 if (!self->stat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020012965 int result = os_DirEntry_is_symlink_impl(self, defining_class);
12966 if (result == -1) {
Victor Stinner6036e442015-03-08 01:58:04 +010012967 return NULL;
Victor Stinner97f33c32020-05-14 18:05:58 +020012968 }
12969 if (result) {
12970 PyObject *module = PyType_GetModule(defining_class);
12971 self->stat = DirEntry_fetch_stat(module, self, 1);
12972 }
12973 else {
12974 self->stat = DirEntry_get_lstat(defining_class, self);
12975 }
Victor Stinner6036e442015-03-08 01:58:04 +010012976 }
12977
12978 Py_XINCREF(self->stat);
12979 return self->stat;
12980}
12981
Victor Stinner6036e442015-03-08 01:58:04 +010012982/* Set exception and return -1 on error, 0 for False, 1 for True */
12983static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012984DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
12985 int follow_symlinks, unsigned short mode_bits)
Victor Stinner6036e442015-03-08 01:58:04 +010012986{
12987 PyObject *stat = NULL;
12988 PyObject *st_mode = NULL;
12989 long mode;
12990 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012991#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012992 int is_symlink;
12993 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012994#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012995#ifdef MS_WINDOWS
12996 unsigned long dir_bits;
12997#endif
12998
12999#ifdef MS_WINDOWS
13000 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
13001 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010013002#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013003 is_symlink = self->d_type == DT_LNK;
13004 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
13005#endif
13006
Victor Stinner35a97c02015-03-08 02:59:09 +010013007#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013008 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010013009#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020013010 stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010013011 if (!stat) {
13012 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
13013 /* If file doesn't exist (anymore), then return False
13014 (i.e., say it's not a file/directory) */
13015 PyErr_Clear();
13016 return 0;
13017 }
13018 goto error;
13019 }
Victor Stinner97f33c32020-05-14 18:05:58 +020013020 _posixstate* state = get_posix_state(PyType_GetModule(defining_class));
13021 st_mode = PyObject_GetAttr(stat, state->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010013022 if (!st_mode)
13023 goto error;
13024
13025 mode = PyLong_AsLong(st_mode);
13026 if (mode == -1 && PyErr_Occurred())
13027 goto error;
13028 Py_CLEAR(st_mode);
13029 Py_CLEAR(stat);
13030 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010013031#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013032 }
13033 else if (is_symlink) {
13034 assert(mode_bits != S_IFLNK);
13035 result = 0;
13036 }
13037 else {
13038 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
13039#ifdef MS_WINDOWS
13040 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
13041 if (mode_bits == S_IFDIR)
13042 result = dir_bits != 0;
13043 else
13044 result = dir_bits == 0;
13045#else /* POSIX */
13046 if (mode_bits == S_IFDIR)
13047 result = self->d_type == DT_DIR;
13048 else
13049 result = self->d_type == DT_REG;
13050#endif
13051 }
Victor Stinner35a97c02015-03-08 02:59:09 +010013052#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013053
13054 return result;
13055
13056error:
13057 Py_XDECREF(st_mode);
13058 Py_XDECREF(stat);
13059 return -1;
13060}
13061
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013062/*[clinic input]
13063os.DirEntry.is_dir -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013064 defining_class: defining_class
13065 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013066 *
13067 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010013068
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013069Return True if the entry is a directory; cached per entry.
13070[clinic start generated code]*/
13071
13072static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013073os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
13074 int follow_symlinks)
13075/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013076{
Victor Stinner97f33c32020-05-14 18:05:58 +020013077 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010013078}
13079
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013080/*[clinic input]
13081os.DirEntry.is_file -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013082 defining_class: defining_class
13083 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013084 *
13085 follow_symlinks: bool = True
13086
13087Return True if the entry is a file; cached per entry.
13088[clinic start generated code]*/
13089
13090static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013091os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
13092 int follow_symlinks)
13093/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013094{
Victor Stinner97f33c32020-05-14 18:05:58 +020013095 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010013096}
13097
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013098/*[clinic input]
13099os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010013100
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013101Return inode of the entry; cached per entry.
13102[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013103
13104static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013105os_DirEntry_inode_impl(DirEntry *self)
13106/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013107{
13108#ifdef MS_WINDOWS
13109 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013110 PyObject *unicode;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013111 STRUCT_STAT stat;
13112 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010013113
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013114 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010013115 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013116#if USE_UNICODE_WCHAR_CACHE
13117_Py_COMP_DIAG_PUSH
13118_Py_COMP_DIAG_IGNORE_DEPR_DECLS
13119 const wchar_t *path = PyUnicode_AsUnicode(unicode);
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013120 result = LSTAT(path, &stat);
13121 Py_DECREF(unicode);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013122_Py_COMP_DIAG_POP
13123#else /* USE_UNICODE_WCHAR_CACHE */
13124 wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL);
13125 Py_DECREF(unicode);
13126 result = LSTAT(path, &stat);
13127 PyMem_Free(path);
13128#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013129
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013130 if (result != 0)
13131 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013132
13133 self->win32_file_index = stat.st_ino;
13134 self->got_file_index = 1;
13135 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010013136 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
13137 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010013138#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020013139 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
13140 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010013141#endif
13142}
13143
13144static PyObject *
13145DirEntry_repr(DirEntry *self)
13146{
13147 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13148}
13149
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013150/*[clinic input]
13151os.DirEntry.__fspath__
13152
13153Returns the path for the entry.
13154[clinic start generated code]*/
13155
Brett Cannon96881cd2016-06-10 14:37:21 -070013156static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013157os_DirEntry___fspath___impl(DirEntry *self)
13158/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070013159{
13160 Py_INCREF(self->path);
13161 return self->path;
13162}
13163
Victor Stinner6036e442015-03-08 01:58:04 +010013164static PyMemberDef DirEntry_members[] = {
13165 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13166 "the entry's base filename, relative to scandir() \"path\" argument"},
13167 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13168 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13169 {NULL}
13170};
13171
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013172#include "clinic/posixmodule.c.h"
13173
Victor Stinner6036e442015-03-08 01:58:04 +010013174static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013175 OS_DIRENTRY_IS_DIR_METHODDEF
13176 OS_DIRENTRY_IS_FILE_METHODDEF
13177 OS_DIRENTRY_IS_SYMLINK_METHODDEF
13178 OS_DIRENTRY_STAT_METHODDEF
13179 OS_DIRENTRY_INODE_METHODDEF
13180 OS_DIRENTRY___FSPATH___METHODDEF
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013181 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
13182 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Victor Stinner6036e442015-03-08 01:58:04 +010013183 {NULL}
13184};
13185
Eddie Elizondob3966632019-11-05 07:16:14 -080013186static PyType_Slot DirEntryType_slots[] = {
13187 {Py_tp_new, _disabled_new},
13188 {Py_tp_dealloc, DirEntry_dealloc},
13189 {Py_tp_repr, DirEntry_repr},
13190 {Py_tp_methods, DirEntry_methods},
13191 {Py_tp_members, DirEntry_members},
13192 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010013193};
13194
Eddie Elizondob3966632019-11-05 07:16:14 -080013195static PyType_Spec DirEntryType_spec = {
13196 MODNAME ".DirEntry",
13197 sizeof(DirEntry),
13198 0,
13199 Py_TPFLAGS_DEFAULT,
13200 DirEntryType_slots
13201};
13202
13203
Victor Stinner6036e442015-03-08 01:58:04 +010013204#ifdef MS_WINDOWS
13205
13206static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013207join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010013208{
13209 Py_ssize_t path_len;
13210 Py_ssize_t size;
13211 wchar_t *result;
13212 wchar_t ch;
13213
13214 if (!path_wide) { /* Default arg: "." */
13215 path_wide = L".";
13216 path_len = 1;
13217 }
13218 else {
13219 path_len = wcslen(path_wide);
13220 }
13221
13222 /* The +1's are for the path separator and the NUL */
13223 size = path_len + 1 + wcslen(filename) + 1;
13224 result = PyMem_New(wchar_t, size);
13225 if (!result) {
13226 PyErr_NoMemory();
13227 return NULL;
13228 }
13229 wcscpy(result, path_wide);
13230 if (path_len > 0) {
13231 ch = result[path_len - 1];
13232 if (ch != SEP && ch != ALTSEP && ch != L':')
13233 result[path_len++] = SEP;
13234 wcscpy(result + path_len, filename);
13235 }
13236 return result;
13237}
13238
13239static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013240DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
Victor Stinner6036e442015-03-08 01:58:04 +010013241{
13242 DirEntry *entry;
13243 BY_HANDLE_FILE_INFORMATION file_info;
13244 ULONG reparse_tag;
13245 wchar_t *joined_path;
13246
Victor Stinner1c2fa782020-05-10 11:05:29 +020013247 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013248 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013249 if (!entry)
13250 return NULL;
13251 entry->name = NULL;
13252 entry->path = NULL;
13253 entry->stat = NULL;
13254 entry->lstat = NULL;
13255 entry->got_file_index = 0;
13256
13257 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13258 if (!entry->name)
13259 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013260 if (path->narrow) {
13261 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13262 if (!entry->name)
13263 goto error;
13264 }
Victor Stinner6036e442015-03-08 01:58:04 +010013265
13266 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13267 if (!joined_path)
13268 goto error;
13269
13270 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13271 PyMem_Free(joined_path);
13272 if (!entry->path)
13273 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013274 if (path->narrow) {
13275 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13276 if (!entry->path)
13277 goto error;
13278 }
Victor Stinner6036e442015-03-08 01:58:04 +010013279
Steve Dowercc16be82016-09-08 10:35:16 -070013280 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013281 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13282
13283 return (PyObject *)entry;
13284
13285error:
13286 Py_DECREF(entry);
13287 return NULL;
13288}
13289
13290#else /* POSIX */
13291
13292static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013293join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013294{
13295 Py_ssize_t path_len;
13296 Py_ssize_t size;
13297 char *result;
13298
13299 if (!path_narrow) { /* Default arg: "." */
13300 path_narrow = ".";
13301 path_len = 1;
13302 }
13303 else {
13304 path_len = strlen(path_narrow);
13305 }
13306
13307 if (filename_len == -1)
13308 filename_len = strlen(filename);
13309
13310 /* The +1's are for the path separator and the NUL */
13311 size = path_len + 1 + filename_len + 1;
13312 result = PyMem_New(char, size);
13313 if (!result) {
13314 PyErr_NoMemory();
13315 return NULL;
13316 }
13317 strcpy(result, path_narrow);
13318 if (path_len > 0 && result[path_len - 1] != '/')
13319 result[path_len++] = '/';
13320 strcpy(result + path_len, filename);
13321 return result;
13322}
13323
13324static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013325DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13326 Py_ssize_t name_len, ino_t d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013327#ifdef HAVE_DIRENT_D_TYPE
13328 , unsigned char d_type
13329#endif
13330 )
Victor Stinner6036e442015-03-08 01:58:04 +010013331{
13332 DirEntry *entry;
13333 char *joined_path;
13334
Victor Stinner1c2fa782020-05-10 11:05:29 +020013335 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013336 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013337 if (!entry)
13338 return NULL;
13339 entry->name = NULL;
13340 entry->path = NULL;
13341 entry->stat = NULL;
13342 entry->lstat = NULL;
13343
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013344 if (path->fd != -1) {
13345 entry->dir_fd = path->fd;
13346 joined_path = NULL;
13347 }
13348 else {
13349 entry->dir_fd = DEFAULT_DIR_FD;
13350 joined_path = join_path_filename(path->narrow, name, name_len);
13351 if (!joined_path)
13352 goto error;
13353 }
Victor Stinner6036e442015-03-08 01:58:04 +010013354
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013355 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013356 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013357 if (joined_path)
13358 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013359 }
13360 else {
13361 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013362 if (joined_path)
13363 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013364 }
13365 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013366 if (!entry->name)
13367 goto error;
13368
13369 if (path->fd != -1) {
13370 entry->path = entry->name;
13371 Py_INCREF(entry->path);
13372 }
13373 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013374 goto error;
13375
Victor Stinner35a97c02015-03-08 02:59:09 +010013376#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013377 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013378#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013379 entry->d_ino = d_ino;
13380
13381 return (PyObject *)entry;
13382
13383error:
13384 Py_XDECREF(entry);
13385 return NULL;
13386}
13387
13388#endif
13389
13390
13391typedef struct {
13392 PyObject_HEAD
13393 path_t path;
13394#ifdef MS_WINDOWS
13395 HANDLE handle;
13396 WIN32_FIND_DATAW file_data;
13397 int first_time;
13398#else /* POSIX */
13399 DIR *dirp;
13400#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013401#ifdef HAVE_FDOPENDIR
13402 int fd;
13403#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013404} ScandirIterator;
13405
13406#ifdef MS_WINDOWS
13407
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013408static int
13409ScandirIterator_is_closed(ScandirIterator *iterator)
13410{
13411 return iterator->handle == INVALID_HANDLE_VALUE;
13412}
13413
Victor Stinner6036e442015-03-08 01:58:04 +010013414static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013415ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013416{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013417 HANDLE handle = iterator->handle;
13418
13419 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013420 return;
13421
Victor Stinner6036e442015-03-08 01:58:04 +010013422 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013423 Py_BEGIN_ALLOW_THREADS
13424 FindClose(handle);
13425 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013426}
13427
13428static PyObject *
13429ScandirIterator_iternext(ScandirIterator *iterator)
13430{
13431 WIN32_FIND_DATAW *file_data = &iterator->file_data;
13432 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013433 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013434
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013435 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013436 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013437 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013438
13439 while (1) {
13440 if (!iterator->first_time) {
13441 Py_BEGIN_ALLOW_THREADS
13442 success = FindNextFileW(iterator->handle, file_data);
13443 Py_END_ALLOW_THREADS
13444 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013445 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013446 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013447 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013448 break;
13449 }
13450 }
13451 iterator->first_time = 0;
13452
13453 /* Skip over . and .. */
13454 if (wcscmp(file_data->cFileName, L".") != 0 &&
Victor Stinner1c2fa782020-05-10 11:05:29 +020013455 wcscmp(file_data->cFileName, L"..") != 0)
13456 {
13457 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13458 entry = DirEntry_from_find_data(module, &iterator->path, file_data);
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013459 if (!entry)
13460 break;
13461 return entry;
13462 }
Victor Stinner6036e442015-03-08 01:58:04 +010013463
13464 /* Loop till we get a non-dot directory or finish iterating */
13465 }
13466
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013467 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013468 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013469 return NULL;
13470}
13471
13472#else /* POSIX */
13473
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013474static int
13475ScandirIterator_is_closed(ScandirIterator *iterator)
13476{
13477 return !iterator->dirp;
13478}
13479
Victor Stinner6036e442015-03-08 01:58:04 +010013480static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013481ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013482{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013483 DIR *dirp = iterator->dirp;
13484
13485 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013486 return;
13487
Victor Stinner6036e442015-03-08 01:58:04 +010013488 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013489 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013490#ifdef HAVE_FDOPENDIR
13491 if (iterator->path.fd != -1)
13492 rewinddir(dirp);
13493#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013494 closedir(dirp);
13495 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013496 return;
13497}
13498
13499static PyObject *
13500ScandirIterator_iternext(ScandirIterator *iterator)
13501{
13502 struct dirent *direntp;
13503 Py_ssize_t name_len;
13504 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013505 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013506
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013507 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013508 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013509 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013510
13511 while (1) {
13512 errno = 0;
13513 Py_BEGIN_ALLOW_THREADS
13514 direntp = readdir(iterator->dirp);
13515 Py_END_ALLOW_THREADS
13516
13517 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013518 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013519 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013520 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013521 break;
13522 }
13523
13524 /* Skip over . and .. */
13525 name_len = NAMLEN(direntp);
13526 is_dot = direntp->d_name[0] == '.' &&
13527 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
13528 if (!is_dot) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020013529 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13530 entry = DirEntry_from_posix_info(module,
13531 &iterator->path, direntp->d_name,
13532 name_len, direntp->d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013533#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner1c2fa782020-05-10 11:05:29 +020013534 , direntp->d_type
Victor Stinner35a97c02015-03-08 02:59:09 +010013535#endif
13536 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013537 if (!entry)
13538 break;
13539 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013540 }
13541
13542 /* Loop till we get a non-dot directory or finish iterating */
13543 }
13544
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013545 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013546 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013547 return NULL;
13548}
13549
13550#endif
13551
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013552static PyObject *
13553ScandirIterator_close(ScandirIterator *self, PyObject *args)
13554{
13555 ScandirIterator_closedir(self);
13556 Py_RETURN_NONE;
13557}
13558
13559static PyObject *
13560ScandirIterator_enter(PyObject *self, PyObject *args)
13561{
13562 Py_INCREF(self);
13563 return self;
13564}
13565
13566static PyObject *
13567ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13568{
13569 ScandirIterator_closedir(self);
13570 Py_RETURN_NONE;
13571}
13572
Victor Stinner6036e442015-03-08 01:58:04 +010013573static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013574ScandirIterator_finalize(ScandirIterator *iterator)
13575{
13576 PyObject *error_type, *error_value, *error_traceback;
13577
13578 /* Save the current exception, if any. */
13579 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13580
13581 if (!ScandirIterator_is_closed(iterator)) {
13582 ScandirIterator_closedir(iterator);
13583
13584 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13585 "unclosed scandir iterator %R", iterator)) {
13586 /* Spurious errors can appear at shutdown */
13587 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13588 PyErr_WriteUnraisable((PyObject *) iterator);
13589 }
13590 }
13591 }
13592
Victor Stinner7bfa4092016-03-23 00:43:54 +010013593 path_cleanup(&iterator->path);
13594
13595 /* Restore the saved exception. */
13596 PyErr_Restore(error_type, error_value, error_traceback);
13597}
13598
13599static void
Victor Stinner6036e442015-03-08 01:58:04 +010013600ScandirIterator_dealloc(ScandirIterator *iterator)
13601{
Eddie Elizondob3966632019-11-05 07:16:14 -080013602 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010013603 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13604 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013605
Eddie Elizondob3966632019-11-05 07:16:14 -080013606 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13607 free_func(iterator);
13608 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013609}
13610
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013611static PyMethodDef ScandirIterator_methods[] = {
13612 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13613 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13614 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13615 {NULL}
13616};
13617
Eddie Elizondob3966632019-11-05 07:16:14 -080013618static PyType_Slot ScandirIteratorType_slots[] = {
13619 {Py_tp_new, _disabled_new},
13620 {Py_tp_dealloc, ScandirIterator_dealloc},
13621 {Py_tp_finalize, ScandirIterator_finalize},
13622 {Py_tp_iter, PyObject_SelfIter},
13623 {Py_tp_iternext, ScandirIterator_iternext},
13624 {Py_tp_methods, ScandirIterator_methods},
13625 {0, 0},
13626};
13627
13628static PyType_Spec ScandirIteratorType_spec = {
13629 MODNAME ".ScandirIterator",
13630 sizeof(ScandirIterator),
13631 0,
Victor Stinner97f33c32020-05-14 18:05:58 +020013632 // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
13633 // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
Eddie Elizondob3966632019-11-05 07:16:14 -080013634 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
13635 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010013636};
13637
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013638/*[clinic input]
13639os.scandir
13640
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013641 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013642
13643Return an iterator of DirEntry objects for given path.
13644
BNMetricsb9427072018-11-02 15:20:19 +000013645path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013646is bytes, the names of yielded DirEntry objects will also be bytes; in
13647all other circumstances they will be str.
13648
13649If path is None, uses the path='.'.
13650[clinic start generated code]*/
13651
Victor Stinner6036e442015-03-08 01:58:04 +010013652static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013653os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013654/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013655{
13656 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013657#ifdef MS_WINDOWS
13658 wchar_t *path_strW;
13659#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013660 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013661#ifdef HAVE_FDOPENDIR
13662 int fd = -1;
13663#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013664#endif
13665
Steve Dower60419a72019-06-24 08:42:54 -070013666 if (PySys_Audit("os.scandir", "O",
13667 path->object ? path->object : Py_None) < 0) {
13668 return NULL;
13669 }
13670
Hai Shif707d942020-03-16 21:15:01 +080013671 PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013672 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010013673 if (!iterator)
13674 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013675
13676#ifdef MS_WINDOWS
13677 iterator->handle = INVALID_HANDLE_VALUE;
13678#else
13679 iterator->dirp = NULL;
13680#endif
13681
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013682 /* Move the ownership to iterator->path */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013683 memcpy(&iterator->path, path, sizeof(path_t));
13684 memset(path, 0, sizeof(path_t));
Victor Stinner6036e442015-03-08 01:58:04 +010013685
13686#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013687 iterator->first_time = 1;
13688
13689 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13690 if (!path_strW)
13691 goto error;
13692
13693 Py_BEGIN_ALLOW_THREADS
13694 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13695 Py_END_ALLOW_THREADS
13696
13697 PyMem_Free(path_strW);
13698
13699 if (iterator->handle == INVALID_HANDLE_VALUE) {
13700 path_error(&iterator->path);
13701 goto error;
13702 }
13703#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013704 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013705#ifdef HAVE_FDOPENDIR
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013706 if (iterator->path.fd != -1) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013707 /* closedir() closes the FD, so we duplicate it */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013708 fd = _Py_dup(iterator->path.fd);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013709 if (fd == -1)
13710 goto error;
13711
13712 Py_BEGIN_ALLOW_THREADS
13713 iterator->dirp = fdopendir(fd);
13714 Py_END_ALLOW_THREADS
13715 }
13716 else
13717#endif
13718 {
13719 if (iterator->path.narrow)
13720 path_str = iterator->path.narrow;
13721 else
13722 path_str = ".";
13723
13724 Py_BEGIN_ALLOW_THREADS
13725 iterator->dirp = opendir(path_str);
13726 Py_END_ALLOW_THREADS
13727 }
Victor Stinner6036e442015-03-08 01:58:04 +010013728
13729 if (!iterator->dirp) {
13730 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013731#ifdef HAVE_FDOPENDIR
13732 if (fd != -1) {
13733 Py_BEGIN_ALLOW_THREADS
13734 close(fd);
13735 Py_END_ALLOW_THREADS
13736 }
13737#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013738 goto error;
13739 }
13740#endif
13741
13742 return (PyObject *)iterator;
13743
13744error:
13745 Py_DECREF(iterator);
13746 return NULL;
13747}
13748
Ethan Furman410ef8e2016-06-04 12:06:26 -070013749/*
13750 Return the file system path representation of the object.
13751
13752 If the object is str or bytes, then allow it to pass through with
13753 an incremented refcount. If the object defines __fspath__(), then
13754 return the result of that method. All other types raise a TypeError.
13755*/
13756PyObject *
13757PyOS_FSPath(PyObject *path)
13758{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013759 /* For error message reasons, this function is manually inlined in
13760 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013761 PyObject *func = NULL;
13762 PyObject *path_repr = NULL;
13763
13764 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13765 Py_INCREF(path);
13766 return path;
13767 }
13768
13769 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13770 if (NULL == func) {
13771 return PyErr_Format(PyExc_TypeError,
13772 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013773 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080013774 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070013775 }
13776
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013777 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013778 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013779 if (NULL == path_repr) {
13780 return NULL;
13781 }
13782
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013783 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13784 PyErr_Format(PyExc_TypeError,
13785 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080013786 "not %.200s", _PyType_Name(Py_TYPE(path)),
13787 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013788 Py_DECREF(path_repr);
13789 return NULL;
13790 }
13791
Ethan Furman410ef8e2016-06-04 12:06:26 -070013792 return path_repr;
13793}
13794
13795/*[clinic input]
13796os.fspath
13797
13798 path: object
13799
13800Return the file system path representation of the object.
13801
Brett Cannonb4f43e92016-06-09 14:32:08 -070013802If the object is str or bytes, then allow it to pass through as-is. If the
13803object defines __fspath__(), then return the result of that method. All other
13804types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013805[clinic start generated code]*/
13806
13807static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013808os_fspath_impl(PyObject *module, PyObject *path)
13809/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013810{
13811 return PyOS_FSPath(path);
13812}
Victor Stinner6036e442015-03-08 01:58:04 +010013813
Victor Stinner9b1f4742016-09-06 16:18:52 -070013814#ifdef HAVE_GETRANDOM_SYSCALL
13815/*[clinic input]
13816os.getrandom
13817
13818 size: Py_ssize_t
13819 flags: int=0
13820
13821Obtain a series of random bytes.
13822[clinic start generated code]*/
13823
13824static PyObject *
13825os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13826/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13827{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013828 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013829 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013830
13831 if (size < 0) {
13832 errno = EINVAL;
13833 return posix_error();
13834 }
13835
Victor Stinnerec2319c2016-09-20 23:00:59 +020013836 bytes = PyBytes_FromStringAndSize(NULL, size);
13837 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013838 PyErr_NoMemory();
13839 return NULL;
13840 }
13841
13842 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013843 n = syscall(SYS_getrandom,
13844 PyBytes_AS_STRING(bytes),
13845 PyBytes_GET_SIZE(bytes),
13846 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013847 if (n < 0 && errno == EINTR) {
13848 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013849 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013850 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013851
13852 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013853 continue;
13854 }
13855 break;
13856 }
13857
13858 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013859 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013860 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013861 }
13862
Victor Stinnerec2319c2016-09-20 23:00:59 +020013863 if (n != size) {
13864 _PyBytes_Resize(&bytes, n);
13865 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013866
13867 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013868
13869error:
13870 Py_DECREF(bytes);
13871 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013872}
13873#endif /* HAVE_GETRANDOM_SYSCALL */
13874
Steve Dower2438cdf2019-03-29 16:37:16 -070013875#ifdef MS_WINDOWS
13876/* bpo-36085: Helper functions for managing DLL search directories
13877 * on win32
13878 */
13879
13880typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13881typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13882
13883/*[clinic input]
13884os._add_dll_directory
13885
13886 path: path_t
13887
13888Add a path to the DLL search path.
13889
13890This search path is used when resolving dependencies for imported
13891extension modules (the module itself is resolved through sys.path),
13892and also by ctypes.
13893
13894Returns an opaque value that may be passed to os.remove_dll_directory
13895to remove this directory from the search path.
13896[clinic start generated code]*/
13897
13898static PyObject *
13899os__add_dll_directory_impl(PyObject *module, path_t *path)
13900/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13901{
13902 HMODULE hKernel32;
13903 PAddDllDirectory AddDllDirectory;
13904 DLL_DIRECTORY_COOKIE cookie = 0;
13905 DWORD err = 0;
13906
Saiyang Gou7514f4f2020-02-12 23:47:42 -080013907 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
13908 return NULL;
13909 }
13910
Steve Dower2438cdf2019-03-29 16:37:16 -070013911 /* For Windows 7, we have to load this. As this will be a fairly
13912 infrequent operation, just do it each time. Kernel32 is always
13913 loaded. */
13914 Py_BEGIN_ALLOW_THREADS
13915 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13916 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13917 hKernel32, "AddDllDirectory")) ||
13918 !(cookie = (*AddDllDirectory)(path->wide))) {
13919 err = GetLastError();
13920 }
13921 Py_END_ALLOW_THREADS
13922
13923 if (err) {
13924 return win32_error_object_err("add_dll_directory",
13925 path->object, err);
13926 }
13927
13928 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13929}
13930
13931/*[clinic input]
13932os._remove_dll_directory
13933
13934 cookie: object
13935
13936Removes a path from the DLL search path.
13937
13938The parameter is an opaque value that was returned from
13939os.add_dll_directory. You can only remove directories that you added
13940yourself.
13941[clinic start generated code]*/
13942
13943static PyObject *
13944os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13945/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13946{
13947 HMODULE hKernel32;
13948 PRemoveDllDirectory RemoveDllDirectory;
13949 DLL_DIRECTORY_COOKIE cookieValue;
13950 DWORD err = 0;
13951
13952 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13953 PyErr_SetString(PyExc_TypeError,
13954 "Provided cookie was not returned from os.add_dll_directory");
13955 return NULL;
13956 }
13957
13958 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13959 cookie, "DLL directory cookie");
13960
13961 /* For Windows 7, we have to load this. As this will be a fairly
13962 infrequent operation, just do it each time. Kernel32 is always
13963 loaded. */
13964 Py_BEGIN_ALLOW_THREADS
13965 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13966 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13967 hKernel32, "RemoveDllDirectory")) ||
13968 !(*RemoveDllDirectory)(cookieValue)) {
13969 err = GetLastError();
13970 }
13971 Py_END_ALLOW_THREADS
13972
13973 if (err) {
13974 return win32_error_object_err("remove_dll_directory",
13975 NULL, err);
13976 }
13977
13978 if (PyCapsule_SetName(cookie, NULL)) {
13979 return NULL;
13980 }
13981
13982 Py_RETURN_NONE;
13983}
13984
13985#endif
Larry Hastings31826802013-10-19 00:09:25 -070013986
Victor Stinner65a796e2020-04-01 18:49:29 +020013987
13988/* Only check if WIFEXITED is available: expect that it comes
13989 with WEXITSTATUS, WIFSIGNALED, etc.
13990
13991 os.waitstatus_to_exitcode() is implemented in C and not in Python, so
13992 subprocess can safely call it during late Python finalization without
13993 risking that used os attributes were set to None by _PyImport_Cleanup(). */
13994#if defined(WIFEXITED) || defined(MS_WINDOWS)
13995/*[clinic input]
13996os.waitstatus_to_exitcode
13997
Victor Stinner9bee32b2020-04-22 16:30:35 +020013998 status as status_obj: object
Victor Stinner65a796e2020-04-01 18:49:29 +020013999
14000Convert a wait status to an exit code.
14001
14002On Unix:
14003
14004* If WIFEXITED(status) is true, return WEXITSTATUS(status).
14005* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
14006* Otherwise, raise a ValueError.
14007
14008On Windows, return status shifted right by 8 bits.
14009
14010On Unix, if the process is being traced or if waitpid() was called with
14011WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
14012This function must not be called if WIFSTOPPED(status) is true.
14013[clinic start generated code]*/
14014
14015static PyObject *
Victor Stinner9bee32b2020-04-22 16:30:35 +020014016os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
14017/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
Victor Stinner65a796e2020-04-01 18:49:29 +020014018{
14019#ifndef MS_WINDOWS
Victor Stinner9bee32b2020-04-22 16:30:35 +020014020 int status = _PyLong_AsInt(status_obj);
14021 if (status == -1 && PyErr_Occurred()) {
14022 return NULL;
14023 }
14024
Victor Stinner65a796e2020-04-01 18:49:29 +020014025 WAIT_TYPE wait_status;
14026 WAIT_STATUS_INT(wait_status) = status;
14027 int exitcode;
14028 if (WIFEXITED(wait_status)) {
14029 exitcode = WEXITSTATUS(wait_status);
14030 /* Sanity check to provide warranty on the function behavior.
14031 It should not occur in practice */
14032 if (exitcode < 0) {
14033 PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
14034 return NULL;
14035 }
14036 }
14037 else if (WIFSIGNALED(wait_status)) {
14038 int signum = WTERMSIG(wait_status);
14039 /* Sanity check to provide warranty on the function behavior.
14040 It should not occurs in practice */
14041 if (signum <= 0) {
14042 PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
14043 return NULL;
14044 }
14045 exitcode = -signum;
14046 } else if (WIFSTOPPED(wait_status)) {
14047 /* Status only received if the process is being traced
14048 or if waitpid() was called with WUNTRACED option. */
14049 int signum = WSTOPSIG(wait_status);
14050 PyErr_Format(PyExc_ValueError,
14051 "process stopped by delivery of signal %i",
14052 signum);
14053 return NULL;
14054 }
14055 else {
14056 PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
14057 return NULL;
14058 }
14059 return PyLong_FromLong(exitcode);
14060#else
14061 /* Windows implementation: see os.waitpid() implementation
14062 which uses _cwait(). */
Victor Stinner9bee32b2020-04-22 16:30:35 +020014063 unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
14064 if (status == (unsigned long long)-1 && PyErr_Occurred()) {
14065 return NULL;
14066 }
14067
14068 unsigned long long exitcode = (status >> 8);
14069 /* ExitProcess() accepts an UINT type:
14070 reject exit code which doesn't fit in an UINT */
14071 if (exitcode > UINT_MAX) {
14072 PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
14073 return NULL;
14074 }
14075 return PyLong_FromUnsignedLong((unsigned long)exitcode);
Victor Stinner65a796e2020-04-01 18:49:29 +020014076#endif
14077}
14078#endif
14079
14080
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014081static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070014082
14083 OS_STAT_METHODDEF
14084 OS_ACCESS_METHODDEF
14085 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014086 OS_CHDIR_METHODDEF
14087 OS_CHFLAGS_METHODDEF
14088 OS_CHMOD_METHODDEF
14089 OS_FCHMOD_METHODDEF
14090 OS_LCHMOD_METHODDEF
14091 OS_CHOWN_METHODDEF
14092 OS_FCHOWN_METHODDEF
14093 OS_LCHOWN_METHODDEF
14094 OS_LCHFLAGS_METHODDEF
14095 OS_CHROOT_METHODDEF
14096 OS_CTERMID_METHODDEF
14097 OS_GETCWD_METHODDEF
14098 OS_GETCWDB_METHODDEF
14099 OS_LINK_METHODDEF
14100 OS_LISTDIR_METHODDEF
14101 OS_LSTAT_METHODDEF
14102 OS_MKDIR_METHODDEF
14103 OS_NICE_METHODDEF
14104 OS_GETPRIORITY_METHODDEF
14105 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014106 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030014107 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014108 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010014109 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014110 OS_RENAME_METHODDEF
14111 OS_REPLACE_METHODDEF
14112 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014113 OS_SYMLINK_METHODDEF
14114 OS_SYSTEM_METHODDEF
14115 OS_UMASK_METHODDEF
14116 OS_UNAME_METHODDEF
14117 OS_UNLINK_METHODDEF
14118 OS_REMOVE_METHODDEF
14119 OS_UTIME_METHODDEF
14120 OS_TIMES_METHODDEF
14121 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014122 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014123 OS_EXECV_METHODDEF
14124 OS_EXECVE_METHODDEF
14125 OS_SPAWNV_METHODDEF
14126 OS_SPAWNVE_METHODDEF
14127 OS_FORK1_METHODDEF
14128 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020014129 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014130 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14131 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14132 OS_SCHED_GETPARAM_METHODDEF
14133 OS_SCHED_GETSCHEDULER_METHODDEF
14134 OS_SCHED_RR_GET_INTERVAL_METHODDEF
14135 OS_SCHED_SETPARAM_METHODDEF
14136 OS_SCHED_SETSCHEDULER_METHODDEF
14137 OS_SCHED_YIELD_METHODDEF
14138 OS_SCHED_SETAFFINITY_METHODDEF
14139 OS_SCHED_GETAFFINITY_METHODDEF
14140 OS_OPENPTY_METHODDEF
14141 OS_FORKPTY_METHODDEF
14142 OS_GETEGID_METHODDEF
14143 OS_GETEUID_METHODDEF
14144 OS_GETGID_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014145 OS_GETGROUPLIST_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014146 OS_GETGROUPS_METHODDEF
14147 OS_GETPID_METHODDEF
14148 OS_GETPGRP_METHODDEF
14149 OS_GETPPID_METHODDEF
14150 OS_GETUID_METHODDEF
14151 OS_GETLOGIN_METHODDEF
14152 OS_KILL_METHODDEF
14153 OS_KILLPG_METHODDEF
14154 OS_PLOCK_METHODDEF
Steve Dowercc16be82016-09-08 10:35:16 -070014155 OS_STARTFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014156 OS_SETUID_METHODDEF
14157 OS_SETEUID_METHODDEF
14158 OS_SETREUID_METHODDEF
14159 OS_SETGID_METHODDEF
14160 OS_SETEGID_METHODDEF
14161 OS_SETREGID_METHODDEF
14162 OS_SETGROUPS_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014163 OS_INITGROUPS_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014164 OS_GETPGID_METHODDEF
14165 OS_SETPGRP_METHODDEF
14166 OS_WAIT_METHODDEF
14167 OS_WAIT3_METHODDEF
14168 OS_WAIT4_METHODDEF
14169 OS_WAITID_METHODDEF
14170 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080014171 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014172 OS_GETSID_METHODDEF
14173 OS_SETSID_METHODDEF
14174 OS_SETPGID_METHODDEF
14175 OS_TCGETPGRP_METHODDEF
14176 OS_TCSETPGRP_METHODDEF
14177 OS_OPEN_METHODDEF
14178 OS_CLOSE_METHODDEF
14179 OS_CLOSERANGE_METHODDEF
14180 OS_DEVICE_ENCODING_METHODDEF
14181 OS_DUP_METHODDEF
14182 OS_DUP2_METHODDEF
14183 OS_LOCKF_METHODDEF
14184 OS_LSEEK_METHODDEF
14185 OS_READ_METHODDEF
14186 OS_READV_METHODDEF
14187 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014188 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014189 OS_WRITE_METHODDEF
14190 OS_WRITEV_METHODDEF
14191 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014192 OS_PWRITEV_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014193 OS_SENDFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014194 OS_FSTAT_METHODDEF
14195 OS_ISATTY_METHODDEF
14196 OS_PIPE_METHODDEF
14197 OS_PIPE2_METHODDEF
14198 OS_MKFIFO_METHODDEF
14199 OS_MKNOD_METHODDEF
14200 OS_MAJOR_METHODDEF
14201 OS_MINOR_METHODDEF
14202 OS_MAKEDEV_METHODDEF
14203 OS_FTRUNCATE_METHODDEF
14204 OS_TRUNCATE_METHODDEF
14205 OS_POSIX_FALLOCATE_METHODDEF
14206 OS_POSIX_FADVISE_METHODDEF
14207 OS_PUTENV_METHODDEF
14208 OS_UNSETENV_METHODDEF
14209 OS_STRERROR_METHODDEF
14210 OS_FCHDIR_METHODDEF
14211 OS_FSYNC_METHODDEF
14212 OS_SYNC_METHODDEF
14213 OS_FDATASYNC_METHODDEF
14214 OS_WCOREDUMP_METHODDEF
14215 OS_WIFCONTINUED_METHODDEF
14216 OS_WIFSTOPPED_METHODDEF
14217 OS_WIFSIGNALED_METHODDEF
14218 OS_WIFEXITED_METHODDEF
14219 OS_WEXITSTATUS_METHODDEF
14220 OS_WTERMSIG_METHODDEF
14221 OS_WSTOPSIG_METHODDEF
14222 OS_FSTATVFS_METHODDEF
14223 OS_STATVFS_METHODDEF
14224 OS_CONFSTR_METHODDEF
14225 OS_SYSCONF_METHODDEF
14226 OS_FPATHCONF_METHODDEF
14227 OS_PATHCONF_METHODDEF
14228 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030014229 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014230 OS__GETDISKUSAGE_METHODDEF
14231 OS__GETFINALPATHNAME_METHODDEF
14232 OS__GETVOLUMEPATHNAME_METHODDEF
14233 OS_GETLOADAVG_METHODDEF
14234 OS_URANDOM_METHODDEF
14235 OS_SETRESUID_METHODDEF
14236 OS_SETRESGID_METHODDEF
14237 OS_GETRESUID_METHODDEF
14238 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000014239
Larry Hastings2f936352014-08-05 14:04:04 +100014240 OS_GETXATTR_METHODDEF
14241 OS_SETXATTR_METHODDEF
14242 OS_REMOVEXATTR_METHODDEF
14243 OS_LISTXATTR_METHODDEF
14244
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014245 OS_GET_TERMINAL_SIZE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014246 OS_CPU_COUNT_METHODDEF
14247 OS_GET_INHERITABLE_METHODDEF
14248 OS_SET_INHERITABLE_METHODDEF
14249 OS_GET_HANDLE_INHERITABLE_METHODDEF
14250 OS_SET_HANDLE_INHERITABLE_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014251 OS_GET_BLOCKING_METHODDEF
14252 OS_SET_BLOCKING_METHODDEF
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014253 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070014254 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070014255 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014256 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070014257 OS__ADD_DLL_DIRECTORY_METHODDEF
14258 OS__REMOVE_DLL_DIRECTORY_METHODDEF
Victor Stinner65a796e2020-04-01 18:49:29 +020014259 OS_WAITSTATUS_TO_EXITCODE_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014260 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014261};
14262
Barry Warsaw4a342091996-12-19 23:50:02 +000014263static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014264all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000014265{
Guido van Rossum94f6f721999-01-06 18:42:14 +000014266#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014267 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014268#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014269#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014270 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014271#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014272#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014273 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014274#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014275#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014276 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014277#endif
Fred Drakec9680921999-12-13 16:37:25 +000014278#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014279 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000014280#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014281#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014282 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014283#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014284#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014285 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014286#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014287#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014288 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014289#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014290#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014291 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014292#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014293#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014294 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014295#endif
14296#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014297 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014298#endif
14299#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014300 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014301#endif
14302#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014303 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014304#endif
14305#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014306 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014307#endif
14308#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014309 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014310#endif
14311#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014312 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014313#endif
14314#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014315 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014316#endif
14317#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014318 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014319#endif
14320#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014321 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014322#endif
14323#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014324 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014325#endif
14326#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014327 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014328#endif
14329#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014330 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014331#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014332#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014333 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014334#endif
14335#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014336 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014337#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014338#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014339 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014340#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014341#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014342 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014343#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014344#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014345#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014346 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014347#endif
14348#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014349 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014350#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014351#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014352#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014353 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014354#endif
14355#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014356 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014357#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014358#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014359 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014360#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014361#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014362 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014363#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014364#ifdef O_TMPFILE
14365 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14366#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014367#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014368 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014369#endif
14370#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014371 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014372#endif
14373#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014374 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014375#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014376#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014377 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014378#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014379#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014380 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014381#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014382
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014383
Jesus Cea94363612012-06-22 18:32:07 +020014384#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014385 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014386#endif
14387#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014388 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014389#endif
14390
Tim Peters5aa91602002-01-30 05:46:57 +000014391/* MS Windows */
14392#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014393 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014394 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014395#endif
14396#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000014397 /* Optimize for short life (keep in memory). */
14398 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014399 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014400#endif
14401#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000014402 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014403 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014404#endif
14405#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000014406 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014407 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014408#endif
14409#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014410 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014411 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014412#endif
14413
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014414/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014415#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014416 /* Send a SIGIO signal whenever input or output
14417 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014418 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014419#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014420#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014421 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014422 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014423#endif
14424#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000014425 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014426 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014427#endif
14428#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000014429 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014430 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014431#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014432#ifdef O_NOLINKS
14433 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014434 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014435#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014436#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014437 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014438 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014439#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000014440
Victor Stinner8c62be82010-05-06 00:08:46 +000014441 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014442#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014443 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014444#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014445#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014446 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014447#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014448#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014449 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014450#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014451#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014452 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014453#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014454#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014455 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014456#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014457#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014458 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014459#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014460#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014461 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014462#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014463#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014464 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014465#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014466#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014467 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014468#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014469#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014470 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014471#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014472#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014473 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014474#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014475#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014476 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014477#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014478#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014479 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014480#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014481#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014482 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014483#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014484#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014485 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014486#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014487#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014488 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014489#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014490#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014491 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014492#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014493
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000014494 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014495#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014496 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014497#endif /* ST_RDONLY */
14498#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014499 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014500#endif /* ST_NOSUID */
14501
doko@ubuntu.comca616a22013-12-08 15:23:07 +010014502 /* GNU extensions */
14503#ifdef ST_NODEV
14504 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
14505#endif /* ST_NODEV */
14506#ifdef ST_NOEXEC
14507 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
14508#endif /* ST_NOEXEC */
14509#ifdef ST_SYNCHRONOUS
14510 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
14511#endif /* ST_SYNCHRONOUS */
14512#ifdef ST_MANDLOCK
14513 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
14514#endif /* ST_MANDLOCK */
14515#ifdef ST_WRITE
14516 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
14517#endif /* ST_WRITE */
14518#ifdef ST_APPEND
14519 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
14520#endif /* ST_APPEND */
14521#ifdef ST_NOATIME
14522 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
14523#endif /* ST_NOATIME */
14524#ifdef ST_NODIRATIME
14525 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
14526#endif /* ST_NODIRATIME */
14527#ifdef ST_RELATIME
14528 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
14529#endif /* ST_RELATIME */
14530
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014531 /* FreeBSD sendfile() constants */
14532#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014533 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014534#endif
14535#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014536 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014537#endif
14538#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014539 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014540#endif
14541
Ross Lagerwall7807c352011-03-17 20:20:30 +020014542 /* constants for posix_fadvise */
14543#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014544 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014545#endif
14546#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014547 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014548#endif
14549#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014550 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014551#endif
14552#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014553 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014554#endif
14555#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014556 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014557#endif
14558#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014559 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014560#endif
14561
14562 /* constants for waitid */
14563#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014564 if (PyModule_AddIntMacro(m, P_PID)) return -1;
14565 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
14566 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080014567#ifdef P_PIDFD
14568 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
14569#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014570#endif
14571#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014572 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014573#endif
14574#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014575 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014576#endif
14577#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014578 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014579#endif
14580#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014581 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014582#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014583#ifdef CLD_KILLED
14584 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
14585#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014586#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014587 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014588#endif
14589#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014590 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014591#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014592#ifdef CLD_STOPPED
14593 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
14594#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014595#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014596 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014597#endif
14598
14599 /* constants for lockf */
14600#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014601 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014602#endif
14603#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014604 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014605#endif
14606#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014607 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014608#endif
14609#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014610 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014611#endif
14612
Pablo Galindo4defba32018-01-27 16:16:37 +000014613#ifdef RWF_DSYNC
14614 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14615#endif
14616#ifdef RWF_HIPRI
14617 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14618#endif
14619#ifdef RWF_SYNC
14620 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14621#endif
14622#ifdef RWF_NOWAIT
14623 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14624#endif
YoSTEALTH76ef2552020-05-27 15:32:22 -060014625#ifdef RWF_APPEND
14626 if (PyModule_AddIntConstant(m, "RWF_APPEND", RWF_APPEND)) return -1;
14627#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000014628
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014629/* constants for posix_spawn */
14630#ifdef HAVE_POSIX_SPAWN
14631 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14632 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14633 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14634#endif
14635
pxinwrf2d7ac72019-05-21 18:46:37 +080014636#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014637 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14638 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014639 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014640#endif
14641#ifdef HAVE_SPAWNV
14642 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014643 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014644#endif
14645
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014646#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014647#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014648 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014649#endif
14650#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014651 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014652#endif
14653#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014654 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014655#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014656#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014657 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014658#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014659#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014660 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014661#endif
14662#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014663 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014664#endif
14665#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014666 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014667#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014668#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014669 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014670#endif
14671#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014672 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014673#endif
14674#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014675 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014676#endif
14677#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014678 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014679#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014680#endif
14681
Benjamin Peterson9428d532011-09-14 11:45:52 -040014682#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014683 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
14684 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
14685 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040014686#endif
14687
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014688#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014689 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014690#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014691#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014692 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014693#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014694#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014695 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014696#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014697#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014698 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014699#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014700#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014701 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014702#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014703#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014704 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014705#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014706#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014707 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014708#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010014709#if HAVE_DECL_RTLD_MEMBER
14710 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
14711#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020014712
Victor Stinner9b1f4742016-09-06 16:18:52 -070014713#ifdef HAVE_GETRANDOM_SYSCALL
14714 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
14715 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
14716#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014717#ifdef HAVE_MEMFD_CREATE
14718 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
14719 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
14720#ifdef MFD_HUGETLB
14721 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014722#endif
14723#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014724 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014725#endif
14726#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014727 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014728#endif
14729#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014730 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014731#endif
14732#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014733 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014734#endif
14735#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014736 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014737#endif
14738#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014739 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014740#endif
14741#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014742 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014743#endif
14744#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014745 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014746#endif
14747#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014748 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014749#endif
14750#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014751 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014752#endif
14753#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014754 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014755#endif
14756#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014757 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014758#endif
14759#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014760 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014761#endif
14762#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014763 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
14764#endif
14765#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070014766
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014767#if defined(__APPLE__)
14768 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
14769#endif
14770
Steve Dower2438cdf2019-03-29 16:37:16 -070014771#ifdef MS_WINDOWS
14772 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
14773 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
14774 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
14775 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
14776 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
14777#endif
14778
Victor Stinner8c62be82010-05-06 00:08:46 +000014779 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000014780}
14781
14782
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014783static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014784
14785#ifdef HAVE_FACCESSAT
14786 "HAVE_FACCESSAT",
14787#endif
14788
14789#ifdef HAVE_FCHDIR
14790 "HAVE_FCHDIR",
14791#endif
14792
14793#ifdef HAVE_FCHMOD
14794 "HAVE_FCHMOD",
14795#endif
14796
14797#ifdef HAVE_FCHMODAT
14798 "HAVE_FCHMODAT",
14799#endif
14800
14801#ifdef HAVE_FCHOWN
14802 "HAVE_FCHOWN",
14803#endif
14804
Larry Hastings00964ed2013-08-12 13:49:30 -040014805#ifdef HAVE_FCHOWNAT
14806 "HAVE_FCHOWNAT",
14807#endif
14808
Larry Hastings9cf065c2012-06-22 16:30:09 -070014809#ifdef HAVE_FEXECVE
14810 "HAVE_FEXECVE",
14811#endif
14812
14813#ifdef HAVE_FDOPENDIR
14814 "HAVE_FDOPENDIR",
14815#endif
14816
Georg Brandl306336b2012-06-24 12:55:33 +020014817#ifdef HAVE_FPATHCONF
14818 "HAVE_FPATHCONF",
14819#endif
14820
Larry Hastings9cf065c2012-06-22 16:30:09 -070014821#ifdef HAVE_FSTATAT
14822 "HAVE_FSTATAT",
14823#endif
14824
14825#ifdef HAVE_FSTATVFS
14826 "HAVE_FSTATVFS",
14827#endif
14828
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014829#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014830 "HAVE_FTRUNCATE",
14831#endif
14832
Larry Hastings9cf065c2012-06-22 16:30:09 -070014833#ifdef HAVE_FUTIMENS
14834 "HAVE_FUTIMENS",
14835#endif
14836
14837#ifdef HAVE_FUTIMES
14838 "HAVE_FUTIMES",
14839#endif
14840
14841#ifdef HAVE_FUTIMESAT
14842 "HAVE_FUTIMESAT",
14843#endif
14844
14845#ifdef HAVE_LINKAT
14846 "HAVE_LINKAT",
14847#endif
14848
14849#ifdef HAVE_LCHFLAGS
14850 "HAVE_LCHFLAGS",
14851#endif
14852
14853#ifdef HAVE_LCHMOD
14854 "HAVE_LCHMOD",
14855#endif
14856
14857#ifdef HAVE_LCHOWN
14858 "HAVE_LCHOWN",
14859#endif
14860
14861#ifdef HAVE_LSTAT
14862 "HAVE_LSTAT",
14863#endif
14864
14865#ifdef HAVE_LUTIMES
14866 "HAVE_LUTIMES",
14867#endif
14868
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014869#ifdef HAVE_MEMFD_CREATE
14870 "HAVE_MEMFD_CREATE",
14871#endif
14872
Larry Hastings9cf065c2012-06-22 16:30:09 -070014873#ifdef HAVE_MKDIRAT
14874 "HAVE_MKDIRAT",
14875#endif
14876
14877#ifdef HAVE_MKFIFOAT
14878 "HAVE_MKFIFOAT",
14879#endif
14880
14881#ifdef HAVE_MKNODAT
14882 "HAVE_MKNODAT",
14883#endif
14884
14885#ifdef HAVE_OPENAT
14886 "HAVE_OPENAT",
14887#endif
14888
14889#ifdef HAVE_READLINKAT
14890 "HAVE_READLINKAT",
14891#endif
14892
14893#ifdef HAVE_RENAMEAT
14894 "HAVE_RENAMEAT",
14895#endif
14896
14897#ifdef HAVE_SYMLINKAT
14898 "HAVE_SYMLINKAT",
14899#endif
14900
14901#ifdef HAVE_UNLINKAT
14902 "HAVE_UNLINKAT",
14903#endif
14904
14905#ifdef HAVE_UTIMENSAT
14906 "HAVE_UTIMENSAT",
14907#endif
14908
14909#ifdef MS_WINDOWS
14910 "MS_WINDOWS",
14911#endif
14912
14913 NULL
14914};
14915
14916
Victor Stinner1c2fa782020-05-10 11:05:29 +020014917static int
14918posixmodule_exec(PyObject *m)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014919{
Victor Stinner97f33c32020-05-14 18:05:58 +020014920 _posixstate *state = get_posix_state(m);
Tim Peters5aa91602002-01-30 05:46:57 +000014921
Victor Stinner8c62be82010-05-06 00:08:46 +000014922 /* Initialize environ dictionary */
Victor Stinner97f33c32020-05-14 18:05:58 +020014923 PyObject *v = convertenviron();
Victor Stinner8c62be82010-05-06 00:08:46 +000014924 Py_XINCREF(v);
14925 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014926 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014927 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014928
Victor Stinner8c62be82010-05-06 00:08:46 +000014929 if (all_ins(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020014930 return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014931
Victor Stinner8c62be82010-05-06 00:08:46 +000014932 if (setup_confname_tables(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020014933 return -1;
Fred Drakebec628d1999-12-15 18:31:10 +000014934
Victor Stinner8c62be82010-05-06 00:08:46 +000014935 Py_INCREF(PyExc_OSError);
14936 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014937
Ross Lagerwall7807c352011-03-17 20:20:30 +020014938#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080014939 waitid_result_desc.name = MODNAME ".waitid_result";
14940 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
14941 if (WaitidResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014942 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014943 }
14944 Py_INCREF(WaitidResultType);
14945 PyModule_AddObject(m, "waitid_result", WaitidResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014946 state->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014947#endif
14948
Eddie Elizondob3966632019-11-05 07:16:14 -080014949 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
14950 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14951 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14952 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
14953 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
14954 if (StatResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014955 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014956 }
14957 Py_INCREF(StatResultType);
14958 PyModule_AddObject(m, "stat_result", StatResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014959 state->StatResultType = StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014960 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
14961 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014962
Eddie Elizondob3966632019-11-05 07:16:14 -080014963 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
14964 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
14965 if (StatVFSResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014966 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014967 }
14968 Py_INCREF(StatVFSResultType);
14969 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014970 state->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014971#ifdef NEED_TICKS_PER_SECOND
14972# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080014973 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014974# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080014975 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014976# else
Eddie Elizondob3966632019-11-05 07:16:14 -080014977 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014978# endif
14979#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014980
William Orr81574b82018-10-01 22:19:56 -070014981#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080014982 sched_param_desc.name = MODNAME ".sched_param";
14983 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
14984 if (SchedParamType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014985 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014986 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014987 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080014988 PyModule_AddObject(m, "sched_param", SchedParamType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014989 state->SchedParamType = SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014990 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014991#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014992
Eddie Elizondob3966632019-11-05 07:16:14 -080014993 /* initialize TerminalSize_info */
14994 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
14995 if (TerminalSizeType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014996 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014997 }
14998 Py_INCREF(TerminalSizeType);
14999 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015000 state->TerminalSizeType = TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015001
15002 /* initialize scandir types */
Victor Stinner1c2fa782020-05-10 11:05:29 +020015003 PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015004 if (ScandirIteratorType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015005 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015006 }
Victor Stinner97f33c32020-05-14 18:05:58 +020015007 state->ScandirIteratorType = ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015008
Victor Stinner1c2fa782020-05-10 11:05:29 +020015009 PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015010 if (DirEntryType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015011 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015012 }
15013 Py_INCREF(DirEntryType);
15014 PyModule_AddObject(m, "DirEntry", DirEntryType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015015 state->DirEntryType = DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015016
Larry Hastings605a62d2012-06-24 04:33:36 -070015017 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080015018 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015019 if (TimesResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015020 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015021 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015022 Py_INCREF(TimesResultType);
15023 PyModule_AddObject(m, "times_result", TimesResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015024 state->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015025
Eddie Elizondob3966632019-11-05 07:16:14 -080015026 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015027 if (UnameResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015028 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015029 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015030 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015031 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015032 state->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015033
Thomas Wouters477c8d52006-05-27 19:21:47 +000015034#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000015035 /*
15036 * Step 2 of weak-linking support on Mac OS X.
15037 *
15038 * The code below removes functions that are not available on the
15039 * currently active platform.
15040 *
15041 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070015042 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000015043 * OSX 10.4.
15044 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000015045#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000015046 if (fstatvfs == NULL) {
15047 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015048 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015049 }
15050 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000015051#endif /* HAVE_FSTATVFS */
15052
15053#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000015054 if (statvfs == NULL) {
15055 if (PyObject_DelAttrString(m, "statvfs") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015056 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015057 }
15058 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000015059#endif /* HAVE_STATVFS */
15060
15061# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000015062 if (lchown == NULL) {
15063 if (PyObject_DelAttrString(m, "lchown") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015064 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015065 }
15066 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000015067#endif /* HAVE_LCHOWN */
15068
15069
15070#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010015071
Victor Stinner97f33c32020-05-14 18:05:58 +020015072 if ((state->billion = PyLong_FromLong(1000000000)) == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015073 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015074#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +020015075 state->struct_rusage = PyUnicode_InternFromString("struct_rusage");
15076 if (state->struct_rusage == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015077 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015078#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020015079 state->st_mode = PyUnicode_InternFromString("st_mode");
15080 if (state->st_mode == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015081 return -1;
Larry Hastings6fe20b32012-04-19 15:07:49 -070015082
Larry Hastings9cf065c2012-06-22 16:30:09 -070015083 /* suppress "function not used" warnings */
15084 {
15085 int ignored;
15086 fd_specified("", -1);
15087 follow_symlinks_specified("", 1);
15088 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
15089 dir_fd_converter(Py_None, &ignored);
15090 dir_fd_unavailable(Py_None, &ignored);
15091 }
15092
15093 /*
15094 * provide list of locally available functions
15095 * so os.py can populate support_* lists
15096 */
Victor Stinner97f33c32020-05-14 18:05:58 +020015097 PyObject *list = PyList_New(0);
15098 if (!list) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015099 return -1;
Victor Stinner97f33c32020-05-14 18:05:58 +020015100 }
15101 for (const char * const *trace = have_functions; *trace; trace++) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070015102 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
15103 if (!unicode)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015104 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015105 if (PyList_Append(list, unicode))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015106 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015107 Py_DECREF(unicode);
15108 }
15109 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040015110
Victor Stinner1c2fa782020-05-10 11:05:29 +020015111 return 0;
15112}
15113
15114
15115static PyModuleDef_Slot posixmodile_slots[] = {
15116 {Py_mod_exec, posixmodule_exec},
15117 {0, NULL}
15118};
15119
15120static struct PyModuleDef posixmodule = {
15121 PyModuleDef_HEAD_INIT,
15122 .m_name = MODNAME,
15123 .m_doc = posix__doc__,
15124 .m_size = sizeof(_posixstate),
15125 .m_methods = posix_methods,
15126 .m_slots = posixmodile_slots,
15127 .m_traverse = _posix_traverse,
15128 .m_clear = _posix_clear,
15129 .m_free = _posix_free,
15130};
15131
15132PyMODINIT_FUNC
15133INITFUNC(void)
15134{
15135 return PyModuleDef_Init(&posixmodule);
Guido van Rossumb6775db1994-08-01 11:34:53 +000015136}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015137
15138#ifdef __cplusplus
15139}
15140#endif