blob: 47ae7a8c22ac2ba9092c20441f40b0ebcefbbaa4 [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
Victor Stinner4a21e572020-04-15 02:35:41 +020035#include "pycore_ceval.h" // _PyEval_ReInitThreads()
36#include "pycore_import.h" // _PyImport_ReInitLock()
37#include "pycore_pystate.h" // _PyInterpreterState_GET()
38#include "structmember.h" // PyMemberDef
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020039#ifndef MS_WINDOWS
Victor Stinnerd5d9e812019-05-13 12:35:37 +020040# include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010041#else
Victor Stinnerd5d9e812019-05-13 12:35:37 +020042# include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020043#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000044
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020045/* On android API level 21, 'AT_EACCESS' is not declared although
46 * HAVE_FACCESSAT is defined. */
47#ifdef __ANDROID__
Victor Stinner5eca75d2020-04-15 15:07:31 +020048# undef HAVE_FACCESSAT
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020049#endif
50
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000051#include <stdio.h> /* needed for ctermid() */
52
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000053#ifdef __cplusplus
54extern "C" {
55#endif
56
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000057PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000058"This module provides access to operating system functionality that is\n\
59standardized by the C Standard and the POSIX standard (a thinly\n\
60disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000061corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000062
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000063
Ross Lagerwall4d076da2011-03-18 06:56:53 +020064#ifdef HAVE_SYS_UIO_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020065# include <sys/uio.h>
Ross Lagerwall4d076da2011-03-18 06:56:53 +020066#endif
67
Christian Heimes75b96182017-09-05 15:53:09 +020068#ifdef HAVE_SYS_SYSMACROS_H
69/* GNU C Library: major(), minor(), makedev() */
Victor Stinner5eca75d2020-04-15 15:07:31 +020070# include <sys/sysmacros.h>
Christian Heimes75b96182017-09-05 15:53:09 +020071#endif
72
Thomas Wouters0e3f5912006-08-11 14:57:12 +000073#ifdef HAVE_SYS_TYPES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020074# include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075#endif /* HAVE_SYS_TYPES_H */
76
77#ifdef HAVE_SYS_STAT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020078# include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000079#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000080
Guido van Rossum36bc6801995-06-14 22:54:23 +000081#ifdef HAVE_SYS_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020082# include <sys/wait.h> // WNOHANG
Guido van Rossum36bc6801995-06-14 22:54:23 +000083#endif
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080084#ifdef HAVE_LINUX_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020085# include <linux/wait.h> // P_PIDFD
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080086#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000087
Thomas Wouters0e3f5912006-08-11 14:57:12 +000088#ifdef HAVE_SIGNAL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020089# include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000090#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000091
Guido van Rossumb6775db1994-08-01 11:34:53 +000092#ifdef HAVE_FCNTL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020093# include <fcntl.h>
94#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000095
Guido van Rossuma6535fd2001-10-18 19:44:10 +000096#ifdef HAVE_GRP_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020097# include <grp.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000098#endif
99
Barry Warsaw5676bd12003-01-07 20:57:09 +0000100#ifdef HAVE_SYSEXITS_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200101# include <sysexits.h>
102#endif
Barry Warsaw5676bd12003-01-07 20:57:09 +0000103
Anthony Baxter8a560de2004-10-13 15:30:56 +0000104#ifdef HAVE_SYS_LOADAVG_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200105# include <sys/loadavg.h>
Anthony Baxter8a560de2004-10-13 15:30:56 +0000106#endif
107
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000108#ifdef HAVE_SYS_SENDFILE_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200109# include <sys/sendfile.h>
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000110#endif
111
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200112#if defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200113# include <copyfile.h>
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200114#endif
115
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500116#ifdef HAVE_SCHED_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200117# include <sched.h>
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500118#endif
119
Pablo Galindoaac4d032019-05-31 19:39:47 +0100120#ifdef HAVE_COPY_FILE_RANGE
Victor Stinner5eca75d2020-04-15 15:07:31 +0200121# include <unistd.h>
Pablo Galindoaac4d032019-05-31 19:39:47 +0100122#endif
123
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500124#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200125# undef HAVE_SCHED_SETAFFINITY
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500126#endif
127
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200128#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200129# define USE_XATTRS
Benjamin Peterson9428d532011-09-14 11:45:52 -0400130#endif
131
132#ifdef USE_XATTRS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200133# include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400134#endif
135
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000136#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200137# ifdef HAVE_SYS_SOCKET_H
138# include <sys/socket.h>
139# endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000140#endif
141
Victor Stinner8b905bd2011-10-25 13:34:04 +0200142#ifdef HAVE_DLFCN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200143# include <dlfcn.h>
Victor Stinner8b905bd2011-10-25 13:34:04 +0200144#endif
145
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200146#ifdef __hpux
Victor Stinner5eca75d2020-04-15 15:07:31 +0200147# include <sys/mpctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200148#endif
149
150#if defined(__DragonFly__) || \
151 defined(__OpenBSD__) || \
152 defined(__FreeBSD__) || \
153 defined(__NetBSD__) || \
154 defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200155# include <sys/sysctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200156#endif
157
Victor Stinner9b1f4742016-09-06 16:18:52 -0700158#ifdef HAVE_LINUX_RANDOM_H
159# include <linux/random.h>
160#endif
161#ifdef HAVE_GETRANDOM_SYSCALL
162# include <sys/syscall.h>
163#endif
164
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100165#if defined(MS_WINDOWS)
166# define TERMSIZE_USE_CONIO
167#elif defined(HAVE_SYS_IOCTL_H)
168# include <sys/ioctl.h>
169# if defined(HAVE_TERMIOS_H)
170# include <termios.h>
171# endif
172# if defined(TIOCGWINSZ)
173# define TERMSIZE_USE_IOCTL
174# endif
175#endif /* MS_WINDOWS */
176
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000178/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000179#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200180# define HAVE_OPENDIR 1
181# define HAVE_SYSTEM 1
182# include <process.h>
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000183#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200184# ifdef _MSC_VER
185 /* Microsoft compiler */
186# define HAVE_GETPPID 1
187# define HAVE_GETLOGIN 1
188# define HAVE_SPAWNV 1
189# define HAVE_EXECV 1
190# define HAVE_WSPAWNV 1
191# define HAVE_WEXECV 1
192# define HAVE_PIPE 1
193# define HAVE_SYSTEM 1
194# define HAVE_CWAIT 1
195# define HAVE_FSYNC 1
196# define fsync _commit
197# else
198 /* Unix functions that the configure script doesn't check for */
199# ifndef __VXWORKS__
200# define HAVE_EXECV 1
201# define HAVE_FORK 1
202# if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
203# define HAVE_FORK1 1
204# endif
205# endif
206# define HAVE_GETEGID 1
207# define HAVE_GETEUID 1
208# define HAVE_GETGID 1
209# define HAVE_GETPPID 1
210# define HAVE_GETUID 1
211# define HAVE_KILL 1
212# define HAVE_OPENDIR 1
213# define HAVE_PIPE 1
214# define HAVE_SYSTEM 1
215# define HAVE_WAIT 1
216# define HAVE_TTYNAME 1
217# endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000218#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000219
Eddie Elizondob3966632019-11-05 07:16:14 -0800220_Py_IDENTIFIER(__fspath__);
Victor Stinnera2f7c002012-02-08 03:36:25 +0100221
Larry Hastings61272b72014-01-07 12:41:53 -0800222/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000223# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800224module os
Larry Hastings61272b72014-01-07 12:41:53 -0800225[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000226/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100227
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000229
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000230#if defined(__sgi)&&_COMPILER_VERSION>=700
231/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
232 (default) */
233extern char *ctermid_r(char *);
234#endif
235
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000236#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237
pxinwrf2d7ac72019-05-21 18:46:37 +0800238#if defined(__VXWORKS__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200239# include <vxCpuLib.h>
240# include <rtpLib.h>
241# include <wait.h>
242# include <taskLib.h>
243# ifndef _P_WAIT
244# define _P_WAIT 0
245# define _P_NOWAIT 1
246# define _P_NOWAITO 1
247# endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800248#endif /* __VXWORKS__ */
249
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000250#ifdef HAVE_POSIX_SPAWN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200251# include <spawn.h>
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000252#endif
253
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254#ifdef HAVE_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200255# include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000256#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000258#ifdef HAVE_SYS_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200259# include <sys/utime.h>
260# define HAVE_UTIME_H /* pretend we do for the rest of this file */
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000261#endif /* HAVE_SYS_UTIME_H */
262
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#ifdef HAVE_SYS_TIMES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200264# include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000265#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266
267#ifdef HAVE_SYS_PARAM_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200268# include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000269#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270
271#ifdef HAVE_SYS_UTSNAME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200272# include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000275#ifdef HAVE_DIRENT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200276# include <dirent.h>
277# define NAMLEN(dirent) strlen((dirent)->d_name)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200279# if defined(__WATCOMC__) && !defined(__QNX__)
280# include <direct.h>
281# define NAMLEN(dirent) strlen((dirent)->d_name)
282# else
283# define dirent direct
284# define NAMLEN(dirent) (dirent)->d_namlen
285# endif
286# ifdef HAVE_SYS_NDIR_H
287# include <sys/ndir.h>
288# endif
289# ifdef HAVE_SYS_DIR_H
290# include <sys/dir.h>
291# endif
292# ifdef HAVE_NDIR_H
293# include <ndir.h>
294# endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000295#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000297#ifdef _MSC_VER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200298# ifdef HAVE_DIRECT_H
299# include <direct.h>
300# endif
301# ifdef HAVE_IO_H
302# include <io.h>
303# endif
304# ifdef HAVE_PROCESS_H
305# include <process.h>
306# endif
307# ifndef IO_REPARSE_TAG_SYMLINK
308# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
309# endif
310# ifndef IO_REPARSE_TAG_MOUNT_POINT
311# define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
312# endif
313# include "osdefs.h" // SEP
314# include <malloc.h>
315# include <windows.h>
316# include <shellapi.h> // ShellExecute()
317# include <lmcons.h> // UNLEN
318# define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000319#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000320
Tim Petersbc2e10e2002-03-03 23:17:02 +0000321#ifndef MAXPATHLEN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200322# if defined(PATH_MAX) && PATH_MAX > 1024
323# define MAXPATHLEN PATH_MAX
324# else
325# define MAXPATHLEN 1024
326# endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#endif /* MAXPATHLEN */
328
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000329#ifdef UNION_WAIT
Victor Stinner5eca75d2020-04-15 15:07:31 +0200330 /* Emulate some macros on systems that have a union instead of macros */
331# ifndef WIFEXITED
332# define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
333# endif
334# ifndef WEXITSTATUS
335# define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
336# endif
337# ifndef WTERMSIG
338# define WTERMSIG(u_wait) ((u_wait).w_termsig)
339# endif
340# define WAIT_TYPE union wait
341# define WAIT_STATUS_INT(s) (s.w_status)
342#else
343 /* !UNION_WAIT */
344# define WAIT_TYPE int
345# define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000346#endif /* UNION_WAIT */
347
Greg Wardb48bc172000-03-01 21:51:56 +0000348/* Don't use the "_r" form if we don't need it (also, won't have a
349 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200350#if defined(HAVE_CTERMID_R)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200351# define USE_CTERMID_R
Greg Wardb48bc172000-03-01 21:51:56 +0000352#endif
353
Fred Drake699f3522000-06-29 21:12:41 +0000354/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000355#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000356#undef FSTAT
357#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200358#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200359# define STAT win32_stat
360# define LSTAT win32_lstat
361# define FSTAT _Py_fstat_noraise
362# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000363#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200364# define STAT stat
365# define LSTAT lstat
366# define FSTAT fstat
367# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000368#endif
369
Tim Peters11b23062003-04-23 02:39:17 +0000370#if defined(MAJOR_IN_MKDEV)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200371# include <sys/mkdev.h>
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000372#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200373# if defined(MAJOR_IN_SYSMACROS)
374# include <sys/sysmacros.h>
375# endif
376# if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
377# include <sys/mkdev.h>
378# endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000379#endif
Fred Drake699f3522000-06-29 21:12:41 +0000380
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200381#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200382# define INITFUNC PyInit_nt
383# define MODNAME "nt"
Victor Stinner6036e442015-03-08 01:58:04 +0100384#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200385# define INITFUNC PyInit_posix
386# define MODNAME "posix"
Victor Stinner6036e442015-03-08 01:58:04 +0100387#endif
388
jcea6c51d512018-01-28 14:00:08 +0100389#if defined(__sun)
390/* Something to implement in autoconf, not present in autoconf 2.69 */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200391# define HAVE_STRUCT_STAT_ST_FSTYPE 1
jcea6c51d512018-01-28 14:00:08 +0100392#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200393
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600394/* memfd_create is either defined in sys/mman.h or sys/memfd.h
395 * linux/memfd.h defines additional flags
396 */
397#ifdef HAVE_SYS_MMAN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200398# include <sys/mman.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600399#endif
400#ifdef HAVE_SYS_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200401# include <sys/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600402#endif
403#ifdef HAVE_LINUX_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200404# include <linux/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600405#endif
406
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800407#ifdef _Py_MEMORY_SANITIZER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200408# include <sanitizer/msan_interface.h>
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800409#endif
410
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200411#ifdef HAVE_FORK
412static void
413run_at_forkers(PyObject *lst, int reverse)
414{
415 Py_ssize_t i;
416 PyObject *cpy;
417
418 if (lst != NULL) {
419 assert(PyList_CheckExact(lst));
420
421 /* Use a list copy in case register_at_fork() is called from
422 * one of the callbacks.
423 */
424 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
425 if (cpy == NULL)
426 PyErr_WriteUnraisable(lst);
427 else {
428 if (reverse)
429 PyList_Reverse(cpy);
430 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
431 PyObject *func, *res;
432 func = PyList_GET_ITEM(cpy, i);
Jeroen Demeyer7f41c8e2019-07-04 12:35:31 +0200433 res = _PyObject_CallNoArg(func);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200434 if (res == NULL)
435 PyErr_WriteUnraisable(func);
436 else
437 Py_DECREF(res);
438 }
439 Py_DECREF(cpy);
440 }
441 }
442}
443
444void
445PyOS_BeforeFork(void)
446{
Victor Stinner81a7be32020-04-14 15:14:01 +0200447 run_at_forkers(_PyInterpreterState_GET()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200448
449 _PyImport_AcquireLock();
450}
451
452void
453PyOS_AfterFork_Parent(void)
454{
455 if (_PyImport_ReleaseLock() <= 0)
456 Py_FatalError("failed releasing import lock after fork");
457
Victor Stinner81a7be32020-04-14 15:14:01 +0200458 run_at_forkers(_PyInterpreterState_GET()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200459}
460
461void
462PyOS_AfterFork_Child(void)
463{
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200464 _PyRuntimeState *runtime = &_PyRuntime;
465 _PyGILState_Reinit(runtime);
Victor Stinnerd5d9e812019-05-13 12:35:37 +0200466 _PyEval_ReInitThreads(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200467 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200468 _PySignal_AfterFork();
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200469 _PyRuntimeState_ReInitThreads(runtime);
Victor Stinnerb49858b2019-05-24 15:20:23 +0200470 _PyInterpreterState_DeleteExceptMain(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200471
Victor Stinner81a7be32020-04-14 15:14:01 +0200472 run_at_forkers(_PyInterpreterState_GET()->after_forkers_child, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200473}
474
475static int
476register_at_forker(PyObject **lst, PyObject *func)
477{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700478 if (func == NULL) /* nothing to register? do nothing. */
479 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200480 if (*lst == NULL) {
481 *lst = PyList_New(0);
482 if (*lst == NULL)
483 return -1;
484 }
485 return PyList_Append(*lst, func);
486}
Victor Stinner87255be2020-04-07 23:11:49 +0200487#endif /* HAVE_FORK */
488
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200489
490/* Legacy wrapper */
491void
492PyOS_AfterFork(void)
493{
494#ifdef HAVE_FORK
495 PyOS_AfterFork_Child();
496#endif
497}
498
499
Victor Stinner6036e442015-03-08 01:58:04 +0100500#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200501/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700502void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
503void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200504 ULONG, struct _Py_stat_struct *);
505#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700506
Larry Hastings9cf065c2012-06-22 16:30:09 -0700507
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200508#ifndef MS_WINDOWS
509PyObject *
510_PyLong_FromUid(uid_t uid)
511{
512 if (uid == (uid_t)-1)
513 return PyLong_FromLong(-1);
514 return PyLong_FromUnsignedLong(uid);
515}
516
517PyObject *
518_PyLong_FromGid(gid_t gid)
519{
520 if (gid == (gid_t)-1)
521 return PyLong_FromLong(-1);
522 return PyLong_FromUnsignedLong(gid);
523}
524
525int
526_Py_Uid_Converter(PyObject *obj, void *p)
527{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528 uid_t uid;
529 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200530 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200531 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700532 unsigned long uresult;
533
534 index = PyNumber_Index(obj);
535 if (index == NULL) {
536 PyErr_Format(PyExc_TypeError,
537 "uid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800538 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200539 return 0;
540 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700541
542 /*
543 * Handling uid_t is complicated for two reasons:
544 * * Although uid_t is (always?) unsigned, it still
545 * accepts -1.
546 * * We don't know its size in advance--it may be
547 * bigger than an int, or it may be smaller than
548 * a long.
549 *
550 * So a bit of defensive programming is in order.
551 * Start with interpreting the value passed
552 * in as a signed long and see if it works.
553 */
554
555 result = PyLong_AsLongAndOverflow(index, &overflow);
556
557 if (!overflow) {
558 uid = (uid_t)result;
559
560 if (result == -1) {
561 if (PyErr_Occurred())
562 goto fail;
563 /* It's a legitimate -1, we're done. */
564 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200565 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700566
567 /* Any other negative number is disallowed. */
568 if (result < 0)
569 goto underflow;
570
571 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200572 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700573 (long)uid != result)
574 goto underflow;
575 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200576 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700577
578 if (overflow < 0)
579 goto underflow;
580
581 /*
582 * Okay, the value overflowed a signed long. If it
583 * fits in an *unsigned* long, it may still be okay,
584 * as uid_t may be unsigned long on this platform.
585 */
586 uresult = PyLong_AsUnsignedLong(index);
587 if (PyErr_Occurred()) {
588 if (PyErr_ExceptionMatches(PyExc_OverflowError))
589 goto overflow;
590 goto fail;
591 }
592
593 uid = (uid_t)uresult;
594
595 /*
596 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
597 * but this value would get interpreted as (uid_t)-1 by chown
598 * and its siblings. That's not what the user meant! So we
599 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100600 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700601 */
602 if (uid == (uid_t)-1)
603 goto overflow;
604
605 /* Ensure the value wasn't truncated. */
606 if (sizeof(uid_t) < sizeof(long) &&
607 (unsigned long)uid != uresult)
608 goto overflow;
609 /* fallthrough */
610
611success:
612 Py_DECREF(index);
613 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200614 return 1;
615
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200617 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618 "uid is less than minimum");
619 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700621overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200622 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700623 "uid is greater than maximum");
624 /* fallthrough */
625
626fail:
627 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200628 return 0;
629}
630
631int
632_Py_Gid_Converter(PyObject *obj, void *p)
633{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700634 gid_t gid;
635 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200636 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200637 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700638 unsigned long uresult;
639
640 index = PyNumber_Index(obj);
641 if (index == NULL) {
642 PyErr_Format(PyExc_TypeError,
643 "gid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800644 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200645 return 0;
646 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700647
648 /*
649 * Handling gid_t is complicated for two reasons:
650 * * Although gid_t is (always?) unsigned, it still
651 * accepts -1.
652 * * We don't know its size in advance--it may be
653 * bigger than an int, or it may be smaller than
654 * a long.
655 *
656 * So a bit of defensive programming is in order.
657 * Start with interpreting the value passed
658 * in as a signed long and see if it works.
659 */
660
661 result = PyLong_AsLongAndOverflow(index, &overflow);
662
663 if (!overflow) {
664 gid = (gid_t)result;
665
666 if (result == -1) {
667 if (PyErr_Occurred())
668 goto fail;
669 /* It's a legitimate -1, we're done. */
670 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200671 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700672
673 /* Any other negative number is disallowed. */
674 if (result < 0) {
675 goto underflow;
676 }
677
678 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200679 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680 (long)gid != result)
681 goto underflow;
682 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200683 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684
685 if (overflow < 0)
686 goto underflow;
687
688 /*
689 * Okay, the value overflowed a signed long. If it
690 * fits in an *unsigned* long, it may still be okay,
691 * as gid_t may be unsigned long on this platform.
692 */
693 uresult = PyLong_AsUnsignedLong(index);
694 if (PyErr_Occurred()) {
695 if (PyErr_ExceptionMatches(PyExc_OverflowError))
696 goto overflow;
697 goto fail;
698 }
699
700 gid = (gid_t)uresult;
701
702 /*
703 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
704 * but this value would get interpreted as (gid_t)-1 by chown
705 * and its siblings. That's not what the user meant! So we
706 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100707 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700708 */
709 if (gid == (gid_t)-1)
710 goto overflow;
711
712 /* Ensure the value wasn't truncated. */
713 if (sizeof(gid_t) < sizeof(long) &&
714 (unsigned long)gid != uresult)
715 goto overflow;
716 /* fallthrough */
717
718success:
719 Py_DECREF(index);
720 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200721 return 1;
722
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700723underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200724 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700725 "gid is less than minimum");
726 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200727
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700728overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200729 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700730 "gid is greater than maximum");
731 /* fallthrough */
732
733fail:
734 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200735 return 0;
736}
737#endif /* MS_WINDOWS */
738
739
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700740#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800741
742
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200743#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
744static int
745_Py_Dev_Converter(PyObject *obj, void *p)
746{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200747 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200748 if (PyErr_Occurred())
749 return 0;
750 return 1;
751}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800752#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200753
754
Larry Hastings9cf065c2012-06-22 16:30:09 -0700755#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400756/*
757 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
758 * without the int cast, the value gets interpreted as uint (4291925331),
759 * which doesn't play nicely with all the initializer lines in this file that
760 * look like this:
761 * int dir_fd = DEFAULT_DIR_FD;
762 */
763#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700764#else
765#define DEFAULT_DIR_FD (-100)
766#endif
767
768static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300769_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200770{
771 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700772 long long_value;
773
774 PyObject *index = PyNumber_Index(o);
775 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700776 return 0;
777 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700778
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300779 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700780 long_value = PyLong_AsLongAndOverflow(index, &overflow);
781 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300782 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200783 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700784 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700785 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700786 return 0;
787 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200788 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700789 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700790 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700791 return 0;
792 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700793
Larry Hastings9cf065c2012-06-22 16:30:09 -0700794 *p = (int)long_value;
795 return 1;
796}
797
798static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200799dir_fd_converter(PyObject *o, void *p)
800{
801 if (o == Py_None) {
802 *(int *)p = DEFAULT_DIR_FD;
803 return 1;
804 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300805 else if (PyIndex_Check(o)) {
806 return _fd_converter(o, (int *)p);
807 }
808 else {
809 PyErr_Format(PyExc_TypeError,
810 "argument should be integer or None, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800811 _PyType_Name(Py_TYPE(o)));
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300812 return 0;
813 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700814}
815
Eddie Elizondob3966632019-11-05 07:16:14 -0800816typedef struct {
817 PyObject *billion;
Eddie Elizondob3966632019-11-05 07:16:14 -0800818 PyObject *DirEntryType;
819 PyObject *ScandirIteratorType;
820#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
821 PyObject *SchedParamType;
822#endif
823 PyObject *StatResultType;
824 PyObject *StatVFSResultType;
825 PyObject *TerminalSizeType;
826 PyObject *TimesResultType;
827 PyObject *UnameResultType;
828#if defined(HAVE_WAITID) && !defined(__APPLE__)
829 PyObject *WaitidResultType;
830#endif
831#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
832 PyObject *struct_rusage;
833#endif
834 PyObject *st_mode;
835} _posixstate;
836
Eddie Elizondob3966632019-11-05 07:16:14 -0800837
Hai Shif707d942020-03-16 21:15:01 +0800838static inline _posixstate*
839get_posix_state(PyObject *module)
840{
841 void *state = PyModule_GetState(module);
842 assert(state != NULL);
843 return (_posixstate *)state;
844}
845
Larry Hastings9cf065c2012-06-22 16:30:09 -0700846/*
847 * A PyArg_ParseTuple "converter" function
848 * that handles filesystem paths in the manner
849 * preferred by the os module.
850 *
851 * path_converter accepts (Unicode) strings and their
852 * subclasses, and bytes and their subclasses. What
853 * it does with the argument depends on the platform:
854 *
855 * * On Windows, if we get a (Unicode) string we
856 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700857 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700858 *
859 * * On all other platforms, strings are encoded
860 * to bytes using PyUnicode_FSConverter, then we
861 * extract the char * from the bytes object and
862 * return that.
863 *
864 * path_converter also optionally accepts signed
865 * integers (representing open file descriptors) instead
866 * of path strings.
867 *
868 * Input fields:
869 * path.nullable
870 * If nonzero, the path is permitted to be None.
871 * path.allow_fd
872 * If nonzero, the path is permitted to be a file handle
873 * (a signed int) instead of a string.
874 * path.function_name
875 * If non-NULL, path_converter will use that as the name
876 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700877 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700878 * path.argument_name
879 * If non-NULL, path_converter will use that as the name
880 * of the parameter in error messages.
881 * (If path.argument_name is NULL it uses "path".)
882 *
883 * Output fields:
884 * path.wide
885 * Points to the path if it was expressed as Unicode
886 * and was not encoded. (Only used on Windows.)
887 * path.narrow
888 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700889 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000890 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700891 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700892 * path.fd
893 * Contains a file descriptor if path.accept_fd was true
894 * and the caller provided a signed integer instead of any
895 * sort of string.
896 *
897 * WARNING: if your "path" parameter is optional, and is
898 * unspecified, path_converter will never get called.
899 * So if you set allow_fd, you *MUST* initialize path.fd = -1
900 * yourself!
901 * path.length
902 * The length of the path in characters, if specified as
903 * a string.
904 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800905 * The original object passed in (if get a PathLike object,
906 * the result of PyOS_FSPath() is treated as the original object).
907 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700908 * path.cleanup
909 * For internal use only. May point to a temporary object.
910 * (Pay no attention to the man behind the curtain.)
911 *
912 * At most one of path.wide or path.narrow will be non-NULL.
913 * If path was None and path.nullable was set,
914 * or if path was an integer and path.allow_fd was set,
915 * both path.wide and path.narrow will be NULL
916 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200917 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700918 * path_converter takes care to not write to the path_t
919 * unless it's successful. However it must reset the
920 * "cleanup" field each time it's called.
921 *
922 * Use as follows:
923 * path_t path;
924 * memset(&path, 0, sizeof(path));
925 * PyArg_ParseTuple(args, "O&", path_converter, &path);
926 * // ... use values from path ...
927 * path_cleanup(&path);
928 *
929 * (Note that if PyArg_Parse fails you don't need to call
930 * path_cleanup(). However it is safe to do so.)
931 */
932typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100933 const char *function_name;
934 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935 int nullable;
936 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300937 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700938#ifdef MS_WINDOWS
939 BOOL narrow;
940#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300941 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700942#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943 int fd;
944 Py_ssize_t length;
945 PyObject *object;
946 PyObject *cleanup;
947} path_t;
948
Steve Dowercc16be82016-09-08 10:35:16 -0700949#ifdef MS_WINDOWS
950#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
951 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
952#else
Larry Hastings2f936352014-08-05 14:04:04 +1000953#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
954 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700955#endif
Larry Hastings31826802013-10-19 00:09:25 -0700956
Larry Hastings9cf065c2012-06-22 16:30:09 -0700957static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800958path_cleanup(path_t *path)
959{
960 Py_CLEAR(path->object);
961 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700962}
963
964static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300965path_converter(PyObject *o, void *p)
966{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700967 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800968 PyObject *bytes = NULL;
969 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700970 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300971 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700972#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800973 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700974 const wchar_t *wide;
975#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700976
977#define FORMAT_EXCEPTION(exc, fmt) \
978 PyErr_Format(exc, "%s%s" fmt, \
979 path->function_name ? path->function_name : "", \
980 path->function_name ? ": " : "", \
981 path->argument_name ? path->argument_name : "path")
982
983 /* Py_CLEANUP_SUPPORTED support */
984 if (o == NULL) {
985 path_cleanup(path);
986 return 1;
987 }
988
Brett Cannon3f9183b2016-08-26 14:44:48 -0700989 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800990 path->object = path->cleanup = NULL;
991 /* path->object owns a reference to the original object */
992 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700993
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300994 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700995 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700996#ifdef MS_WINDOWS
997 path->narrow = FALSE;
998#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700999 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001000#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001002 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001003 }
1004
Brett Cannon3f9183b2016-08-26 14:44:48 -07001005 /* Only call this here so that we don't treat the return value of
1006 os.fspath() as an fd or buffer. */
1007 is_index = path->allow_fd && PyIndex_Check(o);
1008 is_buffer = PyObject_CheckBuffer(o);
1009 is_bytes = PyBytes_Check(o);
1010 is_unicode = PyUnicode_Check(o);
1011
1012 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
1013 /* Inline PyOS_FSPath() for better error messages. */
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001014 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001015
1016 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1017 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001018 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001019 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001020 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001021 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001022 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001023 goto error_exit;
1024 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001025 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001026 is_unicode = 1;
1027 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001028 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001029 is_bytes = 1;
1030 }
1031 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001032 PyErr_Format(PyExc_TypeError,
1033 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -08001034 "not %.200s", _PyType_Name(Py_TYPE(o)),
1035 _PyType_Name(Py_TYPE(res)));
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001036 Py_DECREF(res);
1037 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001038 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001039
1040 /* still owns a reference to the original object */
1041 Py_DECREF(o);
1042 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001043 }
1044
1045 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001046#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001047 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001048 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001049 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001050 }
Victor Stinner59799a82013-11-13 14:17:30 +01001051 if (length > 32767) {
1052 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001053 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001054 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001055 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001056 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001057 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001058 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001059
1060 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001061 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001062 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001063 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001064#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001065 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001066 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001067 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001068#endif
1069 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001070 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001071 bytes = o;
1072 Py_INCREF(bytes);
1073 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001074 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001075 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001076 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001077 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1078 "%s%s%s should be %s, not %.200s",
1079 path->function_name ? path->function_name : "",
1080 path->function_name ? ": " : "",
1081 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001082 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1083 "integer or None" :
1084 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1085 path->nullable ? "string, bytes, os.PathLike or None" :
1086 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001087 _PyType_Name(Py_TYPE(o)))) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001088 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001089 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001090 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001091 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001092 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001093 }
1094 }
Steve Dowercc16be82016-09-08 10:35:16 -07001095 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001096 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001097 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001098 }
1099 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001100#ifdef MS_WINDOWS
1101 path->narrow = FALSE;
1102#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001103 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001104#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001105 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001106 }
1107 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001108 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001109 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1110 path->function_name ? path->function_name : "",
1111 path->function_name ? ": " : "",
1112 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001113 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1114 "integer or None" :
1115 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1116 path->nullable ? "string, bytes, os.PathLike or None" :
1117 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001118 _PyType_Name(Py_TYPE(o)));
Xiang Zhang04316c42017-01-08 23:26:57 +08001119 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001120 }
1121
Larry Hastings9cf065c2012-06-22 16:30:09 -07001122 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001123 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001124 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001125 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001126 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001127 }
1128
Steve Dowercc16be82016-09-08 10:35:16 -07001129#ifdef MS_WINDOWS
1130 wo = PyUnicode_DecodeFSDefaultAndSize(
1131 narrow,
1132 length
1133 );
1134 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001135 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001136 }
1137
Xiang Zhang04316c42017-01-08 23:26:57 +08001138 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001139 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001140 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001141 }
1142 if (length > 32767) {
1143 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001144 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001145 }
1146 if (wcslen(wide) != length) {
1147 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001148 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001149 }
1150 path->wide = wide;
1151 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001152 path->cleanup = wo;
1153 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001154#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001155 path->wide = NULL;
1156 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001157 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001158 /* Still a reference owned by path->object, don't have to
1159 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001160 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001161 }
1162 else {
1163 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001164 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001165#endif
1166 path->fd = -1;
1167
1168 success_exit:
1169 path->length = length;
1170 path->object = o;
1171 return Py_CLEANUP_SUPPORTED;
1172
1173 error_exit:
1174 Py_XDECREF(o);
1175 Py_XDECREF(bytes);
1176#ifdef MS_WINDOWS
1177 Py_XDECREF(wo);
1178#endif
1179 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001180}
1181
1182static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001183argument_unavailable_error(const char *function_name, const char *argument_name)
1184{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001185 PyErr_Format(PyExc_NotImplementedError,
1186 "%s%s%s unavailable on this platform",
1187 (function_name != NULL) ? function_name : "",
1188 (function_name != NULL) ? ": ": "",
1189 argument_name);
1190}
1191
1192static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001193dir_fd_unavailable(PyObject *o, void *p)
1194{
1195 int dir_fd;
1196 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001197 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001198 if (dir_fd != DEFAULT_DIR_FD) {
1199 argument_unavailable_error(NULL, "dir_fd");
1200 return 0;
1201 }
1202 *(int *)p = dir_fd;
1203 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001204}
1205
1206static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001207fd_specified(const char *function_name, int fd)
1208{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001209 if (fd == -1)
1210 return 0;
1211
1212 argument_unavailable_error(function_name, "fd");
1213 return 1;
1214}
1215
1216static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001217follow_symlinks_specified(const char *function_name, int follow_symlinks)
1218{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219 if (follow_symlinks)
1220 return 0;
1221
1222 argument_unavailable_error(function_name, "follow_symlinks");
1223 return 1;
1224}
1225
1226static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001227path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1228{
Steve Dowercc16be82016-09-08 10:35:16 -07001229 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1230#ifndef MS_WINDOWS
1231 && !path->narrow
1232#endif
1233 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001234 PyErr_Format(PyExc_ValueError,
1235 "%s: can't specify dir_fd without matching path",
1236 function_name);
1237 return 1;
1238 }
1239 return 0;
1240}
1241
1242static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001243dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1244{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001245 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1246 PyErr_Format(PyExc_ValueError,
1247 "%s: can't specify both dir_fd and fd",
1248 function_name);
1249 return 1;
1250 }
1251 return 0;
1252}
1253
1254static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001255fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1256 int follow_symlinks)
1257{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001258 if ((fd > 0) && (!follow_symlinks)) {
1259 PyErr_Format(PyExc_ValueError,
1260 "%s: cannot use fd and follow_symlinks together",
1261 function_name);
1262 return 1;
1263 }
1264 return 0;
1265}
1266
1267static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001268dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1269 int follow_symlinks)
1270{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001271 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1272 PyErr_Format(PyExc_ValueError,
1273 "%s: cannot use dir_fd and follow_symlinks together",
1274 function_name);
1275 return 1;
1276 }
1277 return 0;
1278}
1279
Larry Hastings2f936352014-08-05 14:04:04 +10001280#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001281 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001282#else
Larry Hastings2f936352014-08-05 14:04:04 +10001283 typedef off_t Py_off_t;
1284#endif
1285
1286static int
1287Py_off_t_converter(PyObject *arg, void *addr)
1288{
1289#ifdef HAVE_LARGEFILE_SUPPORT
1290 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1291#else
1292 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001293#endif
1294 if (PyErr_Occurred())
1295 return 0;
1296 return 1;
1297}
Larry Hastings2f936352014-08-05 14:04:04 +10001298
1299static PyObject *
1300PyLong_FromPy_off_t(Py_off_t offset)
1301{
1302#ifdef HAVE_LARGEFILE_SUPPORT
1303 return PyLong_FromLongLong(offset);
1304#else
1305 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001306#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001307}
1308
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001309#ifdef HAVE_SIGSET_T
1310/* Convert an iterable of integers to a sigset.
1311 Return 1 on success, return 0 and raise an exception on error. */
1312int
1313_Py_Sigset_Converter(PyObject *obj, void *addr)
1314{
1315 sigset_t *mask = (sigset_t *)addr;
1316 PyObject *iterator, *item;
1317 long signum;
1318 int overflow;
1319
Rémi Lapeyref0900192019-05-04 01:30:53 +02001320 // The extra parens suppress the unreachable-code warning with clang on MacOS
1321 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001322 /* Probably only if mask == NULL. */
1323 PyErr_SetFromErrno(PyExc_OSError);
1324 return 0;
1325 }
1326
1327 iterator = PyObject_GetIter(obj);
1328 if (iterator == NULL) {
1329 return 0;
1330 }
1331
1332 while ((item = PyIter_Next(iterator)) != NULL) {
1333 signum = PyLong_AsLongAndOverflow(item, &overflow);
1334 Py_DECREF(item);
1335 if (signum <= 0 || signum >= NSIG) {
1336 if (overflow || signum != -1 || !PyErr_Occurred()) {
1337 PyErr_Format(PyExc_ValueError,
1338 "signal number %ld out of range", signum);
1339 }
1340 goto error;
1341 }
1342 if (sigaddset(mask, (int)signum)) {
1343 if (errno != EINVAL) {
1344 /* Probably impossible */
1345 PyErr_SetFromErrno(PyExc_OSError);
1346 goto error;
1347 }
1348 /* For backwards compatibility, allow idioms such as
1349 * `range(1, NSIG)` but warn about invalid signal numbers
1350 */
1351 const char msg[] =
1352 "invalid signal number %ld, please use valid_signals()";
1353 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1354 goto error;
1355 }
1356 }
1357 }
1358 if (!PyErr_Occurred()) {
1359 Py_DECREF(iterator);
1360 return 1;
1361 }
1362
1363error:
1364 Py_DECREF(iterator);
1365 return 0;
1366}
1367#endif /* HAVE_SIGSET_T */
1368
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001369#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001370
1371static int
Brian Curtind25aef52011-06-13 15:16:04 -05001372win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001373{
Martin Panter70214ad2016-08-04 02:38:59 +00001374 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1375 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001376 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001377
1378 if (0 == DeviceIoControl(
1379 reparse_point_handle,
1380 FSCTL_GET_REPARSE_POINT,
1381 NULL, 0, /* in buffer */
1382 target_buffer, sizeof(target_buffer),
1383 &n_bytes_returned,
1384 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001385 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001386
1387 if (reparse_tag)
1388 *reparse_tag = rdb->ReparseTag;
1389
Brian Curtind25aef52011-06-13 15:16:04 -05001390 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001391}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001392
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001393#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001394
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001395/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001396#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001397/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001398** environ directly, we must obtain it with _NSGetEnviron(). See also
1399** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001400*/
1401#include <crt_externs.h>
pxinwrf2d7ac72019-05-21 18:46:37 +08001402#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001403extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001404#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001405
Barry Warsaw53699e91996-12-10 23:23:01 +00001406static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001407convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001408{
Victor Stinner8c62be82010-05-06 00:08:46 +00001409 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001410#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001411 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001412#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001414#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001415
Victor Stinner8c62be82010-05-06 00:08:46 +00001416 d = PyDict_New();
1417 if (d == NULL)
1418 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001419#ifdef MS_WINDOWS
1420 /* _wenviron must be initialized in this way if the program is started
1421 through main() instead of wmain(). */
1422 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001423 e = _wenviron;
Benoit Hudson723f71a2019-12-06 14:15:03 -05001424#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1425 /* environ is not accessible as an extern in a shared object on OSX; use
1426 _NSGetEnviron to resolve it. The value changes if you add environment
1427 variables between calls to Py_Initialize, so don't cache the value. */
1428 e = *_NSGetEnviron();
Victor Stinner8c62be82010-05-06 00:08:46 +00001429#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001430 e = environ;
1431#endif
1432 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001433 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001434 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001435 PyObject *k;
1436 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001437#ifdef MS_WINDOWS
1438 const wchar_t *p = wcschr(*e, L'=');
1439#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001440 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001441#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001442 if (p == NULL)
1443 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001444#ifdef MS_WINDOWS
1445 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1446#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001447 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001448#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001449 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001450 Py_DECREF(d);
1451 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001452 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001453#ifdef MS_WINDOWS
1454 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1455#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001456 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001457#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001458 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001459 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001460 Py_DECREF(d);
1461 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001462 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001463 if (PyDict_GetItemWithError(d, k) == NULL) {
1464 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1465 Py_DECREF(v);
1466 Py_DECREF(k);
1467 Py_DECREF(d);
1468 return NULL;
1469 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001470 }
1471 Py_DECREF(k);
1472 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001473 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001474 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001475}
1476
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001477/* Set a POSIX-specific error from errno, and return NULL */
1478
Barry Warsawd58d7641998-07-23 16:14:40 +00001479static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001480posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001481{
Victor Stinner8c62be82010-05-06 00:08:46 +00001482 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001483}
Mark Hammondef8b6542001-05-13 08:04:26 +00001484
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001485#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001486static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001487win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001488{
Victor Stinner8c62be82010-05-06 00:08:46 +00001489 /* XXX We should pass the function name along in the future.
1490 (winreg.c also wants to pass the function name.)
1491 This would however require an additional param to the
1492 Windows error object, which is non-trivial.
1493 */
1494 errno = GetLastError();
1495 if (filename)
1496 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1497 else
1498 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001499}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001500
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001501static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001502win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001503{
1504 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001505 if (filename)
1506 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001507 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001508 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001509 filename);
1510 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001511 return PyErr_SetFromWindowsErr(err);
1512}
1513
1514static PyObject *
1515win32_error_object(const char* function, PyObject* filename)
1516{
1517 errno = GetLastError();
1518 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001519}
1520
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001521#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001522
Larry Hastings9cf065c2012-06-22 16:30:09 -07001523static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001524posix_path_object_error(PyObject *path)
1525{
1526 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1527}
1528
1529static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001530path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001531{
1532#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001533 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1534 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001535#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001536 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001537#endif
1538}
1539
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001540static PyObject *
1541path_object_error2(PyObject *path, PyObject *path2)
1542{
1543#ifdef MS_WINDOWS
1544 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1545 PyExc_OSError, 0, path, path2);
1546#else
1547 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1548#endif
1549}
1550
1551static PyObject *
1552path_error(path_t *path)
1553{
1554 return path_object_error(path->object);
1555}
Larry Hastings31826802013-10-19 00:09:25 -07001556
Larry Hastingsb0827312014-02-09 22:05:19 -08001557static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001558posix_path_error(path_t *path)
1559{
1560 return posix_path_object_error(path->object);
1561}
1562
1563static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001564path_error2(path_t *path, path_t *path2)
1565{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001566 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001567}
1568
1569
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001570/* POSIX generic methods */
1571
Larry Hastings2f936352014-08-05 14:04:04 +10001572static int
1573fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001574{
Victor Stinner8c62be82010-05-06 00:08:46 +00001575 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001576 int *pointer = (int *)p;
1577 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001578 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001579 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001580 *pointer = fd;
1581 return 1;
1582}
1583
1584static PyObject *
1585posix_fildes_fd(int fd, int (*func)(int))
1586{
1587 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001588 int async_err = 0;
1589
1590 do {
1591 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001592 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001593 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001594 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001595 Py_END_ALLOW_THREADS
1596 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1597 if (res != 0)
1598 return (!async_err) ? posix_error() : NULL;
1599 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001600}
Guido van Rossum21142a01999-01-08 21:05:37 +00001601
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001602
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001603#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001604/* This is a reimplementation of the C library's chdir function,
1605 but one that produces Win32 errors instead of DOS error codes.
1606 chdir is essentially a wrapper around SetCurrentDirectory; however,
1607 it also needs to set "magic" environment variables indicating
1608 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001609static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001610win32_wchdir(LPCWSTR path)
1611{
Victor Stinnered537822015-12-13 21:40:26 +01001612 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001613 int result;
1614 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001615
Victor Stinner8c62be82010-05-06 00:08:46 +00001616 if(!SetCurrentDirectoryW(path))
1617 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001618 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001619 if (!result)
1620 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001621 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001622 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001623 if (!new_path) {
1624 SetLastError(ERROR_OUTOFMEMORY);
1625 return FALSE;
1626 }
1627 result = GetCurrentDirectoryW(result, new_path);
1628 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001629 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001630 return FALSE;
1631 }
1632 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001633 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1634 wcsncmp(new_path, L"//", 2) == 0);
1635 if (!is_unc_like_path) {
1636 env[1] = new_path[0];
1637 result = SetEnvironmentVariableW(env, new_path);
1638 }
Victor Stinnered537822015-12-13 21:40:26 +01001639 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001640 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001641 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001642}
1643#endif
1644
Martin v. Löwis14694662006-02-03 12:54:16 +00001645#ifdef MS_WINDOWS
1646/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1647 - time stamps are restricted to second resolution
1648 - file modification times suffer from forth-and-back conversions between
1649 UTC and local time
1650 Therefore, we implement our own stat, based on the Win32 API directly.
1651*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001652#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001653#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001654#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001655
Victor Stinner6036e442015-03-08 01:58:04 +01001656static void
Steve Dowercc16be82016-09-08 10:35:16 -07001657find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1658 BY_HANDLE_FILE_INFORMATION *info,
1659 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001660{
1661 memset(info, 0, sizeof(*info));
1662 info->dwFileAttributes = pFileData->dwFileAttributes;
1663 info->ftCreationTime = pFileData->ftCreationTime;
1664 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1665 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1666 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1667 info->nFileSizeLow = pFileData->nFileSizeLow;
1668/* info->nNumberOfLinks = 1; */
1669 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1670 *reparse_tag = pFileData->dwReserved0;
1671 else
1672 *reparse_tag = 0;
1673}
1674
Guido van Rossumd8faa362007-04-27 19:54:29 +00001675static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001676attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001677{
Victor Stinner8c62be82010-05-06 00:08:46 +00001678 HANDLE hFindFile;
1679 WIN32_FIND_DATAW FileData;
1680 hFindFile = FindFirstFileW(pszFile, &FileData);
1681 if (hFindFile == INVALID_HANDLE_VALUE)
1682 return FALSE;
1683 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001684 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001685 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001686}
1687
Brian Curtind25aef52011-06-13 15:16:04 -05001688static int
Steve Dowercc16be82016-09-08 10:35:16 -07001689win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001690 BOOL traverse)
1691{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001692 HANDLE hFile;
1693 BY_HANDLE_FILE_INFORMATION fileInfo;
1694 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1695 DWORD fileType, error;
1696 BOOL isUnhandledTag = FALSE;
1697 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001698
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001699 DWORD access = FILE_READ_ATTRIBUTES;
1700 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1701 if (!traverse) {
1702 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1703 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001704
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001705 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001706 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001707 /* Either the path doesn't exist, or the caller lacks access. */
1708 error = GetLastError();
1709 switch (error) {
1710 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1711 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1712 /* Try reading the parent directory. */
1713 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1714 /* Cannot read the parent directory. */
1715 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001716 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001717 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001718 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1719 if (traverse ||
1720 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1721 /* The stat call has to traverse but cannot, so fail. */
1722 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001723 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001724 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001725 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001726 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001727
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001728 case ERROR_INVALID_PARAMETER:
1729 /* \\.\con requires read or write access. */
1730 hFile = CreateFileW(path, access | GENERIC_READ,
1731 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1732 OPEN_EXISTING, flags, NULL);
1733 if (hFile == INVALID_HANDLE_VALUE) {
1734 SetLastError(error);
1735 return -1;
1736 }
1737 break;
1738
1739 case ERROR_CANT_ACCESS_FILE:
1740 /* bpo37834: open unhandled reparse points if traverse fails. */
1741 if (traverse) {
1742 traverse = FALSE;
1743 isUnhandledTag = TRUE;
1744 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1745 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1746 }
1747 if (hFile == INVALID_HANDLE_VALUE) {
1748 SetLastError(error);
1749 return -1;
1750 }
1751 break;
1752
1753 default:
1754 return -1;
1755 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001756 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001757
1758 if (hFile != INVALID_HANDLE_VALUE) {
1759 /* Handle types other than files on disk. */
1760 fileType = GetFileType(hFile);
1761 if (fileType != FILE_TYPE_DISK) {
1762 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1763 retval = -1;
1764 goto cleanup;
1765 }
1766 DWORD fileAttributes = GetFileAttributesW(path);
1767 memset(result, 0, sizeof(*result));
1768 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1769 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1770 /* \\.\pipe\ or \\.\mailslot\ */
1771 result->st_mode = _S_IFDIR;
1772 } else if (fileType == FILE_TYPE_CHAR) {
1773 /* \\.\nul */
1774 result->st_mode = _S_IFCHR;
1775 } else if (fileType == FILE_TYPE_PIPE) {
1776 /* \\.\pipe\spam */
1777 result->st_mode = _S_IFIFO;
1778 }
1779 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1780 goto cleanup;
1781 }
1782
1783 /* Query the reparse tag, and traverse a non-link. */
1784 if (!traverse) {
1785 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1786 &tagInfo, sizeof(tagInfo))) {
1787 /* Allow devices that do not support FileAttributeTagInfo. */
1788 switch (GetLastError()) {
1789 case ERROR_INVALID_PARAMETER:
1790 case ERROR_INVALID_FUNCTION:
1791 case ERROR_NOT_SUPPORTED:
1792 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1793 tagInfo.ReparseTag = 0;
1794 break;
1795 default:
1796 retval = -1;
1797 goto cleanup;
1798 }
1799 } else if (tagInfo.FileAttributes &
1800 FILE_ATTRIBUTE_REPARSE_POINT) {
1801 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1802 if (isUnhandledTag) {
1803 /* Traversing previously failed for either this link
1804 or its target. */
1805 SetLastError(ERROR_CANT_ACCESS_FILE);
1806 retval = -1;
1807 goto cleanup;
1808 }
1809 /* Traverse a non-link, but not if traversing already failed
1810 for an unhandled tag. */
1811 } else if (!isUnhandledTag) {
1812 CloseHandle(hFile);
1813 return win32_xstat_impl(path, result, TRUE);
1814 }
1815 }
1816 }
1817
1818 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
1819 switch (GetLastError()) {
1820 case ERROR_INVALID_PARAMETER:
1821 case ERROR_INVALID_FUNCTION:
1822 case ERROR_NOT_SUPPORTED:
Steve Dower772ec0f2019-09-04 14:42:54 -07001823 /* Volumes and physical disks are block devices, e.g.
1824 \\.\C: and \\.\PhysicalDrive0. */
1825 memset(result, 0, sizeof(*result));
1826 result->st_mode = 0x6000; /* S_IFBLK */
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001827 goto cleanup;
1828 }
Steve Dower772ec0f2019-09-04 14:42:54 -07001829 retval = -1;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001830 goto cleanup;
1831 }
1832 }
1833
1834 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
1835
1836 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
1837 /* Fix the file execute permissions. This hack sets S_IEXEC if
1838 the filename has an extension that is commonly used by files
1839 that CreateProcessW can execute. A real implementation calls
1840 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
1841 AccessCheck to check for generic read, write, and execute
1842 access. */
1843 const wchar_t *fileExtension = wcsrchr(path, '.');
1844 if (fileExtension) {
1845 if (_wcsicmp(fileExtension, L".exe") == 0 ||
1846 _wcsicmp(fileExtension, L".bat") == 0 ||
1847 _wcsicmp(fileExtension, L".cmd") == 0 ||
1848 _wcsicmp(fileExtension, L".com") == 0) {
1849 result->st_mode |= 0111;
1850 }
1851 }
1852 }
1853
1854cleanup:
1855 if (hFile != INVALID_HANDLE_VALUE) {
Steve Dower772ec0f2019-09-04 14:42:54 -07001856 /* Preserve last error if we are failing */
1857 error = retval ? GetLastError() : 0;
1858 if (!CloseHandle(hFile)) {
1859 retval = -1;
1860 } else if (retval) {
1861 /* Restore last error */
1862 SetLastError(error);
1863 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001864 }
1865
1866 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001867}
1868
1869static int
Steve Dowercc16be82016-09-08 10:35:16 -07001870win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001871{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001872 /* Protocol violation: we explicitly clear errno, instead of
1873 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001874 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001875 errno = 0;
1876 return code;
1877}
Brian Curtind25aef52011-06-13 15:16:04 -05001878/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001879
1880 In Posix, stat automatically traverses symlinks and returns the stat
1881 structure for the target. In Windows, the equivalent GetFileAttributes by
1882 default does not traverse symlinks and instead returns attributes for
1883 the symlink.
1884
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001885 Instead, we will open the file (which *does* traverse symlinks by default)
1886 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00001887
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001888static int
Steve Dowercc16be82016-09-08 10:35:16 -07001889win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001890{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001891 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001892}
1893
Victor Stinner8c62be82010-05-06 00:08:46 +00001894static int
Steve Dowercc16be82016-09-08 10:35:16 -07001895win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001896{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001897 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001898}
1899
Martin v. Löwis14694662006-02-03 12:54:16 +00001900#endif /* MS_WINDOWS */
1901
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001902PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001903"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001904This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001905 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001906or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1907\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001908Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1909or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001910\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001911See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001912
1913static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 {"st_mode", "protection bits"},
1915 {"st_ino", "inode"},
1916 {"st_dev", "device"},
1917 {"st_nlink", "number of hard links"},
1918 {"st_uid", "user ID of owner"},
1919 {"st_gid", "group ID of owner"},
1920 {"st_size", "total size, in bytes"},
1921 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1922 {NULL, "integer time of last access"},
1923 {NULL, "integer time of last modification"},
1924 {NULL, "integer time of last change"},
1925 {"st_atime", "time of last access"},
1926 {"st_mtime", "time of last modification"},
1927 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001928 {"st_atime_ns", "time of last access in nanoseconds"},
1929 {"st_mtime_ns", "time of last modification in nanoseconds"},
1930 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001931#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001932 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001933#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001934#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001935 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001936#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001937#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001939#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001940#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001941 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001942#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001943#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001944 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001945#endif
1946#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001947 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001948#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001949#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1950 {"st_file_attributes", "Windows file attribute bits"},
1951#endif
jcea6c51d512018-01-28 14:00:08 +01001952#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1953 {"st_fstype", "Type of filesystem"},
1954#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001955#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
1956 {"st_reparse_tag", "Windows reparse tag"},
1957#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001959};
1960
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001961#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001962#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001963#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001964#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001965#endif
1966
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001967#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001968#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1969#else
1970#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1971#endif
1972
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001973#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001974#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1975#else
1976#define ST_RDEV_IDX ST_BLOCKS_IDX
1977#endif
1978
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001979#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1980#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1981#else
1982#define ST_FLAGS_IDX ST_RDEV_IDX
1983#endif
1984
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001985#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001986#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001987#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001988#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001989#endif
1990
1991#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1992#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1993#else
1994#define ST_BIRTHTIME_IDX ST_GEN_IDX
1995#endif
1996
Zachary Ware63f277b2014-06-19 09:46:37 -05001997#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1998#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1999#else
2000#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2001#endif
2002
jcea6c51d512018-01-28 14:00:08 +01002003#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2004#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2005#else
2006#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2007#endif
2008
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002009#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2010#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2011#else
2012#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2013#endif
2014
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002015static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002016 "stat_result", /* name */
2017 stat_result__doc__, /* doc */
2018 stat_result_fields,
2019 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002020};
2021
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002022PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002023"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2024This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002025 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002026or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002027\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002028See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002029
2030static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 {"f_bsize", },
2032 {"f_frsize", },
2033 {"f_blocks", },
2034 {"f_bfree", },
2035 {"f_bavail", },
2036 {"f_files", },
2037 {"f_ffree", },
2038 {"f_favail", },
2039 {"f_flag", },
2040 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002041 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002042 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002043};
2044
2045static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002046 "statvfs_result", /* name */
2047 statvfs_result__doc__, /* doc */
2048 statvfs_result_fields,
2049 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002050};
2051
Ross Lagerwall7807c352011-03-17 20:20:30 +02002052#if defined(HAVE_WAITID) && !defined(__APPLE__)
2053PyDoc_STRVAR(waitid_result__doc__,
2054"waitid_result: Result from waitid.\n\n\
2055This object may be accessed either as a tuple of\n\
2056 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2057or via the attributes si_pid, si_uid, and so on.\n\
2058\n\
2059See os.waitid for more information.");
2060
2061static PyStructSequence_Field waitid_result_fields[] = {
2062 {"si_pid", },
2063 {"si_uid", },
2064 {"si_signo", },
2065 {"si_status", },
2066 {"si_code", },
2067 {0}
2068};
2069
2070static PyStructSequence_Desc waitid_result_desc = {
2071 "waitid_result", /* name */
2072 waitid_result__doc__, /* doc */
2073 waitid_result_fields,
2074 5
2075};
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002076#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002077static newfunc structseq_new;
2078
2079static PyObject *
2080statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2081{
Victor Stinner8c62be82010-05-06 00:08:46 +00002082 PyStructSequence *result;
2083 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002084
Victor Stinner8c62be82010-05-06 00:08:46 +00002085 result = (PyStructSequence*)structseq_new(type, args, kwds);
2086 if (!result)
2087 return NULL;
2088 /* If we have been initialized from a tuple,
2089 st_?time might be set to None. Initialize it
2090 from the int slots. */
2091 for (i = 7; i <= 9; i++) {
2092 if (result->ob_item[i+3] == Py_None) {
2093 Py_DECREF(Py_None);
2094 Py_INCREF(result->ob_item[i]);
2095 result->ob_item[i+3] = result->ob_item[i];
2096 }
2097 }
2098 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002099}
2100
Eddie Elizondob3966632019-11-05 07:16:14 -08002101static int
2102_posix_clear(PyObject *module)
2103{
Victor Stinner97f33c32020-05-14 18:05:58 +02002104 _posixstate *state = get_posix_state(module);
2105 Py_CLEAR(state->billion);
2106 Py_CLEAR(state->DirEntryType);
2107 Py_CLEAR(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002108#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002109 Py_CLEAR(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002110#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002111 Py_CLEAR(state->StatResultType);
2112 Py_CLEAR(state->StatVFSResultType);
2113 Py_CLEAR(state->TerminalSizeType);
2114 Py_CLEAR(state->TimesResultType);
2115 Py_CLEAR(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002116#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002117 Py_CLEAR(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002118#endif
2119#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002120 Py_CLEAR(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002121#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002122 Py_CLEAR(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002123 return 0;
2124}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002125
Eddie Elizondob3966632019-11-05 07:16:14 -08002126static int
2127_posix_traverse(PyObject *module, visitproc visit, void *arg)
2128{
Victor Stinner97f33c32020-05-14 18:05:58 +02002129 _posixstate *state = get_posix_state(module);
2130 Py_VISIT(state->billion);
2131 Py_VISIT(state->DirEntryType);
2132 Py_VISIT(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002133#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002134 Py_VISIT(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002135#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002136 Py_VISIT(state->StatResultType);
2137 Py_VISIT(state->StatVFSResultType);
2138 Py_VISIT(state->TerminalSizeType);
2139 Py_VISIT(state->TimesResultType);
2140 Py_VISIT(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002141#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002142 Py_VISIT(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002143#endif
2144#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002145 Py_VISIT(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002146#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002147 Py_VISIT(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002148 return 0;
2149}
2150
2151static void
2152_posix_free(void *module)
2153{
2154 _posix_clear((PyObject *)module);
2155}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002156
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002157static void
Victor Stinner1c2fa782020-05-10 11:05:29 +02002158fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002159{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002160 PyObject *s = _PyLong_FromTime_t(sec);
2161 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2162 PyObject *s_in_ns = NULL;
2163 PyObject *ns_total = NULL;
2164 PyObject *float_s = NULL;
2165
2166 if (!(s && ns_fractional))
2167 goto exit;
2168
Victor Stinner1c2fa782020-05-10 11:05:29 +02002169 s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002170 if (!s_in_ns)
2171 goto exit;
2172
2173 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2174 if (!ns_total)
2175 goto exit;
2176
Victor Stinner01b5aab2017-10-24 02:02:00 -07002177 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2178 if (!float_s) {
2179 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002180 }
2181
2182 PyStructSequence_SET_ITEM(v, index, s);
2183 PyStructSequence_SET_ITEM(v, index+3, float_s);
2184 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2185 s = NULL;
2186 float_s = NULL;
2187 ns_total = NULL;
2188exit:
2189 Py_XDECREF(s);
2190 Py_XDECREF(ns_fractional);
2191 Py_XDECREF(s_in_ns);
2192 Py_XDECREF(ns_total);
2193 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002194}
2195
Tim Peters5aa91602002-01-30 05:46:57 +00002196/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002197 (used by posix_stat() and posix_fstat()) */
2198static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +02002199_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002200{
Victor Stinner8c62be82010-05-06 00:08:46 +00002201 unsigned long ansec, mnsec, cnsec;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002202 PyObject *StatResultType = get_posix_state(module)->StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08002203 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002204 if (v == NULL)
2205 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002206
Victor Stinner8c62be82010-05-06 00:08:46 +00002207 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002208 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002209 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002210#ifdef MS_WINDOWS
2211 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002212#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002213 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002214#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002215 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002216#if defined(MS_WINDOWS)
2217 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2218 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2219#else
2220 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2221 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2222#endif
xdegaye50e86032017-05-22 11:15:08 +02002223 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2224 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002225
Martin v. Löwis14694662006-02-03 12:54:16 +00002226#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002227 ansec = st->st_atim.tv_nsec;
2228 mnsec = st->st_mtim.tv_nsec;
2229 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002230#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002231 ansec = st->st_atimespec.tv_nsec;
2232 mnsec = st->st_mtimespec.tv_nsec;
2233 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002234#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002235 ansec = st->st_atime_nsec;
2236 mnsec = st->st_mtime_nsec;
2237 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002238#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002239 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002240#endif
Victor Stinner1c2fa782020-05-10 11:05:29 +02002241 fill_time(module, v, 7, st->st_atime, ansec);
2242 fill_time(module, v, 8, st->st_mtime, mnsec);
2243 fill_time(module, v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002244
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002245#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002246 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2247 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002248#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002249#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002250 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2251 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002252#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002253#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002254 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2255 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002256#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002257#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002258 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2259 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002260#endif
2261#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002262 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002263 PyObject *val;
2264 unsigned long bsec,bnsec;
2265 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002266#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002267 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002268#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002269 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002270#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002271 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002272 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2273 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002274 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002275#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002276#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002277 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2278 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002279#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002280#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2281 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2282 PyLong_FromUnsignedLong(st->st_file_attributes));
2283#endif
jcea6c51d512018-01-28 14:00:08 +01002284#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2285 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2286 PyUnicode_FromString(st->st_fstype));
2287#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002288#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2289 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2290 PyLong_FromUnsignedLong(st->st_reparse_tag));
2291#endif
Fred Drake699f3522000-06-29 21:12:41 +00002292
Victor Stinner8c62be82010-05-06 00:08:46 +00002293 if (PyErr_Occurred()) {
2294 Py_DECREF(v);
2295 return NULL;
2296 }
Fred Drake699f3522000-06-29 21:12:41 +00002297
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002299}
2300
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002301/* POSIX methods */
2302
Guido van Rossum94f6f721999-01-06 18:42:14 +00002303
2304static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02002305posix_do_stat(PyObject *module, const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002306 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002307{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002308 STRUCT_STAT st;
2309 int result;
2310
2311#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2312 if (follow_symlinks_specified(function_name, follow_symlinks))
2313 return NULL;
2314#endif
2315
2316 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2317 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2318 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2319 return NULL;
2320
2321 Py_BEGIN_ALLOW_THREADS
2322 if (path->fd != -1)
2323 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002324#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002325 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002326 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002327 else
Steve Dowercc16be82016-09-08 10:35:16 -07002328 result = win32_lstat(path->wide, &st);
2329#else
2330 else
2331#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002332 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2333 result = LSTAT(path->narrow, &st);
2334 else
Steve Dowercc16be82016-09-08 10:35:16 -07002335#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002336#ifdef HAVE_FSTATAT
2337 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2338 result = fstatat(dir_fd, path->narrow, &st,
2339 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2340 else
Steve Dowercc16be82016-09-08 10:35:16 -07002341#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002342 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002343#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002344 Py_END_ALLOW_THREADS
2345
Victor Stinner292c8352012-10-30 02:17:38 +01002346 if (result != 0) {
2347 return path_error(path);
2348 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002349
Victor Stinner1c2fa782020-05-10 11:05:29 +02002350 return _pystat_fromstructstat(module, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002351}
2352
Larry Hastings2f936352014-08-05 14:04:04 +10002353/*[python input]
2354
2355for s in """
2356
2357FACCESSAT
2358FCHMODAT
2359FCHOWNAT
2360FSTATAT
2361LINKAT
2362MKDIRAT
2363MKFIFOAT
2364MKNODAT
2365OPENAT
2366READLINKAT
2367SYMLINKAT
2368UNLINKAT
2369
2370""".strip().split():
2371 s = s.strip()
2372 print("""
2373#ifdef HAVE_{s}
2374 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002375#else
Larry Hastings2f936352014-08-05 14:04:04 +10002376 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002377#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002378""".rstrip().format(s=s))
2379
2380for s in """
2381
2382FCHDIR
2383FCHMOD
2384FCHOWN
2385FDOPENDIR
2386FEXECVE
2387FPATHCONF
2388FSTATVFS
2389FTRUNCATE
2390
2391""".strip().split():
2392 s = s.strip()
2393 print("""
2394#ifdef HAVE_{s}
2395 #define PATH_HAVE_{s} 1
2396#else
2397 #define PATH_HAVE_{s} 0
2398#endif
2399
2400""".rstrip().format(s=s))
2401[python start generated code]*/
2402
2403#ifdef HAVE_FACCESSAT
2404 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2405#else
2406 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2407#endif
2408
2409#ifdef HAVE_FCHMODAT
2410 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2411#else
2412 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2413#endif
2414
2415#ifdef HAVE_FCHOWNAT
2416 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2417#else
2418 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2419#endif
2420
2421#ifdef HAVE_FSTATAT
2422 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2423#else
2424 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2425#endif
2426
2427#ifdef HAVE_LINKAT
2428 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2429#else
2430 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2431#endif
2432
2433#ifdef HAVE_MKDIRAT
2434 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2435#else
2436 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2437#endif
2438
2439#ifdef HAVE_MKFIFOAT
2440 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2441#else
2442 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2443#endif
2444
2445#ifdef HAVE_MKNODAT
2446 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2447#else
2448 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2449#endif
2450
2451#ifdef HAVE_OPENAT
2452 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2453#else
2454 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2455#endif
2456
2457#ifdef HAVE_READLINKAT
2458 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2459#else
2460 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2461#endif
2462
2463#ifdef HAVE_SYMLINKAT
2464 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2465#else
2466 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2467#endif
2468
2469#ifdef HAVE_UNLINKAT
2470 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2471#else
2472 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2473#endif
2474
2475#ifdef HAVE_FCHDIR
2476 #define PATH_HAVE_FCHDIR 1
2477#else
2478 #define PATH_HAVE_FCHDIR 0
2479#endif
2480
2481#ifdef HAVE_FCHMOD
2482 #define PATH_HAVE_FCHMOD 1
2483#else
2484 #define PATH_HAVE_FCHMOD 0
2485#endif
2486
2487#ifdef HAVE_FCHOWN
2488 #define PATH_HAVE_FCHOWN 1
2489#else
2490 #define PATH_HAVE_FCHOWN 0
2491#endif
2492
2493#ifdef HAVE_FDOPENDIR
2494 #define PATH_HAVE_FDOPENDIR 1
2495#else
2496 #define PATH_HAVE_FDOPENDIR 0
2497#endif
2498
2499#ifdef HAVE_FEXECVE
2500 #define PATH_HAVE_FEXECVE 1
2501#else
2502 #define PATH_HAVE_FEXECVE 0
2503#endif
2504
2505#ifdef HAVE_FPATHCONF
2506 #define PATH_HAVE_FPATHCONF 1
2507#else
2508 #define PATH_HAVE_FPATHCONF 0
2509#endif
2510
2511#ifdef HAVE_FSTATVFS
2512 #define PATH_HAVE_FSTATVFS 1
2513#else
2514 #define PATH_HAVE_FSTATVFS 0
2515#endif
2516
2517#ifdef HAVE_FTRUNCATE
2518 #define PATH_HAVE_FTRUNCATE 1
2519#else
2520 #define PATH_HAVE_FTRUNCATE 0
2521#endif
2522/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002523
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002524#ifdef MS_WINDOWS
2525 #undef PATH_HAVE_FTRUNCATE
2526 #define PATH_HAVE_FTRUNCATE 1
2527#endif
Larry Hastings31826802013-10-19 00:09:25 -07002528
Larry Hastings61272b72014-01-07 12:41:53 -08002529/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002530
2531class path_t_converter(CConverter):
2532
2533 type = "path_t"
2534 impl_by_reference = True
2535 parse_by_reference = True
2536
2537 converter = 'path_converter'
2538
2539 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002540 # right now path_t doesn't support default values.
2541 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002542 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002543 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002544
Larry Hastings2f936352014-08-05 14:04:04 +10002545 if self.c_default not in (None, 'Py_None'):
2546 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002547
2548 self.nullable = nullable
2549 self.allow_fd = allow_fd
2550
Larry Hastings7726ac92014-01-31 22:03:12 -08002551 def pre_render(self):
2552 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002553 if isinstance(value, str):
2554 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002555 return str(int(bool(value)))
2556
2557 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002558 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002559 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002560 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002561 strify(self.nullable),
2562 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002563 )
2564
2565 def cleanup(self):
2566 return "path_cleanup(&" + self.name + ");\n"
2567
2568
2569class dir_fd_converter(CConverter):
2570 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002571
Larry Hastings2f936352014-08-05 14:04:04 +10002572 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002573 if self.default in (unspecified, None):
2574 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002575 if isinstance(requires, str):
2576 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2577 else:
2578 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002579
Larry Hastings2f936352014-08-05 14:04:04 +10002580class fildes_converter(CConverter):
2581 type = 'int'
2582 converter = 'fildes_converter'
2583
2584class uid_t_converter(CConverter):
2585 type = "uid_t"
2586 converter = '_Py_Uid_Converter'
2587
2588class gid_t_converter(CConverter):
2589 type = "gid_t"
2590 converter = '_Py_Gid_Converter'
2591
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002592class dev_t_converter(CConverter):
2593 type = 'dev_t'
2594 converter = '_Py_Dev_Converter'
2595
2596class dev_t_return_converter(unsigned_long_return_converter):
2597 type = 'dev_t'
2598 conversion_fn = '_PyLong_FromDev'
2599 unsigned_cast = '(dev_t)'
2600
Larry Hastings2f936352014-08-05 14:04:04 +10002601class FSConverter_converter(CConverter):
2602 type = 'PyObject *'
2603 converter = 'PyUnicode_FSConverter'
2604 def converter_init(self):
2605 if self.default is not unspecified:
2606 fail("FSConverter_converter does not support default values")
2607 self.c_default = 'NULL'
2608
2609 def cleanup(self):
2610 return "Py_XDECREF(" + self.name + ");\n"
2611
2612class pid_t_converter(CConverter):
2613 type = 'pid_t'
2614 format_unit = '" _Py_PARSE_PID "'
2615
2616class idtype_t_converter(int_converter):
2617 type = 'idtype_t'
2618
2619class id_t_converter(CConverter):
2620 type = 'id_t'
2621 format_unit = '" _Py_PARSE_PID "'
2622
Benjamin Petersonca470632016-09-06 13:47:26 -07002623class intptr_t_converter(CConverter):
2624 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002625 format_unit = '" _Py_PARSE_INTPTR "'
2626
2627class Py_off_t_converter(CConverter):
2628 type = 'Py_off_t'
2629 converter = 'Py_off_t_converter'
2630
2631class Py_off_t_return_converter(long_return_converter):
2632 type = 'Py_off_t'
2633 conversion_fn = 'PyLong_FromPy_off_t'
2634
2635class path_confname_converter(CConverter):
2636 type="int"
2637 converter="conv_path_confname"
2638
2639class confstr_confname_converter(path_confname_converter):
2640 converter='conv_confstr_confname'
2641
2642class sysconf_confname_converter(path_confname_converter):
2643 converter="conv_sysconf_confname"
2644
Larry Hastings61272b72014-01-07 12:41:53 -08002645[python start generated code]*/
Victor Stinner1c2fa782020-05-10 11:05:29 +02002646/*[python end generated code: output=da39a3ee5e6b4b0d input=f1c8ae8d744f6c8b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002647
Larry Hastings61272b72014-01-07 12:41:53 -08002648/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002649
Larry Hastings2a727912014-01-16 11:32:01 -08002650os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002651
2652 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002653 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002654 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002655
2656 *
2657
Larry Hastings2f936352014-08-05 14:04:04 +10002658 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002659 If not None, it should be a file descriptor open to a directory,
2660 and path should be a relative string; path will then be relative to
2661 that directory.
2662
2663 follow_symlinks: bool = True
2664 If False, and the last element of the path is a symbolic link,
2665 stat will examine the symbolic link itself instead of the file
2666 the link points to.
2667
2668Perform a stat system call on the given path.
2669
2670dir_fd and follow_symlinks may not be implemented
2671 on your platform. If they are unavailable, using them will raise a
2672 NotImplementedError.
2673
2674It's an error to use dir_fd or follow_symlinks when specifying path as
2675 an open file descriptor.
2676
Larry Hastings61272b72014-01-07 12:41:53 -08002677[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002678
Larry Hastings31826802013-10-19 00:09:25 -07002679static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002680os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002681/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002682{
Victor Stinner1c2fa782020-05-10 11:05:29 +02002683 return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002684}
2685
Larry Hastings2f936352014-08-05 14:04:04 +10002686
2687/*[clinic input]
2688os.lstat
2689
2690 path : path_t
2691
2692 *
2693
2694 dir_fd : dir_fd(requires='fstatat') = None
2695
2696Perform a stat system call on the given path, without following symbolic links.
2697
2698Like stat(), but do not follow symbolic links.
2699Equivalent to stat(path, follow_symlinks=False).
2700[clinic start generated code]*/
2701
Larry Hastings2f936352014-08-05 14:04:04 +10002702static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002703os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2704/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002705{
2706 int follow_symlinks = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002707 return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10002708}
Larry Hastings31826802013-10-19 00:09:25 -07002709
Larry Hastings2f936352014-08-05 14:04:04 +10002710
Larry Hastings61272b72014-01-07 12:41:53 -08002711/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002712os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002713
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002714 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002715 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002716
2717 mode: int
2718 Operating-system mode bitfield. Can be F_OK to test existence,
2719 or the inclusive-OR of R_OK, W_OK, and X_OK.
2720
2721 *
2722
Larry Hastings2f936352014-08-05 14:04:04 +10002723 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002724 If not None, it should be a file descriptor open to a directory,
2725 and path should be relative; path will then be relative to that
2726 directory.
2727
2728 effective_ids: bool = False
2729 If True, access will use the effective uid/gid instead of
2730 the real uid/gid.
2731
2732 follow_symlinks: bool = True
2733 If False, and the last element of the path is a symbolic link,
2734 access will examine the symbolic link itself instead of the file
2735 the link points to.
2736
2737Use the real uid/gid to test for access to a path.
2738
2739{parameters}
2740dir_fd, effective_ids, and follow_symlinks may not be implemented
2741 on your platform. If they are unavailable, using them will raise a
2742 NotImplementedError.
2743
2744Note that most operations will use the effective uid/gid, therefore this
2745 routine can be used in a suid/sgid environment to test if the invoking user
2746 has the specified access to the path.
2747
Larry Hastings61272b72014-01-07 12:41:53 -08002748[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002749
Larry Hastings2f936352014-08-05 14:04:04 +10002750static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002751os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002752 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002753/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002754{
Larry Hastings2f936352014-08-05 14:04:04 +10002755 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002756
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002757#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002758 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002759#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002760 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002761#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002762
Larry Hastings9cf065c2012-06-22 16:30:09 -07002763#ifndef HAVE_FACCESSAT
2764 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002765 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002766
2767 if (effective_ids) {
2768 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002769 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002770 }
2771#endif
2772
2773#ifdef MS_WINDOWS
2774 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002775 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002776 Py_END_ALLOW_THREADS
2777
2778 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002779 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002780 * * we didn't get a -1, and
2781 * * write access wasn't requested,
2782 * * or the file isn't read-only,
2783 * * or it's a directory.
2784 * (Directories cannot be read-only on Windows.)
2785 */
Larry Hastings2f936352014-08-05 14:04:04 +10002786 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002787 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002789 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002790#else
2791
2792 Py_BEGIN_ALLOW_THREADS
2793#ifdef HAVE_FACCESSAT
2794 if ((dir_fd != DEFAULT_DIR_FD) ||
2795 effective_ids ||
2796 !follow_symlinks) {
2797 int flags = 0;
2798 if (!follow_symlinks)
2799 flags |= AT_SYMLINK_NOFOLLOW;
2800 if (effective_ids)
2801 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002802 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002803 }
2804 else
2805#endif
Larry Hastings31826802013-10-19 00:09:25 -07002806 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002807 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002808 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002809#endif
2810
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002812}
2813
Guido van Rossumd371ff11999-01-25 16:12:23 +00002814#ifndef F_OK
2815#define F_OK 0
2816#endif
2817#ifndef R_OK
2818#define R_OK 4
2819#endif
2820#ifndef W_OK
2821#define W_OK 2
2822#endif
2823#ifndef X_OK
2824#define X_OK 1
2825#endif
2826
Larry Hastings31826802013-10-19 00:09:25 -07002827
Guido van Rossumd371ff11999-01-25 16:12:23 +00002828#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002829/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002830os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002831
2832 fd: int
2833 Integer file descriptor handle.
2834
2835 /
2836
2837Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002838[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002839
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002840static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002841os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002842/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002843{
Guido van Rossum94f6f721999-01-06 18:42:14 +00002844
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002845 long size = sysconf(_SC_TTY_NAME_MAX);
2846 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002847 return posix_error();
2848 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002849 char *buffer = (char *)PyMem_RawMalloc(size);
2850 if (buffer == NULL) {
2851 return PyErr_NoMemory();
2852 }
2853 int ret = ttyname_r(fd, buffer, size);
2854 if (ret != 0) {
2855 PyMem_RawFree(buffer);
2856 errno = ret;
2857 return posix_error();
2858 }
2859 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
2860 PyMem_RawFree(buffer);
2861 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002862}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002863#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002864
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002865#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002866/*[clinic input]
2867os.ctermid
2868
2869Return the name of the controlling terminal for this process.
2870[clinic start generated code]*/
2871
Larry Hastings2f936352014-08-05 14:04:04 +10002872static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002873os_ctermid_impl(PyObject *module)
2874/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002875{
Victor Stinner8c62be82010-05-06 00:08:46 +00002876 char *ret;
2877 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002878
Greg Wardb48bc172000-03-01 21:51:56 +00002879#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002880 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002881#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002882 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002883#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002884 if (ret == NULL)
2885 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002886 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002887}
Larry Hastings2f936352014-08-05 14:04:04 +10002888#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002889
Larry Hastings2f936352014-08-05 14:04:04 +10002890
2891/*[clinic input]
2892os.chdir
2893
2894 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2895
2896Change the current working directory to the specified path.
2897
2898path may always be specified as a string.
2899On some platforms, path may also be specified as an open file descriptor.
2900 If this functionality is unavailable, using it raises an exception.
2901[clinic start generated code]*/
2902
Larry Hastings2f936352014-08-05 14:04:04 +10002903static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002904os_chdir_impl(PyObject *module, path_t *path)
2905/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002906{
2907 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002908
Saiyang Gou7514f4f2020-02-12 23:47:42 -08002909 if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
2910 return NULL;
2911 }
2912
Larry Hastings9cf065c2012-06-22 16:30:09 -07002913 Py_BEGIN_ALLOW_THREADS
2914#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002915 /* on unix, success = 0, on windows, success = !0 */
2916 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002917#else
2918#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002919 if (path->fd != -1)
2920 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002921 else
2922#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002923 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002924#endif
2925 Py_END_ALLOW_THREADS
2926
2927 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002928 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002929 }
2930
Larry Hastings2f936352014-08-05 14:04:04 +10002931 Py_RETURN_NONE;
2932}
2933
2934
2935#ifdef HAVE_FCHDIR
2936/*[clinic input]
2937os.fchdir
2938
2939 fd: fildes
2940
2941Change to the directory of the given file descriptor.
2942
2943fd must be opened on a directory, not a file.
2944Equivalent to os.chdir(fd).
2945
2946[clinic start generated code]*/
2947
Fred Drake4d1e64b2002-04-15 19:40:07 +00002948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002949os_fchdir_impl(PyObject *module, int fd)
2950/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002951{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08002952 if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
2953 return NULL;
2954 }
Larry Hastings2f936352014-08-05 14:04:04 +10002955 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002956}
2957#endif /* HAVE_FCHDIR */
2958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002959
Larry Hastings2f936352014-08-05 14:04:04 +10002960/*[clinic input]
2961os.chmod
2962
2963 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002964 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002965 On some platforms, path may also be specified as an open file descriptor.
2966 If this functionality is unavailable, using it raises an exception.
2967
2968 mode: int
2969 Operating-system mode bitfield.
2970
2971 *
2972
2973 dir_fd : dir_fd(requires='fchmodat') = None
2974 If not None, it should be a file descriptor open to a directory,
2975 and path should be relative; path will then be relative to that
2976 directory.
2977
2978 follow_symlinks: bool = True
2979 If False, and the last element of the path is a symbolic link,
2980 chmod will modify the symbolic link itself instead of the file
2981 the link points to.
2982
2983Change the access permissions of a file.
2984
2985It is an error to use dir_fd or follow_symlinks when specifying path as
2986 an open file descriptor.
2987dir_fd and follow_symlinks may not be implemented on your platform.
2988 If they are unavailable, using them will raise a NotImplementedError.
2989
2990[clinic start generated code]*/
2991
Larry Hastings2f936352014-08-05 14:04:04 +10002992static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002993os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002994 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002995/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002996{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002997 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002998
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002999#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003000 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003001#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003002
Larry Hastings9cf065c2012-06-22 16:30:09 -07003003#ifdef HAVE_FCHMODAT
3004 int fchmodat_nofollow_unsupported = 0;
3005#endif
3006
Larry Hastings9cf065c2012-06-22 16:30:09 -07003007#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3008 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003009 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003010#endif
3011
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003012 if (PySys_Audit("os.chmod", "Oii", path->object, mode,
3013 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3014 return NULL;
3015 }
3016
Larry Hastings9cf065c2012-06-22 16:30:09 -07003017#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003018 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003019 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003020 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003021 result = 0;
3022 else {
3023 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003024 attr &= ~FILE_ATTRIBUTE_READONLY;
3025 else
3026 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003027 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003028 }
3029 Py_END_ALLOW_THREADS
3030
3031 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003032 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003033 }
3034#else /* MS_WINDOWS */
3035 Py_BEGIN_ALLOW_THREADS
3036#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003037 if (path->fd != -1)
3038 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003039 else
3040#endif
3041#ifdef HAVE_LCHMOD
3042 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003043 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003044 else
3045#endif
3046#ifdef HAVE_FCHMODAT
3047 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
3048 /*
3049 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3050 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003051 * and then says it isn't implemented yet.
3052 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003053 *
3054 * Once it is supported, os.chmod will automatically
3055 * support dir_fd and follow_symlinks=False. (Hopefully.)
3056 * Until then, we need to be careful what exception we raise.
3057 */
Larry Hastings2f936352014-08-05 14:04:04 +10003058 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003059 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3060 /*
3061 * But wait! We can't throw the exception without allowing threads,
3062 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3063 */
3064 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003065 result &&
3066 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3067 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003068 }
3069 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003070#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003071 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003072 Py_END_ALLOW_THREADS
3073
3074 if (result) {
3075#ifdef HAVE_FCHMODAT
3076 if (fchmodat_nofollow_unsupported) {
3077 if (dir_fd != DEFAULT_DIR_FD)
3078 dir_fd_and_follow_symlinks_invalid("chmod",
3079 dir_fd, follow_symlinks);
3080 else
3081 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003082 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003083 }
3084 else
3085#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003086 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087 }
3088#endif
3089
Larry Hastings2f936352014-08-05 14:04:04 +10003090 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003091}
3092
Larry Hastings9cf065c2012-06-22 16:30:09 -07003093
Christian Heimes4e30a842007-11-30 22:12:06 +00003094#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003095/*[clinic input]
3096os.fchmod
3097
3098 fd: int
3099 mode: int
3100
3101Change the access permissions of the file given by file descriptor fd.
3102
3103Equivalent to os.chmod(fd, mode).
3104[clinic start generated code]*/
3105
Larry Hastings2f936352014-08-05 14:04:04 +10003106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003107os_fchmod_impl(PyObject *module, int fd, int mode)
3108/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003109{
3110 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003111 int async_err = 0;
3112
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003113 if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
3114 return NULL;
3115 }
3116
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003117 do {
3118 Py_BEGIN_ALLOW_THREADS
3119 res = fchmod(fd, mode);
3120 Py_END_ALLOW_THREADS
3121 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3122 if (res != 0)
3123 return (!async_err) ? posix_error() : NULL;
3124
Victor Stinner8c62be82010-05-06 00:08:46 +00003125 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003126}
3127#endif /* HAVE_FCHMOD */
3128
Larry Hastings2f936352014-08-05 14:04:04 +10003129
Christian Heimes4e30a842007-11-30 22:12:06 +00003130#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003131/*[clinic input]
3132os.lchmod
3133
3134 path: path_t
3135 mode: int
3136
3137Change the access permissions of a file, without following symbolic links.
3138
3139If path is a symlink, this affects the link itself rather than the target.
3140Equivalent to chmod(path, mode, follow_symlinks=False)."
3141[clinic start generated code]*/
3142
Larry Hastings2f936352014-08-05 14:04:04 +10003143static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003144os_lchmod_impl(PyObject *module, path_t *path, int mode)
3145/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003146{
Victor Stinner8c62be82010-05-06 00:08:46 +00003147 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003148 if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3149 return NULL;
3150 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003151 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003152 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003153 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003154 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003155 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003156 return NULL;
3157 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003158 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003159}
3160#endif /* HAVE_LCHMOD */
3161
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003162
Thomas Wouterscf297e42007-02-23 15:07:44 +00003163#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003164/*[clinic input]
3165os.chflags
3166
3167 path: path_t
3168 flags: unsigned_long(bitwise=True)
3169 follow_symlinks: bool=True
3170
3171Set file flags.
3172
3173If follow_symlinks is False, and the last element of the path is a symbolic
3174 link, chflags will change flags on the symbolic link itself instead of the
3175 file the link points to.
3176follow_symlinks may not be implemented on your platform. If it is
3177unavailable, using it will raise a NotImplementedError.
3178
3179[clinic start generated code]*/
3180
Larry Hastings2f936352014-08-05 14:04:04 +10003181static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003182os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003183 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003184/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003185{
3186 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003187
3188#ifndef HAVE_LCHFLAGS
3189 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003190 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003191#endif
3192
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003193 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3194 return NULL;
3195 }
3196
Victor Stinner8c62be82010-05-06 00:08:46 +00003197 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003198#ifdef HAVE_LCHFLAGS
3199 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003200 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003201 else
3202#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003203 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003204 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003205
Larry Hastings2f936352014-08-05 14:04:04 +10003206 if (result)
3207 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003208
Larry Hastings2f936352014-08-05 14:04:04 +10003209 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003210}
3211#endif /* HAVE_CHFLAGS */
3212
Larry Hastings2f936352014-08-05 14:04:04 +10003213
Thomas Wouterscf297e42007-02-23 15:07:44 +00003214#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003215/*[clinic input]
3216os.lchflags
3217
3218 path: path_t
3219 flags: unsigned_long(bitwise=True)
3220
3221Set file flags.
3222
3223This function will not follow symbolic links.
3224Equivalent to chflags(path, flags, follow_symlinks=False).
3225[clinic start generated code]*/
3226
Larry Hastings2f936352014-08-05 14:04:04 +10003227static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003228os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3229/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003230{
Victor Stinner8c62be82010-05-06 00:08:46 +00003231 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003232 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3233 return NULL;
3234 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003236 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003237 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003238 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003239 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003240 }
Victor Stinner292c8352012-10-30 02:17:38 +01003241 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003242}
3243#endif /* HAVE_LCHFLAGS */
3244
Larry Hastings2f936352014-08-05 14:04:04 +10003245
Martin v. Löwis244edc82001-10-04 22:44:26 +00003246#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003247/*[clinic input]
3248os.chroot
3249 path: path_t
3250
3251Change root directory to path.
3252
3253[clinic start generated code]*/
3254
Larry Hastings2f936352014-08-05 14:04:04 +10003255static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003256os_chroot_impl(PyObject *module, path_t *path)
3257/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003258{
3259 int res;
3260 Py_BEGIN_ALLOW_THREADS
3261 res = chroot(path->narrow);
3262 Py_END_ALLOW_THREADS
3263 if (res < 0)
3264 return path_error(path);
3265 Py_RETURN_NONE;
3266}
3267#endif /* HAVE_CHROOT */
3268
Martin v. Löwis244edc82001-10-04 22:44:26 +00003269
Guido van Rossum21142a01999-01-08 21:05:37 +00003270#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003271/*[clinic input]
3272os.fsync
3273
3274 fd: fildes
3275
3276Force write of fd to disk.
3277[clinic start generated code]*/
3278
Larry Hastings2f936352014-08-05 14:04:04 +10003279static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003280os_fsync_impl(PyObject *module, int fd)
3281/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003282{
3283 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003284}
3285#endif /* HAVE_FSYNC */
3286
Larry Hastings2f936352014-08-05 14:04:04 +10003287
Ross Lagerwall7807c352011-03-17 20:20:30 +02003288#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003289/*[clinic input]
3290os.sync
3291
3292Force write of everything to disk.
3293[clinic start generated code]*/
3294
Larry Hastings2f936352014-08-05 14:04:04 +10003295static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003296os_sync_impl(PyObject *module)
3297/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003298{
3299 Py_BEGIN_ALLOW_THREADS
3300 sync();
3301 Py_END_ALLOW_THREADS
3302 Py_RETURN_NONE;
3303}
Larry Hastings2f936352014-08-05 14:04:04 +10003304#endif /* HAVE_SYNC */
3305
Ross Lagerwall7807c352011-03-17 20:20:30 +02003306
Guido van Rossum21142a01999-01-08 21:05:37 +00003307#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003308#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003309extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3310#endif
3311
Larry Hastings2f936352014-08-05 14:04:04 +10003312/*[clinic input]
3313os.fdatasync
3314
3315 fd: fildes
3316
3317Force write of fd to disk without forcing update of metadata.
3318[clinic start generated code]*/
3319
Larry Hastings2f936352014-08-05 14:04:04 +10003320static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003321os_fdatasync_impl(PyObject *module, int fd)
3322/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003323{
3324 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003325}
3326#endif /* HAVE_FDATASYNC */
3327
3328
Fredrik Lundh10723342000-07-10 16:38:09 +00003329#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003330/*[clinic input]
3331os.chown
3332
3333 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003334 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003335
3336 uid: uid_t
3337
3338 gid: gid_t
3339
3340 *
3341
3342 dir_fd : dir_fd(requires='fchownat') = None
3343 If not None, it should be a file descriptor open to a directory,
3344 and path should be relative; path will then be relative to that
3345 directory.
3346
3347 follow_symlinks: bool = True
3348 If False, and the last element of the path is a symbolic link,
3349 stat will examine the symbolic link itself instead of the file
3350 the link points to.
3351
3352Change the owner and group id of path to the numeric uid and gid.\
3353
3354path may always be specified as a string.
3355On some platforms, path may also be specified as an open file descriptor.
3356 If this functionality is unavailable, using it raises an exception.
3357If dir_fd is not None, it should be a file descriptor open to a directory,
3358 and path should be relative; path will then be relative to that directory.
3359If follow_symlinks is False, and the last element of the path is a symbolic
3360 link, chown will modify the symbolic link itself instead of the file the
3361 link points to.
3362It is an error to use dir_fd or follow_symlinks when specifying path as
3363 an open file descriptor.
3364dir_fd and follow_symlinks may not be implemented on your platform.
3365 If they are unavailable, using them will raise a NotImplementedError.
3366
3367[clinic start generated code]*/
3368
Larry Hastings2f936352014-08-05 14:04:04 +10003369static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003370os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003371 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003372/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003373{
3374 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003375
3376#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3377 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003378 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003379#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003380 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3381 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3382 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003383
3384#ifdef __APPLE__
3385 /*
3386 * This is for Mac OS X 10.3, which doesn't have lchown.
3387 * (But we still have an lchown symbol because of weak-linking.)
3388 * It doesn't have fchownat either. So there's no possibility
3389 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003390 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003391 if ((!follow_symlinks) && (lchown == NULL)) {
3392 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003393 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003394 }
3395#endif
3396
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003397 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
3398 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3399 return NULL;
3400 }
3401
Victor Stinner8c62be82010-05-06 00:08:46 +00003402 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003403#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003404 if (path->fd != -1)
3405 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003406 else
3407#endif
3408#ifdef HAVE_LCHOWN
3409 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003410 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411 else
3412#endif
3413#ifdef HAVE_FCHOWNAT
3414 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003415 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3417 else
3418#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003419 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003420 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003421
Larry Hastings2f936352014-08-05 14:04:04 +10003422 if (result)
3423 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003424
Larry Hastings2f936352014-08-05 14:04:04 +10003425 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003426}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003427#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003428
Larry Hastings2f936352014-08-05 14:04:04 +10003429
Christian Heimes4e30a842007-11-30 22:12:06 +00003430#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003431/*[clinic input]
3432os.fchown
3433
3434 fd: int
3435 uid: uid_t
3436 gid: gid_t
3437
3438Change the owner and group id of the file specified by file descriptor.
3439
3440Equivalent to os.chown(fd, uid, gid).
3441
3442[clinic start generated code]*/
3443
Larry Hastings2f936352014-08-05 14:04:04 +10003444static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003445os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3446/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003447{
Victor Stinner8c62be82010-05-06 00:08:46 +00003448 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003449 int async_err = 0;
3450
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003451 if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
3452 return NULL;
3453 }
3454
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003455 do {
3456 Py_BEGIN_ALLOW_THREADS
3457 res = fchown(fd, uid, gid);
3458 Py_END_ALLOW_THREADS
3459 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3460 if (res != 0)
3461 return (!async_err) ? posix_error() : NULL;
3462
Victor Stinner8c62be82010-05-06 00:08:46 +00003463 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003464}
3465#endif /* HAVE_FCHOWN */
3466
Larry Hastings2f936352014-08-05 14:04:04 +10003467
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003468#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003469/*[clinic input]
3470os.lchown
3471
3472 path : path_t
3473 uid: uid_t
3474 gid: gid_t
3475
3476Change the owner and group id of path to the numeric uid and gid.
3477
3478This function will not follow symbolic links.
3479Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3480[clinic start generated code]*/
3481
Larry Hastings2f936352014-08-05 14:04:04 +10003482static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003483os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3484/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003485{
Victor Stinner8c62be82010-05-06 00:08:46 +00003486 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003487 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
3488 return NULL;
3489 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003491 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003492 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003493 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003494 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003495 }
Larry Hastings2f936352014-08-05 14:04:04 +10003496 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003497}
3498#endif /* HAVE_LCHOWN */
3499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003500
Barry Warsaw53699e91996-12-10 23:23:01 +00003501static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003502posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003503{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003504#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003505 wchar_t wbuf[MAXPATHLEN];
3506 wchar_t *wbuf2 = wbuf;
3507 DWORD len;
3508
3509 Py_BEGIN_ALLOW_THREADS
3510 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3511 /* If the buffer is large enough, len does not include the
3512 terminating \0. If the buffer is too small, len includes
3513 the space needed for the terminator. */
3514 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003515 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003516 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003517 }
Victor Stinner689830e2019-06-26 17:31:12 +02003518 else {
3519 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003520 }
Victor Stinner689830e2019-06-26 17:31:12 +02003521 if (wbuf2) {
3522 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 }
Victor Stinner689830e2019-06-26 17:31:12 +02003524 }
3525 Py_END_ALLOW_THREADS
3526
3527 if (!wbuf2) {
3528 PyErr_NoMemory();
3529 return NULL;
3530 }
3531 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003532 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003533 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003534 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003536
Victor Stinner689830e2019-06-26 17:31:12 +02003537 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3538 if (wbuf2 != wbuf) {
3539 PyMem_RawFree(wbuf2);
3540 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003541
Victor Stinner689830e2019-06-26 17:31:12 +02003542 if (use_bytes) {
3543 if (resobj == NULL) {
3544 return NULL;
3545 }
3546 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3547 }
3548
3549 return resobj;
3550#else
3551 const size_t chunk = 1024;
3552
3553 char *buf = NULL;
3554 char *cwd = NULL;
3555 size_t buflen = 0;
3556
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003558 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003559 char *newbuf;
3560 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3561 buflen += chunk;
3562 newbuf = PyMem_RawRealloc(buf, buflen);
3563 }
3564 else {
3565 newbuf = NULL;
3566 }
3567 if (newbuf == NULL) {
3568 PyMem_RawFree(buf);
3569 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003570 break;
3571 }
Victor Stinner689830e2019-06-26 17:31:12 +02003572 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003573
Victor Stinner4403d7d2015-04-25 00:16:10 +02003574 cwd = getcwd(buf, buflen);
3575 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003577
Victor Stinner689830e2019-06-26 17:31:12 +02003578 if (buf == NULL) {
3579 return PyErr_NoMemory();
3580 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003581 if (cwd == NULL) {
3582 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003583 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003584 }
3585
Victor Stinner689830e2019-06-26 17:31:12 +02003586 PyObject *obj;
3587 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003588 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003589 }
3590 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003591 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003592 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003593 PyMem_RawFree(buf);
3594
3595 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003596#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003597}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003598
Larry Hastings2f936352014-08-05 14:04:04 +10003599
3600/*[clinic input]
3601os.getcwd
3602
3603Return a unicode string representing the current working directory.
3604[clinic start generated code]*/
3605
Larry Hastings2f936352014-08-05 14:04:04 +10003606static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003607os_getcwd_impl(PyObject *module)
3608/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003609{
3610 return posix_getcwd(0);
3611}
3612
Larry Hastings2f936352014-08-05 14:04:04 +10003613
3614/*[clinic input]
3615os.getcwdb
3616
3617Return a bytes string representing the current working directory.
3618[clinic start generated code]*/
3619
Larry Hastings2f936352014-08-05 14:04:04 +10003620static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003621os_getcwdb_impl(PyObject *module)
3622/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003623{
3624 return posix_getcwd(1);
3625}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003626
Larry Hastings2f936352014-08-05 14:04:04 +10003627
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3629#define HAVE_LINK 1
3630#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003631
Guido van Rossumb6775db1994-08-01 11:34:53 +00003632#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003633/*[clinic input]
3634
3635os.link
3636
3637 src : path_t
3638 dst : path_t
3639 *
3640 src_dir_fd : dir_fd = None
3641 dst_dir_fd : dir_fd = None
3642 follow_symlinks: bool = True
3643
3644Create a hard link to a file.
3645
3646If either src_dir_fd or dst_dir_fd is not None, it should be a file
3647 descriptor open to a directory, and the respective path string (src or dst)
3648 should be relative; the path will then be relative to that directory.
3649If follow_symlinks is False, and the last element of src is a symbolic
3650 link, link will create a link to the symbolic link itself instead of the
3651 file the link points to.
3652src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3653 platform. If they are unavailable, using them will raise a
3654 NotImplementedError.
3655[clinic start generated code]*/
3656
Larry Hastings2f936352014-08-05 14:04:04 +10003657static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003658os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003659 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003660/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003661{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003662#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003663 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003664#else
3665 int result;
3666#endif
3667
Larry Hastings9cf065c2012-06-22 16:30:09 -07003668#ifndef HAVE_LINKAT
3669 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3670 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003671 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003672 }
3673#endif
3674
Steve Dowercc16be82016-09-08 10:35:16 -07003675#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003676 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003677 PyErr_SetString(PyExc_NotImplementedError,
3678 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003679 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003680 }
Steve Dowercc16be82016-09-08 10:35:16 -07003681#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003682
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003683 if (PySys_Audit("os.link", "OOii", src->object, dst->object,
3684 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
3685 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
3686 return NULL;
3687 }
3688
Brian Curtin1b9df392010-11-24 20:24:31 +00003689#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003690 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003691 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003692 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003693
Larry Hastings2f936352014-08-05 14:04:04 +10003694 if (!result)
3695 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003696#else
3697 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003698#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003699 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3700 (dst_dir_fd != DEFAULT_DIR_FD) ||
3701 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003702 result = linkat(src_dir_fd, src->narrow,
3703 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003704 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3705 else
Steve Dowercc16be82016-09-08 10:35:16 -07003706#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003707 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003708 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003709
Larry Hastings2f936352014-08-05 14:04:04 +10003710 if (result)
3711 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003712#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003713
Larry Hastings2f936352014-08-05 14:04:04 +10003714 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003715}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003716#endif
3717
Brian Curtin1b9df392010-11-24 20:24:31 +00003718
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003719#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003720static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003721_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003722{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003723 PyObject *v;
3724 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3725 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003726 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003727 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003728 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003729 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003730
Steve Dowercc16be82016-09-08 10:35:16 -07003731 WIN32_FIND_DATAW wFileData;
3732 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003733
Steve Dowercc16be82016-09-08 10:35:16 -07003734 if (!path->wide) { /* Default arg: "." */
3735 po_wchars = L".";
3736 len = 1;
3737 } else {
3738 po_wchars = path->wide;
3739 len = wcslen(path->wide);
3740 }
3741 /* The +5 is so we can append "\\*.*\0" */
3742 wnamebuf = PyMem_New(wchar_t, len + 5);
3743 if (!wnamebuf) {
3744 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003745 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003746 }
Steve Dowercc16be82016-09-08 10:35:16 -07003747 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003748 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003749 wchar_t wch = wnamebuf[len-1];
3750 if (wch != SEP && wch != ALTSEP && wch != L':')
3751 wnamebuf[len++] = SEP;
3752 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003753 }
Steve Dowercc16be82016-09-08 10:35:16 -07003754 if ((list = PyList_New(0)) == NULL) {
3755 goto exit;
3756 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003757 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003758 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003759 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003760 if (hFindFile == INVALID_HANDLE_VALUE) {
3761 int error = GetLastError();
3762 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003763 goto exit;
3764 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003765 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003766 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003767 }
3768 do {
3769 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003770 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3771 wcscmp(wFileData.cFileName, L"..") != 0) {
3772 v = PyUnicode_FromWideChar(wFileData.cFileName,
3773 wcslen(wFileData.cFileName));
3774 if (path->narrow && v) {
3775 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3776 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003777 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003778 Py_DECREF(list);
3779 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003780 break;
3781 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003782 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003783 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003784 Py_DECREF(list);
3785 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003786 break;
3787 }
3788 Py_DECREF(v);
3789 }
3790 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003791 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003792 Py_END_ALLOW_THREADS
3793 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3794 it got to the end of the directory. */
3795 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003796 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003797 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003798 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003799 }
3800 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003801
Larry Hastings9cf065c2012-06-22 16:30:09 -07003802exit:
3803 if (hFindFile != INVALID_HANDLE_VALUE) {
3804 if (FindClose(hFindFile) == FALSE) {
3805 if (list != NULL) {
3806 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003807 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003808 }
3809 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003810 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003811 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003812
Larry Hastings9cf065c2012-06-22 16:30:09 -07003813 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003814} /* end of _listdir_windows_no_opendir */
3815
3816#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3817
3818static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003819_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003820{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003821 PyObject *v;
3822 DIR *dirp = NULL;
3823 struct dirent *ep;
3824 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003825#ifdef HAVE_FDOPENDIR
3826 int fd = -1;
3827#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003828
Victor Stinner8c62be82010-05-06 00:08:46 +00003829 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003830#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003831 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003832 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003833 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003834 if (fd == -1)
3835 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003836
Larry Hastingsfdaea062012-06-25 04:42:23 -07003837 return_str = 1;
3838
Larry Hastings9cf065c2012-06-22 16:30:09 -07003839 Py_BEGIN_ALLOW_THREADS
3840 dirp = fdopendir(fd);
3841 Py_END_ALLOW_THREADS
3842 }
3843 else
3844#endif
3845 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003846 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003847 if (path->narrow) {
3848 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003849 /* only return bytes if they specified a bytes-like object */
3850 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003851 }
3852 else {
3853 name = ".";
3854 return_str = 1;
3855 }
3856
Larry Hastings9cf065c2012-06-22 16:30:09 -07003857 Py_BEGIN_ALLOW_THREADS
3858 dirp = opendir(name);
3859 Py_END_ALLOW_THREADS
3860 }
3861
3862 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003863 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003864#ifdef HAVE_FDOPENDIR
3865 if (fd != -1) {
3866 Py_BEGIN_ALLOW_THREADS
3867 close(fd);
3868 Py_END_ALLOW_THREADS
3869 }
3870#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003871 goto exit;
3872 }
3873 if ((list = PyList_New(0)) == NULL) {
3874 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003875 }
3876 for (;;) {
3877 errno = 0;
3878 Py_BEGIN_ALLOW_THREADS
3879 ep = readdir(dirp);
3880 Py_END_ALLOW_THREADS
3881 if (ep == NULL) {
3882 if (errno == 0) {
3883 break;
3884 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003885 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003886 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003887 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003888 }
3889 }
3890 if (ep->d_name[0] == '.' &&
3891 (NAMLEN(ep) == 1 ||
3892 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3893 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003894 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003895 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3896 else
3897 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003898 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003899 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003900 break;
3901 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003902 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003904 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003905 break;
3906 }
3907 Py_DECREF(v);
3908 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003909
Larry Hastings9cf065c2012-06-22 16:30:09 -07003910exit:
3911 if (dirp != NULL) {
3912 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003913#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003914 if (fd > -1)
3915 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003916#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003917 closedir(dirp);
3918 Py_END_ALLOW_THREADS
3919 }
3920
Larry Hastings9cf065c2012-06-22 16:30:09 -07003921 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003922} /* end of _posix_listdir */
3923#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003924
Larry Hastings2f936352014-08-05 14:04:04 +10003925
3926/*[clinic input]
3927os.listdir
3928
3929 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3930
3931Return a list containing the names of the files in the directory.
3932
BNMetricsb9427072018-11-02 15:20:19 +00003933path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003934 the filenames returned will also be bytes; in all other circumstances
3935 the filenames returned will be str.
3936If path is None, uses the path='.'.
3937On some platforms, path may also be specified as an open file descriptor;\
3938 the file descriptor must refer to a directory.
3939 If this functionality is unavailable, using it raises NotImplementedError.
3940
3941The list is in arbitrary order. It does not include the special
3942entries '.' and '..' even if they are present in the directory.
3943
3944
3945[clinic start generated code]*/
3946
Larry Hastings2f936352014-08-05 14:04:04 +10003947static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003948os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003949/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003950{
Steve Dower60419a72019-06-24 08:42:54 -07003951 if (PySys_Audit("os.listdir", "O",
3952 path->object ? path->object : Py_None) < 0) {
3953 return NULL;
3954 }
Larry Hastings2f936352014-08-05 14:04:04 +10003955#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3956 return _listdir_windows_no_opendir(path, NULL);
3957#else
3958 return _posix_listdir(path, NULL);
3959#endif
3960}
3961
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003962#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003963/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003964/*[clinic input]
3965os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003966
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003967 path: path_t
3968 /
3969
3970[clinic start generated code]*/
3971
3972static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003973os__getfullpathname_impl(PyObject *module, path_t *path)
3974/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003975{
Victor Stinner3939c322019-06-25 15:02:43 +02003976 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003977
Victor Stinner3939c322019-06-25 15:02:43 +02003978 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
3979 if (_Py_abspath(path->wide, &abspath) < 0) {
3980 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003981 }
Victor Stinner3939c322019-06-25 15:02:43 +02003982 if (abspath == NULL) {
3983 return PyErr_NoMemory();
3984 }
3985
3986 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
3987 PyMem_RawFree(abspath);
3988 if (str == NULL) {
3989 return NULL;
3990 }
3991 if (path->narrow) {
3992 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
3993 }
3994 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10003995}
Brian Curtind40e6f72010-07-08 21:39:08 +00003996
Brian Curtind25aef52011-06-13 15:16:04 -05003997
Larry Hastings2f936352014-08-05 14:04:04 +10003998/*[clinic input]
3999os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004000
Steve Dower23ad6d02018-02-22 10:39:10 -08004001 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004002 /
4003
4004A helper function for samepath on windows.
4005[clinic start generated code]*/
4006
Larry Hastings2f936352014-08-05 14:04:04 +10004007static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004008os__getfinalpathname_impl(PyObject *module, path_t *path)
4009/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004010{
4011 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004012 wchar_t buf[MAXPATHLEN], *target_path = buf;
4013 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00004014 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004015 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004016
Steve Dower23ad6d02018-02-22 10:39:10 -08004017 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004018 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08004019 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004020 0, /* desired access */
4021 0, /* share mode */
4022 NULL, /* security attributes */
4023 OPEN_EXISTING,
4024 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4025 FILE_FLAG_BACKUP_SEMANTICS,
4026 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004027 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004028
Steve Dower23ad6d02018-02-22 10:39:10 -08004029 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004030 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004031 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004032
4033 /* We have a good handle to the target, use it to determine the
4034 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004035 while (1) {
4036 Py_BEGIN_ALLOW_THREADS
4037 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4038 buf_size, VOLUME_NAME_DOS);
4039 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004040
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004041 if (!result_length) {
4042 result = win32_error_object("GetFinalPathNameByHandleW",
4043 path->object);
4044 goto cleanup;
4045 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004046
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004047 if (result_length < buf_size) {
4048 break;
4049 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004050
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004051 wchar_t *tmp;
4052 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4053 result_length * sizeof(*tmp));
4054 if (!tmp) {
4055 result = PyErr_NoMemory();
4056 goto cleanup;
4057 }
4058
4059 buf_size = result_length;
4060 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004061 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004062
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004063 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004064 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004065 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004066 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004067
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004068cleanup:
4069 if (target_path != buf) {
4070 PyMem_Free(target_path);
4071 }
4072 CloseHandle(hFile);
4073 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004074}
Brian Curtin62857742010-09-06 17:07:27 +00004075
Tim Golden6b528062013-08-01 12:44:00 +01004076
Larry Hastings2f936352014-08-05 14:04:04 +10004077/*[clinic input]
4078os._getvolumepathname
4079
Steve Dower23ad6d02018-02-22 10:39:10 -08004080 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004081
4082A helper function for ismount on Win32.
4083[clinic start generated code]*/
4084
Larry Hastings2f936352014-08-05 14:04:04 +10004085static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004086os__getvolumepathname_impl(PyObject *module, path_t *path)
4087/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004088{
4089 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004090 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004091 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004092 BOOL ret;
4093
Tim Golden6b528062013-08-01 12:44:00 +01004094 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004095 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004096
Victor Stinner850a18e2017-10-24 16:53:32 -07004097 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004098 PyErr_SetString(PyExc_OverflowError, "path too long");
4099 return NULL;
4100 }
4101
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004102 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004103 if (mountpath == NULL)
4104 return PyErr_NoMemory();
4105
4106 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004107 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004108 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004109 Py_END_ALLOW_THREADS
4110
4111 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004112 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004113 goto exit;
4114 }
4115 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004116 if (path->narrow)
4117 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004118
4119exit:
4120 PyMem_Free(mountpath);
4121 return result;
4122}
Tim Golden6b528062013-08-01 12:44:00 +01004123
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004124#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004125
Larry Hastings2f936352014-08-05 14:04:04 +10004126
4127/*[clinic input]
4128os.mkdir
4129
4130 path : path_t
4131
4132 mode: int = 0o777
4133
4134 *
4135
4136 dir_fd : dir_fd(requires='mkdirat') = None
4137
4138# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4139
4140Create a directory.
4141
4142If dir_fd is not None, it should be a file descriptor open to a directory,
4143 and path should be relative; path will then be relative to that directory.
4144dir_fd may not be implemented on your platform.
4145 If it is unavailable, using it will raise a NotImplementedError.
4146
4147The mode argument is ignored on Windows.
4148[clinic start generated code]*/
4149
Larry Hastings2f936352014-08-05 14:04:04 +10004150static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004151os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4152/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004153{
4154 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004155
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004156 if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
4157 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4158 return NULL;
4159 }
4160
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004161#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004162 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004163 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004165
Larry Hastings2f936352014-08-05 14:04:04 +10004166 if (!result)
4167 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004168#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004169 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004170#if HAVE_MKDIRAT
4171 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004172 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004173 else
4174#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004175#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004176 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004177#else
Larry Hastings2f936352014-08-05 14:04:04 +10004178 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004179#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004180 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004181 if (result < 0)
4182 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004183#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004184 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004185}
4186
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004187
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004188/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4189#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004190#include <sys/resource.h>
4191#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004192
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004193
4194#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004195/*[clinic input]
4196os.nice
4197
4198 increment: int
4199 /
4200
4201Add increment to the priority of process and return the new priority.
4202[clinic start generated code]*/
4203
Larry Hastings2f936352014-08-05 14:04:04 +10004204static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004205os_nice_impl(PyObject *module, int increment)
4206/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004207{
4208 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004209
Victor Stinner8c62be82010-05-06 00:08:46 +00004210 /* There are two flavours of 'nice': one that returns the new
4211 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004212 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004213 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004214
Victor Stinner8c62be82010-05-06 00:08:46 +00004215 If we are of the nice family that returns the new priority, we
4216 need to clear errno before the call, and check if errno is filled
4217 before calling posix_error() on a returnvalue of -1, because the
4218 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004219
Victor Stinner8c62be82010-05-06 00:08:46 +00004220 errno = 0;
4221 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004222#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004223 if (value == 0)
4224 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004225#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004226 if (value == -1 && errno != 0)
4227 /* either nice() or getpriority() returned an error */
4228 return posix_error();
4229 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004230}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004231#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004232
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004233
4234#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004235/*[clinic input]
4236os.getpriority
4237
4238 which: int
4239 who: int
4240
4241Return program scheduling priority.
4242[clinic start generated code]*/
4243
Larry Hastings2f936352014-08-05 14:04:04 +10004244static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004245os_getpriority_impl(PyObject *module, int which, int who)
4246/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004247{
4248 int retval;
4249
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004250 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004251 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004252 if (errno != 0)
4253 return posix_error();
4254 return PyLong_FromLong((long)retval);
4255}
4256#endif /* HAVE_GETPRIORITY */
4257
4258
4259#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004260/*[clinic input]
4261os.setpriority
4262
4263 which: int
4264 who: int
4265 priority: int
4266
4267Set program scheduling priority.
4268[clinic start generated code]*/
4269
Larry Hastings2f936352014-08-05 14:04:04 +10004270static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004271os_setpriority_impl(PyObject *module, int which, int who, int priority)
4272/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004273{
4274 int retval;
4275
4276 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004277 if (retval == -1)
4278 return posix_error();
4279 Py_RETURN_NONE;
4280}
4281#endif /* HAVE_SETPRIORITY */
4282
4283
Barry Warsaw53699e91996-12-10 23:23:01 +00004284static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004285internal_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 +00004286{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004287 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004288 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004289
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004290#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004291 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004292 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004293#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004294 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004295#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004296
Larry Hastings9cf065c2012-06-22 16:30:09 -07004297 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4298 (dst_dir_fd != DEFAULT_DIR_FD);
4299#ifndef HAVE_RENAMEAT
4300 if (dir_fd_specified) {
4301 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004302 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004303 }
4304#endif
4305
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004306 if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
4307 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
4308 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
4309 return NULL;
4310 }
4311
Larry Hastings9cf065c2012-06-22 16:30:09 -07004312#ifdef MS_WINDOWS
4313 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004314 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004315 Py_END_ALLOW_THREADS
4316
Larry Hastings2f936352014-08-05 14:04:04 +10004317 if (!result)
4318 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004319
4320#else
Steve Dowercc16be82016-09-08 10:35:16 -07004321 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4322 PyErr_Format(PyExc_ValueError,
4323 "%s: src and dst must be the same type", function_name);
4324 return NULL;
4325 }
4326
Larry Hastings9cf065c2012-06-22 16:30:09 -07004327 Py_BEGIN_ALLOW_THREADS
4328#ifdef HAVE_RENAMEAT
4329 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004330 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004331 else
4332#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004333 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004334 Py_END_ALLOW_THREADS
4335
Larry Hastings2f936352014-08-05 14:04:04 +10004336 if (result)
4337 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004338#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004339 Py_RETURN_NONE;
4340}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004341
Larry Hastings2f936352014-08-05 14:04:04 +10004342
4343/*[clinic input]
4344os.rename
4345
4346 src : path_t
4347 dst : path_t
4348 *
4349 src_dir_fd : dir_fd = None
4350 dst_dir_fd : dir_fd = None
4351
4352Rename a file or directory.
4353
4354If either src_dir_fd or dst_dir_fd is not None, it should be a file
4355 descriptor open to a directory, and the respective path string (src or dst)
4356 should be relative; the path will then be relative to that directory.
4357src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4358 If they are unavailable, using them will raise a NotImplementedError.
4359[clinic start generated code]*/
4360
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004361static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004362os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004363 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004364/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004365{
Larry Hastings2f936352014-08-05 14:04:04 +10004366 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004367}
4368
Larry Hastings2f936352014-08-05 14:04:04 +10004369
4370/*[clinic input]
4371os.replace = os.rename
4372
4373Rename a file or directory, overwriting the destination.
4374
4375If either src_dir_fd or dst_dir_fd is not None, it should be a file
4376 descriptor open to a directory, and the respective path string (src or dst)
4377 should be relative; the path will then be relative to that directory.
4378src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004379 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004380[clinic start generated code]*/
4381
Larry Hastings2f936352014-08-05 14:04:04 +10004382static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004383os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4384 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004385/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004386{
4387 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4388}
4389
4390
4391/*[clinic input]
4392os.rmdir
4393
4394 path: path_t
4395 *
4396 dir_fd: dir_fd(requires='unlinkat') = None
4397
4398Remove a directory.
4399
4400If dir_fd is not None, it should be a file descriptor open to a directory,
4401 and path should be relative; path will then be relative to that directory.
4402dir_fd may not be implemented on your platform.
4403 If it is unavailable, using it will raise a NotImplementedError.
4404[clinic start generated code]*/
4405
Larry Hastings2f936352014-08-05 14:04:04 +10004406static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004407os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4408/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004409{
4410 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004411
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004412 if (PySys_Audit("os.rmdir", "Oi", path->object,
4413 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4414 return NULL;
4415 }
4416
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004417 Py_BEGIN_ALLOW_THREADS
4418#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004419 /* Windows, success=1, UNIX, success=0 */
4420 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004421#else
4422#ifdef HAVE_UNLINKAT
4423 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004424 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004425 else
4426#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004427 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004428#endif
4429 Py_END_ALLOW_THREADS
4430
Larry Hastings2f936352014-08-05 14:04:04 +10004431 if (result)
4432 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004433
Larry Hastings2f936352014-08-05 14:04:04 +10004434 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004435}
4436
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004437
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004438#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004439#ifdef MS_WINDOWS
4440/*[clinic input]
4441os.system -> long
4442
4443 command: Py_UNICODE
4444
4445Execute the command in a subshell.
4446[clinic start generated code]*/
4447
Larry Hastings2f936352014-08-05 14:04:04 +10004448static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004449os_system_impl(PyObject *module, const Py_UNICODE *command)
4450/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004451{
4452 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004453
Steve Dowerfbe3c762019-10-18 00:52:15 -07004454 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004455 return -1;
4456 }
4457
Victor Stinner8c62be82010-05-06 00:08:46 +00004458 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004459 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004460 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004461 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004462 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004463 return result;
4464}
4465#else /* MS_WINDOWS */
4466/*[clinic input]
4467os.system -> long
4468
4469 command: FSConverter
4470
4471Execute the command in a subshell.
4472[clinic start generated code]*/
4473
Larry Hastings2f936352014-08-05 14:04:04 +10004474static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004475os_system_impl(PyObject *module, PyObject *command)
4476/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004477{
4478 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004479 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004480
Steve Dowerfbe3c762019-10-18 00:52:15 -07004481 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004482 return -1;
4483 }
4484
Larry Hastings2f936352014-08-05 14:04:04 +10004485 Py_BEGIN_ALLOW_THREADS
4486 result = system(bytes);
4487 Py_END_ALLOW_THREADS
4488 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004489}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004490#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004491#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004492
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004493
Larry Hastings2f936352014-08-05 14:04:04 +10004494/*[clinic input]
4495os.umask
4496
4497 mask: int
4498 /
4499
4500Set the current numeric umask and return the previous umask.
4501[clinic start generated code]*/
4502
Larry Hastings2f936352014-08-05 14:04:04 +10004503static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004504os_umask_impl(PyObject *module, int mask)
4505/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004506{
4507 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004508 if (i < 0)
4509 return posix_error();
4510 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004511}
4512
Brian Curtind40e6f72010-07-08 21:39:08 +00004513#ifdef MS_WINDOWS
4514
4515/* override the default DeleteFileW behavior so that directory
4516symlinks can be removed with this function, the same as with
4517Unix symlinks */
4518BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4519{
4520 WIN32_FILE_ATTRIBUTE_DATA info;
4521 WIN32_FIND_DATAW find_data;
4522 HANDLE find_data_handle;
4523 int is_directory = 0;
4524 int is_link = 0;
4525
4526 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4527 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004528
Brian Curtind40e6f72010-07-08 21:39:08 +00004529 /* Get WIN32_FIND_DATA structure for the path to determine if
4530 it is a symlink */
4531 if(is_directory &&
4532 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4533 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4534
4535 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004536 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4537 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4538 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4539 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004540 FindClose(find_data_handle);
4541 }
4542 }
4543 }
4544
4545 if (is_directory && is_link)
4546 return RemoveDirectoryW(lpFileName);
4547
4548 return DeleteFileW(lpFileName);
4549}
4550#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004551
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004552
Larry Hastings2f936352014-08-05 14:04:04 +10004553/*[clinic input]
4554os.unlink
4555
4556 path: path_t
4557 *
4558 dir_fd: dir_fd(requires='unlinkat')=None
4559
4560Remove a file (same as remove()).
4561
4562If dir_fd is not None, it should be a file descriptor open to a directory,
4563 and path should be relative; path will then be relative to that directory.
4564dir_fd may not be implemented on your platform.
4565 If it is unavailable, using it will raise a NotImplementedError.
4566
4567[clinic start generated code]*/
4568
Larry Hastings2f936352014-08-05 14:04:04 +10004569static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004570os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4571/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004572{
4573 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004575 if (PySys_Audit("os.remove", "Oi", path->object,
4576 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4577 return NULL;
4578 }
4579
Larry Hastings9cf065c2012-06-22 16:30:09 -07004580 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004581 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004583 /* Windows, success=1, UNIX, success=0 */
4584 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004585#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586#ifdef HAVE_UNLINKAT
4587 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004588 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004589 else
4590#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004591 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004593 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004594 Py_END_ALLOW_THREADS
4595
Larry Hastings2f936352014-08-05 14:04:04 +10004596 if (result)
4597 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598
Larry Hastings2f936352014-08-05 14:04:04 +10004599 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004600}
4601
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004602
Larry Hastings2f936352014-08-05 14:04:04 +10004603/*[clinic input]
4604os.remove = os.unlink
4605
4606Remove a file (same as unlink()).
4607
4608If dir_fd is not None, it should be a file descriptor open to a directory,
4609 and path should be relative; path will then be relative to that directory.
4610dir_fd may not be implemented on your platform.
4611 If it is unavailable, using it will raise a NotImplementedError.
4612[clinic start generated code]*/
4613
Larry Hastings2f936352014-08-05 14:04:04 +10004614static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004615os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4616/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004617{
4618 return os_unlink_impl(module, path, dir_fd);
4619}
4620
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004621
Larry Hastings605a62d2012-06-24 04:33:36 -07004622static PyStructSequence_Field uname_result_fields[] = {
4623 {"sysname", "operating system name"},
4624 {"nodename", "name of machine on network (implementation-defined)"},
4625 {"release", "operating system release"},
4626 {"version", "operating system version"},
4627 {"machine", "hardware identifier"},
4628 {NULL}
4629};
4630
4631PyDoc_STRVAR(uname_result__doc__,
4632"uname_result: Result from os.uname().\n\n\
4633This object may be accessed either as a tuple of\n\
4634 (sysname, nodename, release, version, machine),\n\
4635or via the attributes sysname, nodename, release, version, and machine.\n\
4636\n\
4637See os.uname for more information.");
4638
4639static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08004640 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07004641 uname_result__doc__, /* doc */
4642 uname_result_fields,
4643 5
4644};
4645
Larry Hastings605a62d2012-06-24 04:33:36 -07004646#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004647/*[clinic input]
4648os.uname
4649
4650Return an object identifying the current operating system.
4651
4652The object behaves like a named tuple with the following fields:
4653 (sysname, nodename, release, version, machine)
4654
4655[clinic start generated code]*/
4656
Larry Hastings2f936352014-08-05 14:04:04 +10004657static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004658os_uname_impl(PyObject *module)
4659/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004660{
Victor Stinner8c62be82010-05-06 00:08:46 +00004661 struct utsname u;
4662 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004663 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004664
Victor Stinner8c62be82010-05-06 00:08:46 +00004665 Py_BEGIN_ALLOW_THREADS
4666 res = uname(&u);
4667 Py_END_ALLOW_THREADS
4668 if (res < 0)
4669 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004670
Hai Shif707d942020-03-16 21:15:01 +08004671 PyObject *UnameResultType = get_posix_state(module)->UnameResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08004672 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004673 if (value == NULL)
4674 return NULL;
4675
4676#define SET(i, field) \
4677 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004678 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004679 if (!o) { \
4680 Py_DECREF(value); \
4681 return NULL; \
4682 } \
4683 PyStructSequence_SET_ITEM(value, i, o); \
4684 } \
4685
4686 SET(0, u.sysname);
4687 SET(1, u.nodename);
4688 SET(2, u.release);
4689 SET(3, u.version);
4690 SET(4, u.machine);
4691
4692#undef SET
4693
4694 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004695}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004696#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004697
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004698
Larry Hastings9cf065c2012-06-22 16:30:09 -07004699
4700typedef struct {
4701 int now;
4702 time_t atime_s;
4703 long atime_ns;
4704 time_t mtime_s;
4705 long mtime_ns;
4706} utime_t;
4707
4708/*
Victor Stinner484df002014-10-09 13:52:31 +02004709 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004710 * they also intentionally leak the declaration of a pointer named "time"
4711 */
4712#define UTIME_TO_TIMESPEC \
4713 struct timespec ts[2]; \
4714 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004715 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004716 time = NULL; \
4717 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004718 ts[0].tv_sec = ut->atime_s; \
4719 ts[0].tv_nsec = ut->atime_ns; \
4720 ts[1].tv_sec = ut->mtime_s; \
4721 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722 time = ts; \
4723 } \
4724
4725#define UTIME_TO_TIMEVAL \
4726 struct timeval tv[2]; \
4727 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004728 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004729 time = NULL; \
4730 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004731 tv[0].tv_sec = ut->atime_s; \
4732 tv[0].tv_usec = ut->atime_ns / 1000; \
4733 tv[1].tv_sec = ut->mtime_s; \
4734 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004735 time = tv; \
4736 } \
4737
4738#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004739 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004740 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004741 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742 time = NULL; \
4743 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004744 u.actime = ut->atime_s; \
4745 u.modtime = ut->mtime_s; \
4746 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747 }
4748
4749#define UTIME_TO_TIME_T \
4750 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004751 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004752 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 time = NULL; \
4754 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004755 timet[0] = ut->atime_s; \
4756 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004757 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 } \
4759
4760
Victor Stinner528a9ab2015-09-03 21:30:26 +02004761#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762
4763static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004764utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765{
4766#ifdef HAVE_UTIMENSAT
4767 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4768 UTIME_TO_TIMESPEC;
4769 return utimensat(dir_fd, path, time, flags);
4770#elif defined(HAVE_FUTIMESAT)
4771 UTIME_TO_TIMEVAL;
4772 /*
4773 * follow_symlinks will never be false here;
4774 * we only allow !follow_symlinks and dir_fd together
4775 * if we have utimensat()
4776 */
4777 assert(follow_symlinks);
4778 return futimesat(dir_fd, path, time);
4779#endif
4780}
4781
Larry Hastings2f936352014-08-05 14:04:04 +10004782 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4783#else
4784 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004785#endif
4786
Victor Stinner528a9ab2015-09-03 21:30:26 +02004787#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004788
4789static int
Victor Stinner484df002014-10-09 13:52:31 +02004790utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004791{
4792#ifdef HAVE_FUTIMENS
4793 UTIME_TO_TIMESPEC;
4794 return futimens(fd, time);
4795#else
4796 UTIME_TO_TIMEVAL;
4797 return futimes(fd, time);
4798#endif
4799}
4800
Larry Hastings2f936352014-08-05 14:04:04 +10004801 #define PATH_UTIME_HAVE_FD 1
4802#else
4803 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804#endif
4805
Victor Stinner5ebae872015-09-22 01:29:33 +02004806#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4807# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4808#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809
Victor Stinner4552ced2015-09-21 22:37:15 +02004810#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811
4812static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004813utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004814{
4815#ifdef HAVE_UTIMENSAT
4816 UTIME_TO_TIMESPEC;
4817 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4818#else
4819 UTIME_TO_TIMEVAL;
4820 return lutimes(path, time);
4821#endif
4822}
4823
4824#endif
4825
4826#ifndef MS_WINDOWS
4827
4828static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004829utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004830{
4831#ifdef HAVE_UTIMENSAT
4832 UTIME_TO_TIMESPEC;
4833 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4834#elif defined(HAVE_UTIMES)
4835 UTIME_TO_TIMEVAL;
4836 return utimes(path, time);
4837#elif defined(HAVE_UTIME_H)
4838 UTIME_TO_UTIMBUF;
4839 return utime(path, time);
4840#else
4841 UTIME_TO_TIME_T;
4842 return utime(path, time);
4843#endif
4844}
4845
4846#endif
4847
Larry Hastings76ad59b2012-05-03 00:30:07 -07004848static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02004849split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004850{
4851 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004852 PyObject *divmod;
Victor Stinner1c2fa782020-05-10 11:05:29 +02004853 divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07004854 if (!divmod)
4855 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004856 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4857 PyErr_Format(PyExc_TypeError,
4858 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08004859 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004860 goto exit;
4861 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004862 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4863 if ((*s == -1) && PyErr_Occurred())
4864 goto exit;
4865 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004866 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004867 goto exit;
4868
4869 result = 1;
4870exit:
4871 Py_XDECREF(divmod);
4872 return result;
4873}
4874
Larry Hastings2f936352014-08-05 14:04:04 +10004875
4876/*[clinic input]
4877os.utime
4878
4879 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004880 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10004881 *
4882 ns: object = NULL
4883 dir_fd: dir_fd(requires='futimensat') = None
4884 follow_symlinks: bool=True
4885
Martin Panter0ff89092015-09-09 01:56:53 +00004886# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004887
4888Set the access and modified time of path.
4889
4890path may always be specified as a string.
4891On some platforms, path may also be specified as an open file descriptor.
4892 If this functionality is unavailable, using it raises an exception.
4893
4894If times is not None, it must be a tuple (atime, mtime);
4895 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004896If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004897 atime_ns and mtime_ns should be expressed as integer nanoseconds
4898 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004899If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004900Specifying tuples for both times and ns is an error.
4901
4902If dir_fd is not None, it should be a file descriptor open to a directory,
4903 and path should be relative; path will then be relative to that directory.
4904If follow_symlinks is False, and the last element of the path is a symbolic
4905 link, utime will modify the symbolic link itself instead of the file the
4906 link points to.
4907It is an error to use dir_fd or follow_symlinks when specifying path
4908 as an open file descriptor.
4909dir_fd and follow_symlinks may not be available on your platform.
4910 If they are unavailable, using them will raise a NotImplementedError.
4911
4912[clinic start generated code]*/
4913
Larry Hastings2f936352014-08-05 14:04:04 +10004914static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004915os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4916 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004917/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004918{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004919#ifdef MS_WINDOWS
4920 HANDLE hFile;
4921 FILETIME atime, mtime;
4922#else
4923 int result;
4924#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004925
Larry Hastings2f936352014-08-05 14:04:04 +10004926 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004927
Christian Heimesb3c87242013-08-01 00:08:16 +02004928 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004929
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004930 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004931 PyErr_SetString(PyExc_ValueError,
4932 "utime: you may specify either 'times'"
4933 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004934 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004935 }
4936
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004937 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004938 time_t a_sec, m_sec;
4939 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004940 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004941 PyErr_SetString(PyExc_TypeError,
4942 "utime: 'times' must be either"
4943 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004944 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004945 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004946 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004947 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004948 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004949 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004950 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004951 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004952 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004953 utime.atime_s = a_sec;
4954 utime.atime_ns = a_nsec;
4955 utime.mtime_s = m_sec;
4956 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004957 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004958 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004959 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004960 PyErr_SetString(PyExc_TypeError,
4961 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004962 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004963 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004964 utime.now = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02004965 if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004966 &utime.atime_s, &utime.atime_ns) ||
Victor Stinner1c2fa782020-05-10 11:05:29 +02004967 !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004969 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004970 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004971 }
4972 else {
4973 /* times and ns are both None/unspecified. use "now". */
4974 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004975 }
4976
Victor Stinner4552ced2015-09-21 22:37:15 +02004977#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004978 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004979 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004980#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004981
Larry Hastings2f936352014-08-05 14:04:04 +10004982 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4983 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4984 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004985 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004986
Larry Hastings9cf065c2012-06-22 16:30:09 -07004987#if !defined(HAVE_UTIMENSAT)
4988 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004989 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004990 "utime: cannot use dir_fd and follow_symlinks "
4991 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004992 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004993 }
4994#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004995
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004996 if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
4997 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4998 return NULL;
4999 }
5000
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005001#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005002 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005003 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5004 NULL, OPEN_EXISTING,
5005 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005006 Py_END_ALLOW_THREADS
5007 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10005008 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005009 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005010 }
5011
Larry Hastings9cf065c2012-06-22 16:30:09 -07005012 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005013 GetSystemTimeAsFileTime(&mtime);
5014 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005015 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005016 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08005017 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5018 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005019 }
5020 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5021 /* Avoid putting the file name into the error here,
5022 as that may confuse the user into believing that
5023 something is wrong with the file, when it also
5024 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005025 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005026 CloseHandle(hFile);
5027 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005028 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005029 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005030#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005031 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005032
Victor Stinner4552ced2015-09-21 22:37:15 +02005033#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005034 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10005035 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005036 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005037#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005038
Victor Stinner528a9ab2015-09-03 21:30:26 +02005039#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005040 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10005041 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005042 else
5043#endif
5044
Victor Stinner528a9ab2015-09-03 21:30:26 +02005045#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005046 if (path->fd != -1)
5047 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005048 else
5049#endif
5050
Larry Hastings2f936352014-08-05 14:04:04 +10005051 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005052
5053 Py_END_ALLOW_THREADS
5054
5055 if (result < 0) {
5056 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005057 posix_error();
5058 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005059 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005060
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005061#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005062
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005063 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005064}
5065
Guido van Rossum3b066191991-06-04 19:40:25 +00005066/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005067
Larry Hastings2f936352014-08-05 14:04:04 +10005068
5069/*[clinic input]
5070os._exit
5071
5072 status: int
5073
5074Exit to the system with specified status, without normal exit processing.
5075[clinic start generated code]*/
5076
Larry Hastings2f936352014-08-05 14:04:04 +10005077static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005078os__exit_impl(PyObject *module, int status)
5079/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005080{
5081 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005082 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005083}
5084
Steve Dowercc16be82016-09-08 10:35:16 -07005085#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5086#define EXECV_CHAR wchar_t
5087#else
5088#define EXECV_CHAR char
5089#endif
5090
pxinwrf2d7ac72019-05-21 18:46:37 +08005091#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005092static void
Steve Dowercc16be82016-09-08 10:35:16 -07005093free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005094{
Victor Stinner8c62be82010-05-06 00:08:46 +00005095 Py_ssize_t i;
5096 for (i = 0; i < count; i++)
5097 PyMem_Free(array[i]);
5098 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005099}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005100
Berker Peksag81816462016-09-15 20:19:47 +03005101static int
5102fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005103{
Victor Stinner8c62be82010-05-06 00:08:46 +00005104 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005105 PyObject *ub;
5106 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005107#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005108 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005109 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005110 *out = PyUnicode_AsWideCharString(ub, &size);
5111 if (*out)
5112 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005113#else
Berker Peksag81816462016-09-15 20:19:47 +03005114 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005115 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005116 size = PyBytes_GET_SIZE(ub);
5117 *out = PyMem_Malloc(size + 1);
5118 if (*out) {
5119 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5120 result = 1;
5121 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005122 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005123#endif
Berker Peksag81816462016-09-15 20:19:47 +03005124 Py_DECREF(ub);
5125 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005126}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005127#endif
5128
pxinwrf2d7ac72019-05-21 18:46:37 +08005129#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005130static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005131parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5132{
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 Py_ssize_t i, pos, envc;
5134 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005135 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005136 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005137
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 i = PyMapping_Size(env);
5139 if (i < 0)
5140 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005141 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005142 if (envlist == NULL) {
5143 PyErr_NoMemory();
5144 return NULL;
5145 }
5146 envc = 0;
5147 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005148 if (!keys)
5149 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005150 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005151 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005152 goto error;
5153 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5154 PyErr_Format(PyExc_TypeError,
5155 "env.keys() or env.values() is not a list");
5156 goto error;
5157 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005158
Victor Stinner8c62be82010-05-06 00:08:46 +00005159 for (pos = 0; pos < i; pos++) {
5160 key = PyList_GetItem(keys, pos);
5161 val = PyList_GetItem(vals, pos);
5162 if (!key || !val)
5163 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005164
Berker Peksag81816462016-09-15 20:19:47 +03005165#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5166 if (!PyUnicode_FSDecoder(key, &key2))
5167 goto error;
5168 if (!PyUnicode_FSDecoder(val, &val2)) {
5169 Py_DECREF(key2);
5170 goto error;
5171 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005172 /* Search from index 1 because on Windows starting '=' is allowed for
5173 defining hidden environment variables. */
5174 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5175 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5176 {
5177 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005178 Py_DECREF(key2);
5179 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005180 goto error;
5181 }
Berker Peksag81816462016-09-15 20:19:47 +03005182 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5183#else
5184 if (!PyUnicode_FSConverter(key, &key2))
5185 goto error;
5186 if (!PyUnicode_FSConverter(val, &val2)) {
5187 Py_DECREF(key2);
5188 goto error;
5189 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005190 if (PyBytes_GET_SIZE(key2) == 0 ||
5191 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5192 {
5193 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005194 Py_DECREF(key2);
5195 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005196 goto error;
5197 }
Berker Peksag81816462016-09-15 20:19:47 +03005198 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5199 PyBytes_AS_STRING(val2));
5200#endif
5201 Py_DECREF(key2);
5202 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005203 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005204 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005205
5206 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5207 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005208 goto error;
5209 }
Berker Peksag81816462016-09-15 20:19:47 +03005210
Steve Dowercc16be82016-09-08 10:35:16 -07005211 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005212 }
5213 Py_DECREF(vals);
5214 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005215
Victor Stinner8c62be82010-05-06 00:08:46 +00005216 envlist[envc] = 0;
5217 *envc_ptr = envc;
5218 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005219
5220error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 Py_XDECREF(keys);
5222 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005223 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005224 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005225}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005226
Steve Dowercc16be82016-09-08 10:35:16 -07005227static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005228parse_arglist(PyObject* argv, Py_ssize_t *argc)
5229{
5230 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005231 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005232 if (argvlist == NULL) {
5233 PyErr_NoMemory();
5234 return NULL;
5235 }
5236 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005237 PyObject* item = PySequence_ITEM(argv, i);
5238 if (item == NULL)
5239 goto fail;
5240 if (!fsconvert_strdup(item, &argvlist[i])) {
5241 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005242 goto fail;
5243 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005244 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005245 }
5246 argvlist[*argc] = NULL;
5247 return argvlist;
5248fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005249 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005250 free_string_array(argvlist, *argc);
5251 return NULL;
5252}
Steve Dowercc16be82016-09-08 10:35:16 -07005253
Ross Lagerwall7807c352011-03-17 20:20:30 +02005254#endif
5255
Larry Hastings2f936352014-08-05 14:04:04 +10005256
Ross Lagerwall7807c352011-03-17 20:20:30 +02005257#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005258/*[clinic input]
5259os.execv
5260
Steve Dowercc16be82016-09-08 10:35:16 -07005261 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005262 Path of executable file.
5263 argv: object
5264 Tuple or list of strings.
5265 /
5266
5267Execute an executable path with arguments, replacing current process.
5268[clinic start generated code]*/
5269
Larry Hastings2f936352014-08-05 14:04:04 +10005270static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005271os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5272/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005273{
Steve Dowercc16be82016-09-08 10:35:16 -07005274 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005275 Py_ssize_t argc;
5276
5277 /* execv has two arguments: (path, argv), where
5278 argv is a list or tuple of strings. */
5279
Ross Lagerwall7807c352011-03-17 20:20:30 +02005280 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5281 PyErr_SetString(PyExc_TypeError,
5282 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005283 return NULL;
5284 }
5285 argc = PySequence_Size(argv);
5286 if (argc < 1) {
5287 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005288 return NULL;
5289 }
5290
5291 argvlist = parse_arglist(argv, &argc);
5292 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005293 return NULL;
5294 }
Steve Dowerbce26262016-11-19 19:17:26 -08005295 if (!argvlist[0][0]) {
5296 PyErr_SetString(PyExc_ValueError,
5297 "execv() arg 2 first element cannot be empty");
5298 free_string_array(argvlist, argc);
5299 return NULL;
5300 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005301
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005302 if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005303 free_string_array(argvlist, argc);
5304 return NULL;
5305 }
5306
Steve Dowerbce26262016-11-19 19:17:26 -08005307 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005308#ifdef HAVE_WEXECV
5309 _wexecv(path->wide, argvlist);
5310#else
5311 execv(path->narrow, argvlist);
5312#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005313 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005314
5315 /* If we get here it's definitely an error */
5316
5317 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005318 return posix_error();
5319}
5320
Larry Hastings2f936352014-08-05 14:04:04 +10005321
5322/*[clinic input]
5323os.execve
5324
5325 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5326 Path of executable file.
5327 argv: object
5328 Tuple or list of strings.
5329 env: object
5330 Dictionary of strings mapping to strings.
5331
5332Execute an executable path with arguments, replacing current process.
5333[clinic start generated code]*/
5334
Larry Hastings2f936352014-08-05 14:04:04 +10005335static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005336os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5337/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005338{
Steve Dowercc16be82016-09-08 10:35:16 -07005339 EXECV_CHAR **argvlist = NULL;
5340 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005341 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005342
Victor Stinner8c62be82010-05-06 00:08:46 +00005343 /* execve has three arguments: (path, argv, env), where
5344 argv is a list or tuple of strings and env is a dictionary
5345 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005346
Ross Lagerwall7807c352011-03-17 20:20:30 +02005347 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005348 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005349 "execve: argv must be a tuple or list");
Saiyang Gou95f60012020-02-04 16:15:00 -08005350 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005351 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005352 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005353 if (argc < 1) {
5354 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5355 return NULL;
5356 }
5357
Victor Stinner8c62be82010-05-06 00:08:46 +00005358 if (!PyMapping_Check(env)) {
5359 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005360 "execve: environment must be a mapping object");
Saiyang Gou95f60012020-02-04 16:15:00 -08005361 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005362 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005363
Ross Lagerwall7807c352011-03-17 20:20:30 +02005364 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005365 if (argvlist == NULL) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005366 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005367 }
Steve Dowerbce26262016-11-19 19:17:26 -08005368 if (!argvlist[0][0]) {
5369 PyErr_SetString(PyExc_ValueError,
5370 "execve: argv first element cannot be empty");
Saiyang Gou95f60012020-02-04 16:15:00 -08005371 goto fail_0;
Steve Dowerbce26262016-11-19 19:17:26 -08005372 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005373
Victor Stinner8c62be82010-05-06 00:08:46 +00005374 envlist = parse_envlist(env, &envc);
5375 if (envlist == NULL)
Saiyang Gou95f60012020-02-04 16:15:00 -08005376 goto fail_0;
5377
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005378 if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005379 goto fail_1;
5380 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005381
Steve Dowerbce26262016-11-19 19:17:26 -08005382 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005383#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005384 if (path->fd > -1)
5385 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005386 else
5387#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005388#ifdef HAVE_WEXECV
5389 _wexecve(path->wide, argvlist, envlist);
5390#else
Larry Hastings2f936352014-08-05 14:04:04 +10005391 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005392#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005393 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005394
5395 /* If we get here it's definitely an error */
5396
Alexey Izbyshev83460312018-10-20 03:28:22 +03005397 posix_path_error(path);
Saiyang Gou95f60012020-02-04 16:15:00 -08005398 fail_1:
Steve Dowercc16be82016-09-08 10:35:16 -07005399 free_string_array(envlist, envc);
Saiyang Gou95f60012020-02-04 16:15:00 -08005400 fail_0:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005401 if (argvlist)
5402 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005403 return NULL;
5404}
Steve Dowercc16be82016-09-08 10:35:16 -07005405
Larry Hastings9cf065c2012-06-22 16:30:09 -07005406#endif /* HAVE_EXECV */
5407
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005408#ifdef HAVE_POSIX_SPAWN
5409
5410enum posix_spawn_file_actions_identifier {
5411 POSIX_SPAWN_OPEN,
5412 POSIX_SPAWN_CLOSE,
5413 POSIX_SPAWN_DUP2
5414};
5415
William Orr81574b82018-10-01 22:19:56 -07005416#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005417static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005418convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005419#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005420
5421static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005422parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005423 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005424 PyObject *setsigdef, PyObject *scheduler,
5425 posix_spawnattr_t *attrp)
5426{
5427 long all_flags = 0;
5428
5429 errno = posix_spawnattr_init(attrp);
5430 if (errno) {
5431 posix_error();
5432 return -1;
5433 }
5434
5435 if (setpgroup) {
5436 pid_t pgid = PyLong_AsPid(setpgroup);
5437 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5438 goto fail;
5439 }
5440 errno = posix_spawnattr_setpgroup(attrp, pgid);
5441 if (errno) {
5442 posix_error();
5443 goto fail;
5444 }
5445 all_flags |= POSIX_SPAWN_SETPGROUP;
5446 }
5447
5448 if (resetids) {
5449 all_flags |= POSIX_SPAWN_RESETIDS;
5450 }
5451
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005452 if (setsid) {
5453#ifdef POSIX_SPAWN_SETSID
5454 all_flags |= POSIX_SPAWN_SETSID;
5455#elif defined(POSIX_SPAWN_SETSID_NP)
5456 all_flags |= POSIX_SPAWN_SETSID_NP;
5457#else
5458 argument_unavailable_error(func_name, "setsid");
5459 return -1;
5460#endif
5461 }
5462
Pablo Galindo254a4662018-09-07 16:44:24 +01005463 if (setsigmask) {
5464 sigset_t set;
5465 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5466 goto fail;
5467 }
5468 errno = posix_spawnattr_setsigmask(attrp, &set);
5469 if (errno) {
5470 posix_error();
5471 goto fail;
5472 }
5473 all_flags |= POSIX_SPAWN_SETSIGMASK;
5474 }
5475
5476 if (setsigdef) {
5477 sigset_t set;
5478 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5479 goto fail;
5480 }
5481 errno = posix_spawnattr_setsigdefault(attrp, &set);
5482 if (errno) {
5483 posix_error();
5484 goto fail;
5485 }
5486 all_flags |= POSIX_SPAWN_SETSIGDEF;
5487 }
5488
5489 if (scheduler) {
5490#ifdef POSIX_SPAWN_SETSCHEDULER
5491 PyObject *py_schedpolicy;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005492 PyObject *schedparam_obj;
Pablo Galindo254a4662018-09-07 16:44:24 +01005493 struct sched_param schedparam;
5494
Victor Stinner1c2fa782020-05-10 11:05:29 +02005495 if (!PyArg_ParseTuple(scheduler, "OO"
Pablo Galindo254a4662018-09-07 16:44:24 +01005496 ";A scheduler tuple must have two elements",
Victor Stinner1c2fa782020-05-10 11:05:29 +02005497 &py_schedpolicy, &schedparam_obj)) {
5498 goto fail;
5499 }
5500 if (!convert_sched_param(module, schedparam_obj, &schedparam)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005501 goto fail;
5502 }
5503 if (py_schedpolicy != Py_None) {
5504 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5505
5506 if (schedpolicy == -1 && PyErr_Occurred()) {
5507 goto fail;
5508 }
5509 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5510 if (errno) {
5511 posix_error();
5512 goto fail;
5513 }
5514 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5515 }
5516 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5517 if (errno) {
5518 posix_error();
5519 goto fail;
5520 }
5521 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5522#else
5523 PyErr_SetString(PyExc_NotImplementedError,
5524 "The scheduler option is not supported in this system.");
5525 goto fail;
5526#endif
5527 }
5528
5529 errno = posix_spawnattr_setflags(attrp, all_flags);
5530 if (errno) {
5531 posix_error();
5532 goto fail;
5533 }
5534
5535 return 0;
5536
5537fail:
5538 (void)posix_spawnattr_destroy(attrp);
5539 return -1;
5540}
5541
5542static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005543parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005544 posix_spawn_file_actions_t *file_actionsp,
5545 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005546{
5547 PyObject *seq;
5548 PyObject *file_action = NULL;
5549 PyObject *tag_obj;
5550
5551 seq = PySequence_Fast(file_actions,
5552 "file_actions must be a sequence or None");
5553 if (seq == NULL) {
5554 return -1;
5555 }
5556
5557 errno = posix_spawn_file_actions_init(file_actionsp);
5558 if (errno) {
5559 posix_error();
5560 Py_DECREF(seq);
5561 return -1;
5562 }
5563
Zackery Spytzd52a83a2019-06-26 14:54:20 -06005564 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03005565 file_action = PySequence_Fast_GET_ITEM(seq, i);
5566 Py_INCREF(file_action);
5567 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5568 PyErr_SetString(PyExc_TypeError,
5569 "Each file_actions element must be a non-empty tuple");
5570 goto fail;
5571 }
5572 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5573 if (tag == -1 && PyErr_Occurred()) {
5574 goto fail;
5575 }
5576
5577 /* Populate the file_actions object */
5578 switch (tag) {
5579 case POSIX_SPAWN_OPEN: {
5580 int fd, oflag;
5581 PyObject *path;
5582 unsigned long mode;
5583 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5584 ";A open file_action tuple must have 5 elements",
5585 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5586 &oflag, &mode))
5587 {
5588 goto fail;
5589 }
Pablo Galindocb970732018-06-19 09:19:50 +01005590 if (PyList_Append(temp_buffer, path)) {
5591 Py_DECREF(path);
5592 goto fail;
5593 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005594 errno = posix_spawn_file_actions_addopen(file_actionsp,
5595 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005596 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005597 if (errno) {
5598 posix_error();
5599 goto fail;
5600 }
5601 break;
5602 }
5603 case POSIX_SPAWN_CLOSE: {
5604 int fd;
5605 if (!PyArg_ParseTuple(file_action, "Oi"
5606 ";A close file_action tuple must have 2 elements",
5607 &tag_obj, &fd))
5608 {
5609 goto fail;
5610 }
5611 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5612 if (errno) {
5613 posix_error();
5614 goto fail;
5615 }
5616 break;
5617 }
5618 case POSIX_SPAWN_DUP2: {
5619 int fd1, fd2;
5620 if (!PyArg_ParseTuple(file_action, "Oii"
5621 ";A dup2 file_action tuple must have 3 elements",
5622 &tag_obj, &fd1, &fd2))
5623 {
5624 goto fail;
5625 }
5626 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5627 fd1, fd2);
5628 if (errno) {
5629 posix_error();
5630 goto fail;
5631 }
5632 break;
5633 }
5634 default: {
5635 PyErr_SetString(PyExc_TypeError,
5636 "Unknown file_actions identifier");
5637 goto fail;
5638 }
5639 }
5640 Py_DECREF(file_action);
5641 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005642
Serhiy Storchakaef347532018-05-01 16:45:04 +03005643 Py_DECREF(seq);
5644 return 0;
5645
5646fail:
5647 Py_DECREF(seq);
5648 Py_DECREF(file_action);
5649 (void)posix_spawn_file_actions_destroy(file_actionsp);
5650 return -1;
5651}
5652
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005653
5654static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005655py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5656 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005657 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005658 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005659{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005660 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005661 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005662 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005663 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005664 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005665 posix_spawnattr_t attr;
5666 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005667 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005668 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005669 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005670 pid_t pid;
5671 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005672
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005673 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005674 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005675 like posix.environ. */
5676
Serhiy Storchakaef347532018-05-01 16:45:04 +03005677 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005678 PyErr_Format(PyExc_TypeError,
5679 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005680 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005681 }
5682 argc = PySequence_Size(argv);
5683 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005684 PyErr_Format(PyExc_ValueError,
5685 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005686 return NULL;
5687 }
5688
5689 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005690 PyErr_Format(PyExc_TypeError,
5691 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005692 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005693 }
5694
5695 argvlist = parse_arglist(argv, &argc);
5696 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005697 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005698 }
5699 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005700 PyErr_Format(PyExc_ValueError,
5701 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005702 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005703 }
5704
5705 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005706 if (envlist == NULL) {
5707 goto exit;
5708 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005709
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005710 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005711 /* There is a bug in old versions of glibc that makes some of the
5712 * helper functions for manipulating file actions not copy the provided
5713 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5714 * copy the value of path for some old versions of glibc (<2.20).
5715 * The use of temp_buffer here is a workaround that keeps the
5716 * python objects that own the buffers alive until posix_spawn gets called.
5717 * Check https://bugs.python.org/issue33630 and
5718 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5719 temp_buffer = PyList_New(0);
5720 if (!temp_buffer) {
5721 goto exit;
5722 }
5723 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005724 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005725 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005726 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005727 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005728
Victor Stinner1c2fa782020-05-10 11:05:29 +02005729 if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005730 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005731 goto exit;
5732 }
5733 attrp = &attr;
5734
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005735 if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005736 goto exit;
5737 }
5738
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005739 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005740#ifdef HAVE_POSIX_SPAWNP
5741 if (use_posix_spawnp) {
5742 err_code = posix_spawnp(&pid, path->narrow,
5743 file_actionsp, attrp, argvlist, envlist);
5744 }
5745 else
5746#endif /* HAVE_POSIX_SPAWNP */
5747 {
5748 err_code = posix_spawn(&pid, path->narrow,
5749 file_actionsp, attrp, argvlist, envlist);
5750 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005751 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005752
Serhiy Storchakaef347532018-05-01 16:45:04 +03005753 if (err_code) {
5754 errno = err_code;
5755 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005756 goto exit;
5757 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005758#ifdef _Py_MEMORY_SANITIZER
5759 __msan_unpoison(&pid, sizeof(pid));
5760#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005761 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005762
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005763exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005764 if (file_actionsp) {
5765 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005766 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005767 if (attrp) {
5768 (void)posix_spawnattr_destroy(attrp);
5769 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005770 if (envlist) {
5771 free_string_array(envlist, envc);
5772 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005773 if (argvlist) {
5774 free_string_array(argvlist, argc);
5775 }
Pablo Galindocb970732018-06-19 09:19:50 +01005776 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005777 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005778}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005779
5780
5781/*[clinic input]
5782
5783os.posix_spawn
5784 path: path_t
5785 Path of executable file.
5786 argv: object
5787 Tuple or list of strings.
5788 env: object
5789 Dictionary of strings mapping to strings.
5790 /
5791 *
5792 file_actions: object(c_default='NULL') = ()
5793 A sequence of file action tuples.
5794 setpgroup: object = NULL
5795 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5796 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005797 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5798 setsid: bool(accept={int}) = False
5799 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005800 setsigmask: object(c_default='NULL') = ()
5801 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5802 setsigdef: object(c_default='NULL') = ()
5803 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5804 scheduler: object = NULL
5805 A tuple with the scheduler policy (optional) and parameters.
5806
5807Execute the program specified by path in a new process.
5808[clinic start generated code]*/
5809
5810static PyObject *
5811os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5812 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005813 PyObject *setpgroup, int resetids, int setsid,
5814 PyObject *setsigmask, PyObject *setsigdef,
5815 PyObject *scheduler)
5816/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005817{
5818 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005819 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005820 scheduler);
5821}
5822 #endif /* HAVE_POSIX_SPAWN */
5823
5824
5825
5826#ifdef HAVE_POSIX_SPAWNP
5827/*[clinic input]
5828
5829os.posix_spawnp
5830 path: path_t
5831 Path of executable file.
5832 argv: object
5833 Tuple or list of strings.
5834 env: object
5835 Dictionary of strings mapping to strings.
5836 /
5837 *
5838 file_actions: object(c_default='NULL') = ()
5839 A sequence of file action tuples.
5840 setpgroup: object = NULL
5841 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5842 resetids: bool(accept={int}) = False
5843 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005844 setsid: bool(accept={int}) = False
5845 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005846 setsigmask: object(c_default='NULL') = ()
5847 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5848 setsigdef: object(c_default='NULL') = ()
5849 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5850 scheduler: object = NULL
5851 A tuple with the scheduler policy (optional) and parameters.
5852
5853Execute the program specified by path in a new process.
5854[clinic start generated code]*/
5855
5856static PyObject *
5857os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5858 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005859 PyObject *setpgroup, int resetids, int setsid,
5860 PyObject *setsigmask, PyObject *setsigdef,
5861 PyObject *scheduler)
5862/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005863{
5864 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005865 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005866 scheduler);
5867}
5868#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005869
pxinwrf2d7ac72019-05-21 18:46:37 +08005870#ifdef HAVE_RTPSPAWN
5871static intptr_t
5872_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5873 const char *envp[])
5874{
5875 RTP_ID rtpid;
5876 int status;
5877 pid_t res;
5878 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005879
pxinwrf2d7ac72019-05-21 18:46:37 +08005880 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5881 uStackSize=0 cannot be used, the default stack size is too small for
5882 Python. */
5883 if (envp) {
5884 rtpid = rtpSpawn(rtpFileName, argv, envp,
5885 100, 0x1000000, 0, VX_FP_TASK);
5886 }
5887 else {
5888 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5889 100, 0x1000000, 0, VX_FP_TASK);
5890 }
5891 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5892 do {
5893 res = waitpid((pid_t)rtpid, &status, 0);
5894 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5895
5896 if (res < 0)
5897 return RTP_ID_ERROR;
5898 return ((intptr_t)status);
5899 }
5900 return ((intptr_t)rtpid);
5901}
5902#endif
5903
5904#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10005905/*[clinic input]
5906os.spawnv
5907
5908 mode: int
5909 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005910 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005911 Path of executable file.
5912 argv: object
5913 Tuple or list of strings.
5914 /
5915
5916Execute the program specified by path in a new process.
5917[clinic start generated code]*/
5918
Larry Hastings2f936352014-08-05 14:04:04 +10005919static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005920os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5921/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005922{
Steve Dowercc16be82016-09-08 10:35:16 -07005923 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005924 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005926 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005927 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005928
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 /* spawnv has three arguments: (mode, path, argv), where
5930 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005931
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 if (PyList_Check(argv)) {
5933 argc = PyList_Size(argv);
5934 getitem = PyList_GetItem;
5935 }
5936 else if (PyTuple_Check(argv)) {
5937 argc = PyTuple_Size(argv);
5938 getitem = PyTuple_GetItem;
5939 }
5940 else {
5941 PyErr_SetString(PyExc_TypeError,
5942 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 return NULL;
5944 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005945 if (argc == 0) {
5946 PyErr_SetString(PyExc_ValueError,
5947 "spawnv() arg 2 cannot be empty");
5948 return NULL;
5949 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005950
Steve Dowercc16be82016-09-08 10:35:16 -07005951 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005952 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005953 return PyErr_NoMemory();
5954 }
5955 for (i = 0; i < argc; i++) {
5956 if (!fsconvert_strdup((*getitem)(argv, i),
5957 &argvlist[i])) {
5958 free_string_array(argvlist, i);
5959 PyErr_SetString(
5960 PyExc_TypeError,
5961 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005962 return NULL;
5963 }
Steve Dower93ff8722016-11-19 19:03:54 -08005964 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005965 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005966 PyErr_SetString(
5967 PyExc_ValueError,
5968 "spawnv() arg 2 first element cannot be empty");
5969 return NULL;
5970 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005971 }
5972 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005973
pxinwrf2d7ac72019-05-21 18:46:37 +08005974#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005975 if (mode == _OLD_P_OVERLAY)
5976 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005977#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005978
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005979 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
Saiyang Gou95f60012020-02-04 16:15:00 -08005980 Py_None) < 0) {
5981 free_string_array(argvlist, argc);
5982 return NULL;
5983 }
5984
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005986 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005987#ifdef HAVE_WSPAWNV
5988 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005989#elif defined(HAVE_RTPSPAWN)
5990 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07005991#else
5992 spawnval = _spawnv(mode, path->narrow, argvlist);
5993#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005994 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005996
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005998
Victor Stinner8c62be82010-05-06 00:08:46 +00005999 if (spawnval == -1)
6000 return posix_error();
6001 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006002 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006003}
6004
Larry Hastings2f936352014-08-05 14:04:04 +10006005/*[clinic input]
6006os.spawnve
6007
6008 mode: int
6009 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006010 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006011 Path of executable file.
6012 argv: object
6013 Tuple or list of strings.
6014 env: object
6015 Dictionary of strings mapping to strings.
6016 /
6017
6018Execute the program specified by path in a new process.
6019[clinic start generated code]*/
6020
Larry Hastings2f936352014-08-05 14:04:04 +10006021static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006022os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006023 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07006024/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006025{
Steve Dowercc16be82016-09-08 10:35:16 -07006026 EXECV_CHAR **argvlist;
6027 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006029 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006030 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006031 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006032 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006033
Victor Stinner8c62be82010-05-06 00:08:46 +00006034 /* spawnve has four arguments: (mode, path, argv, env), where
6035 argv is a list or tuple of strings and env is a dictionary
6036 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006037
Victor Stinner8c62be82010-05-06 00:08:46 +00006038 if (PyList_Check(argv)) {
6039 argc = PyList_Size(argv);
6040 getitem = PyList_GetItem;
6041 }
6042 else if (PyTuple_Check(argv)) {
6043 argc = PyTuple_Size(argv);
6044 getitem = PyTuple_GetItem;
6045 }
6046 else {
6047 PyErr_SetString(PyExc_TypeError,
6048 "spawnve() arg 2 must be a tuple or list");
6049 goto fail_0;
6050 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006051 if (argc == 0) {
6052 PyErr_SetString(PyExc_ValueError,
6053 "spawnve() arg 2 cannot be empty");
6054 goto fail_0;
6055 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006056 if (!PyMapping_Check(env)) {
6057 PyErr_SetString(PyExc_TypeError,
6058 "spawnve() arg 3 must be a mapping object");
6059 goto fail_0;
6060 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006061
Steve Dowercc16be82016-09-08 10:35:16 -07006062 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006063 if (argvlist == NULL) {
6064 PyErr_NoMemory();
6065 goto fail_0;
6066 }
6067 for (i = 0; i < argc; i++) {
6068 if (!fsconvert_strdup((*getitem)(argv, i),
6069 &argvlist[i]))
6070 {
6071 lastarg = i;
6072 goto fail_1;
6073 }
Steve Dowerbce26262016-11-19 19:17:26 -08006074 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006075 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006076 PyErr_SetString(
6077 PyExc_ValueError,
6078 "spawnv() arg 2 first element cannot be empty");
6079 goto fail_1;
6080 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006081 }
6082 lastarg = argc;
6083 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006084
Victor Stinner8c62be82010-05-06 00:08:46 +00006085 envlist = parse_envlist(env, &envc);
6086 if (envlist == NULL)
6087 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006088
pxinwrf2d7ac72019-05-21 18:46:37 +08006089#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006090 if (mode == _OLD_P_OVERLAY)
6091 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006092#endif
Tim Peters25059d32001-12-07 20:35:43 +00006093
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006094 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006095 goto fail_2;
6096 }
6097
Victor Stinner8c62be82010-05-06 00:08:46 +00006098 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006099 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006100#ifdef HAVE_WSPAWNV
6101 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006102#elif defined(HAVE_RTPSPAWN)
6103 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6104 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006105#else
6106 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6107#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006108 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006109 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006110
Victor Stinner8c62be82010-05-06 00:08:46 +00006111 if (spawnval == -1)
6112 (void) posix_error();
6113 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006114 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006115
Saiyang Gou95f60012020-02-04 16:15:00 -08006116 fail_2:
Victor Stinner8c62be82010-05-06 00:08:46 +00006117 while (--envc >= 0)
6118 PyMem_DEL(envlist[envc]);
6119 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006120 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006121 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006122 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006123 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006124}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006125
Guido van Rossuma1065681999-01-25 23:20:23 +00006126#endif /* HAVE_SPAWNV */
6127
6128
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006129#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006130
6131/* Helper function to validate arguments.
6132 Returns 0 on success. non-zero on failure with a TypeError raised.
6133 If obj is non-NULL it must be callable. */
6134static int
6135check_null_or_callable(PyObject *obj, const char* obj_name)
6136{
6137 if (obj && !PyCallable_Check(obj)) {
6138 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006139 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006140 return -1;
6141 }
6142 return 0;
6143}
6144
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006145/*[clinic input]
6146os.register_at_fork
6147
Gregory P. Smith163468a2017-05-29 10:03:41 -07006148 *
6149 before: object=NULL
6150 A callable to be called in the parent before the fork() syscall.
6151 after_in_child: object=NULL
6152 A callable to be called in the child after fork().
6153 after_in_parent: object=NULL
6154 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006155
Gregory P. Smith163468a2017-05-29 10:03:41 -07006156Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006157
Gregory P. Smith163468a2017-05-29 10:03:41 -07006158'before' callbacks are called in reverse order.
6159'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006160
6161[clinic start generated code]*/
6162
6163static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006164os_register_at_fork_impl(PyObject *module, PyObject *before,
6165 PyObject *after_in_child, PyObject *after_in_parent)
6166/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006167{
6168 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006169
Gregory P. Smith163468a2017-05-29 10:03:41 -07006170 if (!before && !after_in_child && !after_in_parent) {
6171 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6172 return NULL;
6173 }
6174 if (check_null_or_callable(before, "before") ||
6175 check_null_or_callable(after_in_child, "after_in_child") ||
6176 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006177 return NULL;
6178 }
Victor Stinner81a7be32020-04-14 15:14:01 +02006179 interp = _PyInterpreterState_GET();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006180
Gregory P. Smith163468a2017-05-29 10:03:41 -07006181 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006182 return NULL;
6183 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006184 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006185 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006186 }
6187 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6188 return NULL;
6189 }
6190 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006191}
6192#endif /* HAVE_FORK */
6193
6194
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006195#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006196/*[clinic input]
6197os.fork1
6198
6199Fork a child process with a single multiplexed (i.e., not bound) thread.
6200
6201Return 0 to child process and PID of child to parent process.
6202[clinic start generated code]*/
6203
Larry Hastings2f936352014-08-05 14:04:04 +10006204static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006205os_fork1_impl(PyObject *module)
6206/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006207{
Victor Stinner8c62be82010-05-06 00:08:46 +00006208 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006209
Victor Stinner81a7be32020-04-14 15:14:01 +02006210 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006211 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6212 return NULL;
6213 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006214 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006215 pid = fork1();
6216 if (pid == 0) {
6217 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006218 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006219 } else {
6220 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006221 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006222 }
6223 if (pid == -1)
6224 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006225 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006226}
Larry Hastings2f936352014-08-05 14:04:04 +10006227#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006228
6229
Guido van Rossumad0ee831995-03-01 10:34:45 +00006230#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006231/*[clinic input]
6232os.fork
6233
6234Fork a child process.
6235
6236Return 0 to child process and PID of child to parent process.
6237[clinic start generated code]*/
6238
Larry Hastings2f936352014-08-05 14:04:04 +10006239static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006240os_fork_impl(PyObject *module)
6241/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006242{
Victor Stinner8c62be82010-05-06 00:08:46 +00006243 pid_t pid;
Victor Stinner252346a2020-05-01 11:33:44 +02006244 PyInterpreterState *interp = _PyInterpreterState_GET();
6245 if (interp->config._isolated_interpreter) {
6246 PyErr_SetString(PyExc_RuntimeError,
6247 "fork not supported for isolated subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -07006248 return NULL;
6249 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006250 if (PySys_Audit("os.fork", NULL) < 0) {
6251 return NULL;
6252 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006253 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 pid = fork();
6255 if (pid == 0) {
6256 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006257 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 } else {
6259 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006260 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006261 }
6262 if (pid == -1)
6263 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006264 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006265}
Larry Hastings2f936352014-08-05 14:04:04 +10006266#endif /* HAVE_FORK */
6267
Guido van Rossum85e3b011991-06-03 12:42:10 +00006268
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006269#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006270#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006271/*[clinic input]
6272os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006273
Larry Hastings2f936352014-08-05 14:04:04 +10006274 policy: int
6275
6276Get the maximum scheduling priority for policy.
6277[clinic start generated code]*/
6278
Larry Hastings2f936352014-08-05 14:04:04 +10006279static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006280os_sched_get_priority_max_impl(PyObject *module, int policy)
6281/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006282{
6283 int max;
6284
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006285 max = sched_get_priority_max(policy);
6286 if (max < 0)
6287 return posix_error();
6288 return PyLong_FromLong(max);
6289}
6290
Larry Hastings2f936352014-08-05 14:04:04 +10006291
6292/*[clinic input]
6293os.sched_get_priority_min
6294
6295 policy: int
6296
6297Get the minimum scheduling priority for policy.
6298[clinic start generated code]*/
6299
Larry Hastings2f936352014-08-05 14:04:04 +10006300static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006301os_sched_get_priority_min_impl(PyObject *module, int policy)
6302/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006303{
6304 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006305 if (min < 0)
6306 return posix_error();
6307 return PyLong_FromLong(min);
6308}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006309#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6310
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006311
Larry Hastings2f936352014-08-05 14:04:04 +10006312#ifdef HAVE_SCHED_SETSCHEDULER
6313/*[clinic input]
6314os.sched_getscheduler
6315 pid: pid_t
6316 /
6317
Min ho Kimc4cacc82019-07-31 08:16:13 +10006318Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006319
6320Passing 0 for pid returns the scheduling policy for the calling process.
6321[clinic start generated code]*/
6322
Larry Hastings2f936352014-08-05 14:04:04 +10006323static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006324os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006325/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006326{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006327 int policy;
6328
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006329 policy = sched_getscheduler(pid);
6330 if (policy < 0)
6331 return posix_error();
6332 return PyLong_FromLong(policy);
6333}
Larry Hastings2f936352014-08-05 14:04:04 +10006334#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006335
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006336
William Orr81574b82018-10-01 22:19:56 -07006337#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006338/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006339class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006340
6341@classmethod
6342os.sched_param.__new__
6343
6344 sched_priority: object
6345 A scheduling parameter.
6346
Eddie Elizondob3966632019-11-05 07:16:14 -08006347Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006348[clinic start generated code]*/
6349
Larry Hastings2f936352014-08-05 14:04:04 +10006350static PyObject *
6351os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006352/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006353{
6354 PyObject *res;
6355
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006356 res = PyStructSequence_New(type);
6357 if (!res)
6358 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006359 Py_INCREF(sched_priority);
6360 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006361 return res;
6362}
6363
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006364PyDoc_VAR(os_sched_param__doc__);
6365
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006366static PyStructSequence_Field sched_param_fields[] = {
6367 {"sched_priority", "the scheduling priority"},
6368 {0}
6369};
6370
6371static PyStructSequence_Desc sched_param_desc = {
6372 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006373 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006374 sched_param_fields,
6375 1
6376};
6377
6378static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006379convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006380{
6381 long priority;
6382
Victor Stinner1c2fa782020-05-10 11:05:29 +02006383 if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006384 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6385 return 0;
6386 }
6387 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6388 if (priority == -1 && PyErr_Occurred())
6389 return 0;
6390 if (priority > INT_MAX || priority < INT_MIN) {
6391 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6392 return 0;
6393 }
6394 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6395 return 1;
6396}
William Orr81574b82018-10-01 22:19:56 -07006397#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006398
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006399
6400#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006401/*[clinic input]
6402os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006403
Larry Hastings2f936352014-08-05 14:04:04 +10006404 pid: pid_t
6405 policy: int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006406 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006407 /
6408
6409Set the scheduling policy for the process identified by pid.
6410
6411If pid is 0, the calling process is changed.
6412param is an instance of sched_param.
6413[clinic start generated code]*/
6414
Larry Hastings2f936352014-08-05 14:04:04 +10006415static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006416os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Victor Stinner1c2fa782020-05-10 11:05:29 +02006417 PyObject *param_obj)
6418/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006419{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006420 struct sched_param param;
6421 if (!convert_sched_param(module, param_obj, &param)) {
6422 return NULL;
6423 }
6424
Jesus Cea9c822272011-09-10 01:40:52 +02006425 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006426 ** sched_setscheduler() returns 0 in Linux, but the previous
6427 ** scheduling policy under Solaris/Illumos, and others.
6428 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006429 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02006430 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006431 return posix_error();
6432 Py_RETURN_NONE;
6433}
Larry Hastings2f936352014-08-05 14:04:04 +10006434#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006435
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006436
6437#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006438/*[clinic input]
6439os.sched_getparam
6440 pid: pid_t
6441 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006442
Larry Hastings2f936352014-08-05 14:04:04 +10006443Returns scheduling parameters for the process identified by pid.
6444
6445If pid is 0, returns parameters for the calling process.
6446Return value is an instance of sched_param.
6447[clinic start generated code]*/
6448
Larry Hastings2f936352014-08-05 14:04:04 +10006449static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006450os_sched_getparam_impl(PyObject *module, pid_t pid)
6451/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006452{
6453 struct sched_param param;
6454 PyObject *result;
6455 PyObject *priority;
6456
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006457 if (sched_getparam(pid, &param))
6458 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02006459 PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -08006460 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006461 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006462 return NULL;
6463 priority = PyLong_FromLong(param.sched_priority);
6464 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006465 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006466 return NULL;
6467 }
Larry Hastings2f936352014-08-05 14:04:04 +10006468 PyStructSequence_SET_ITEM(result, 0, priority);
6469 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006470}
6471
Larry Hastings2f936352014-08-05 14:04:04 +10006472
6473/*[clinic input]
6474os.sched_setparam
6475 pid: pid_t
Victor Stinner1c2fa782020-05-10 11:05:29 +02006476 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006477 /
6478
6479Set scheduling parameters for the process identified by pid.
6480
6481If pid is 0, sets parameters for the calling process.
6482param should be an instance of sched_param.
6483[clinic start generated code]*/
6484
Larry Hastings2f936352014-08-05 14:04:04 +10006485static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02006486os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
6487/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006488{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006489 struct sched_param param;
6490 if (!convert_sched_param(module, param_obj, &param)) {
6491 return NULL;
6492 }
6493
6494 if (sched_setparam(pid, &param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006495 return posix_error();
6496 Py_RETURN_NONE;
6497}
Larry Hastings2f936352014-08-05 14:04:04 +10006498#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006499
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006500
6501#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006502/*[clinic input]
6503os.sched_rr_get_interval -> double
6504 pid: pid_t
6505 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006506
Larry Hastings2f936352014-08-05 14:04:04 +10006507Return the round-robin quantum for the process identified by pid, in seconds.
6508
6509Value returned is a float.
6510[clinic start generated code]*/
6511
Larry Hastings2f936352014-08-05 14:04:04 +10006512static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006513os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6514/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006515{
6516 struct timespec interval;
6517 if (sched_rr_get_interval(pid, &interval)) {
6518 posix_error();
6519 return -1.0;
6520 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006521#ifdef _Py_MEMORY_SANITIZER
6522 __msan_unpoison(&interval, sizeof(interval));
6523#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006524 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6525}
6526#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006527
Larry Hastings2f936352014-08-05 14:04:04 +10006528
6529/*[clinic input]
6530os.sched_yield
6531
6532Voluntarily relinquish the CPU.
6533[clinic start generated code]*/
6534
Larry Hastings2f936352014-08-05 14:04:04 +10006535static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006536os_sched_yield_impl(PyObject *module)
6537/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006538{
6539 if (sched_yield())
6540 return posix_error();
6541 Py_RETURN_NONE;
6542}
6543
Benjamin Peterson2740af82011-08-02 17:41:34 -05006544#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006545/* The minimum number of CPUs allocated in a cpu_set_t */
6546static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006547
Larry Hastings2f936352014-08-05 14:04:04 +10006548/*[clinic input]
6549os.sched_setaffinity
6550 pid: pid_t
6551 mask : object
6552 /
6553
6554Set the CPU affinity of the process identified by pid to mask.
6555
6556mask should be an iterable of integers identifying CPUs.
6557[clinic start generated code]*/
6558
Larry Hastings2f936352014-08-05 14:04:04 +10006559static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006560os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6561/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006562{
Antoine Pitrou84869872012-08-04 16:16:35 +02006563 int ncpus;
6564 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006565 cpu_set_t *cpu_set = NULL;
6566 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006567
Larry Hastings2f936352014-08-05 14:04:04 +10006568 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006569 if (iterator == NULL)
6570 return NULL;
6571
6572 ncpus = NCPUS_START;
6573 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006574 cpu_set = CPU_ALLOC(ncpus);
6575 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006576 PyErr_NoMemory();
6577 goto error;
6578 }
Larry Hastings2f936352014-08-05 14:04:04 +10006579 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006580
6581 while ((item = PyIter_Next(iterator))) {
6582 long cpu;
6583 if (!PyLong_Check(item)) {
6584 PyErr_Format(PyExc_TypeError,
6585 "expected an iterator of ints, "
6586 "but iterator yielded %R",
6587 Py_TYPE(item));
6588 Py_DECREF(item);
6589 goto error;
6590 }
6591 cpu = PyLong_AsLong(item);
6592 Py_DECREF(item);
6593 if (cpu < 0) {
6594 if (!PyErr_Occurred())
6595 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6596 goto error;
6597 }
6598 if (cpu > INT_MAX - 1) {
6599 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6600 goto error;
6601 }
6602 if (cpu >= ncpus) {
6603 /* Grow CPU mask to fit the CPU number */
6604 int newncpus = ncpus;
6605 cpu_set_t *newmask;
6606 size_t newsetsize;
6607 while (newncpus <= cpu) {
6608 if (newncpus > INT_MAX / 2)
6609 newncpus = cpu + 1;
6610 else
6611 newncpus = newncpus * 2;
6612 }
6613 newmask = CPU_ALLOC(newncpus);
6614 if (newmask == NULL) {
6615 PyErr_NoMemory();
6616 goto error;
6617 }
6618 newsetsize = CPU_ALLOC_SIZE(newncpus);
6619 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006620 memcpy(newmask, cpu_set, setsize);
6621 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006622 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006623 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006624 ncpus = newncpus;
6625 }
Larry Hastings2f936352014-08-05 14:04:04 +10006626 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006627 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07006628 if (PyErr_Occurred()) {
6629 goto error;
6630 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006631 Py_CLEAR(iterator);
6632
Larry Hastings2f936352014-08-05 14:04:04 +10006633 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006634 posix_error();
6635 goto error;
6636 }
Larry Hastings2f936352014-08-05 14:04:04 +10006637 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006638 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006639
6640error:
Larry Hastings2f936352014-08-05 14:04:04 +10006641 if (cpu_set)
6642 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006643 Py_XDECREF(iterator);
6644 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006645}
6646
Larry Hastings2f936352014-08-05 14:04:04 +10006647
6648/*[clinic input]
6649os.sched_getaffinity
6650 pid: pid_t
6651 /
6652
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006653Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006654
6655The affinity is returned as a set of CPU identifiers.
6656[clinic start generated code]*/
6657
Larry Hastings2f936352014-08-05 14:04:04 +10006658static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006659os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006660/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006661{
Antoine Pitrou84869872012-08-04 16:16:35 +02006662 int cpu, ncpus, count;
6663 size_t setsize;
6664 cpu_set_t *mask = NULL;
6665 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006666
Antoine Pitrou84869872012-08-04 16:16:35 +02006667 ncpus = NCPUS_START;
6668 while (1) {
6669 setsize = CPU_ALLOC_SIZE(ncpus);
6670 mask = CPU_ALLOC(ncpus);
6671 if (mask == NULL)
6672 return PyErr_NoMemory();
6673 if (sched_getaffinity(pid, setsize, mask) == 0)
6674 break;
6675 CPU_FREE(mask);
6676 if (errno != EINVAL)
6677 return posix_error();
6678 if (ncpus > INT_MAX / 2) {
6679 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6680 "a large enough CPU set");
6681 return NULL;
6682 }
6683 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006684 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006685
6686 res = PySet_New(NULL);
6687 if (res == NULL)
6688 goto error;
6689 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6690 if (CPU_ISSET_S(cpu, setsize, mask)) {
6691 PyObject *cpu_num = PyLong_FromLong(cpu);
6692 --count;
6693 if (cpu_num == NULL)
6694 goto error;
6695 if (PySet_Add(res, cpu_num)) {
6696 Py_DECREF(cpu_num);
6697 goto error;
6698 }
6699 Py_DECREF(cpu_num);
6700 }
6701 }
6702 CPU_FREE(mask);
6703 return res;
6704
6705error:
6706 if (mask)
6707 CPU_FREE(mask);
6708 Py_XDECREF(res);
6709 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006710}
6711
Benjamin Peterson2740af82011-08-02 17:41:34 -05006712#endif /* HAVE_SCHED_SETAFFINITY */
6713
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006714#endif /* HAVE_SCHED_H */
6715
Larry Hastings2f936352014-08-05 14:04:04 +10006716
Neal Norwitzb59798b2003-03-21 01:43:31 +00006717/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006718/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6719#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006720#define DEV_PTY_FILE "/dev/ptc"
6721#define HAVE_DEV_PTMX
6722#else
6723#define DEV_PTY_FILE "/dev/ptmx"
6724#endif
6725
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006726#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006727#ifdef HAVE_PTY_H
6728#include <pty.h>
6729#else
6730#ifdef HAVE_LIBUTIL_H
6731#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006732#else
6733#ifdef HAVE_UTIL_H
6734#include <util.h>
6735#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006736#endif /* HAVE_LIBUTIL_H */
6737#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006738#ifdef HAVE_STROPTS_H
6739#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006740#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006741#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006742
Larry Hastings2f936352014-08-05 14:04:04 +10006743
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006744#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006745/*[clinic input]
6746os.openpty
6747
6748Open a pseudo-terminal.
6749
6750Return a tuple of (master_fd, slave_fd) containing open file descriptors
6751for both the master and slave ends.
6752[clinic start generated code]*/
6753
Larry Hastings2f936352014-08-05 14:04:04 +10006754static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006755os_openpty_impl(PyObject *module)
6756/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006757{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006758 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006759#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006761#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006762#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006764#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006765 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006766#endif
6767#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006768
Thomas Wouters70c21a12000-07-14 14:28:33 +00006769#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006770 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006771 goto posix_error;
6772
6773 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6774 goto error;
6775 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6776 goto error;
6777
Neal Norwitzb59798b2003-03-21 01:43:31 +00006778#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6780 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006781 goto posix_error;
6782 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6783 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006784
Victor Stinnerdaf45552013-08-28 00:53:59 +02006785 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006786 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006787 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006788
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006789#else
Victor Stinner000de532013-11-25 23:19:58 +01006790 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006792 goto posix_error;
6793
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006795
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 /* change permission of slave */
6797 if (grantpt(master_fd) < 0) {
6798 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006799 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006801
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 /* unlock slave */
6803 if (unlockpt(master_fd) < 0) {
6804 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006805 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006807
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006809
Victor Stinner8c62be82010-05-06 00:08:46 +00006810 slave_name = ptsname(master_fd); /* get name of slave */
6811 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006812 goto posix_error;
6813
6814 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006815 if (slave_fd == -1)
6816 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006817
6818 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6819 goto posix_error;
6820
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006821#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006822 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6823 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006824#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006826#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006827#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006828#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006829
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006831
Victor Stinnerdaf45552013-08-28 00:53:59 +02006832posix_error:
6833 posix_error();
6834error:
6835 if (master_fd != -1)
6836 close(master_fd);
6837 if (slave_fd != -1)
6838 close(slave_fd);
6839 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006840}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006841#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006842
Larry Hastings2f936352014-08-05 14:04:04 +10006843
Fred Drake8cef4cf2000-06-28 16:40:38 +00006844#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006845/*[clinic input]
6846os.forkpty
6847
6848Fork a new process with a new pseudo-terminal as controlling tty.
6849
6850Returns a tuple of (pid, master_fd).
6851Like fork(), return pid of 0 to the child process,
6852and pid of child to the parent process.
6853To both, return fd of newly opened pseudo-terminal.
6854[clinic start generated code]*/
6855
Larry Hastings2f936352014-08-05 14:04:04 +10006856static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006857os_forkpty_impl(PyObject *module)
6858/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006859{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006860 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006862
Victor Stinner81a7be32020-04-14 15:14:01 +02006863 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006864 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6865 return NULL;
6866 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006867 if (PySys_Audit("os.forkpty", NULL) < 0) {
6868 return NULL;
6869 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006870 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 pid = forkpty(&master_fd, NULL, NULL, NULL);
6872 if (pid == 0) {
6873 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006874 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 } else {
6876 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006877 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 }
6879 if (pid == -1)
6880 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006882}
Larry Hastings2f936352014-08-05 14:04:04 +10006883#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006884
Ross Lagerwall7807c352011-03-17 20:20:30 +02006885
Guido van Rossumad0ee831995-03-01 10:34:45 +00006886#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006887/*[clinic input]
6888os.getegid
6889
6890Return the current process's effective group id.
6891[clinic start generated code]*/
6892
Larry Hastings2f936352014-08-05 14:04:04 +10006893static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006894os_getegid_impl(PyObject *module)
6895/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006896{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006897 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006898}
Larry Hastings2f936352014-08-05 14:04:04 +10006899#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006901
Guido van Rossumad0ee831995-03-01 10:34:45 +00006902#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006903/*[clinic input]
6904os.geteuid
6905
6906Return the current process's effective user id.
6907[clinic start generated code]*/
6908
Larry Hastings2f936352014-08-05 14:04:04 +10006909static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006910os_geteuid_impl(PyObject *module)
6911/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006912{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006913 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006914}
Larry Hastings2f936352014-08-05 14:04:04 +10006915#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006916
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006917
Guido van Rossumad0ee831995-03-01 10:34:45 +00006918#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006919/*[clinic input]
6920os.getgid
6921
6922Return the current process's group id.
6923[clinic start generated code]*/
6924
Larry Hastings2f936352014-08-05 14:04:04 +10006925static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006926os_getgid_impl(PyObject *module)
6927/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006928{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006929 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006930}
Larry Hastings2f936352014-08-05 14:04:04 +10006931#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006933
Berker Peksag39404992016-09-15 20:45:16 +03006934#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006935/*[clinic input]
6936os.getpid
6937
6938Return the current process id.
6939[clinic start generated code]*/
6940
Larry Hastings2f936352014-08-05 14:04:04 +10006941static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006942os_getpid_impl(PyObject *module)
6943/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006944{
Victor Stinner8c62be82010-05-06 00:08:46 +00006945 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006946}
Berker Peksag39404992016-09-15 20:45:16 +03006947#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006948
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006949#ifdef NGROUPS_MAX
6950#define MAX_GROUPS NGROUPS_MAX
6951#else
6952 /* defined to be 16 on Solaris7, so this should be a small number */
6953#define MAX_GROUPS 64
6954#endif
6955
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006956#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006957
Serhiy Storchaka2b560312020-04-18 19:14:10 +03006958#ifdef __APPLE__
6959/*[clinic input]
6960os.getgrouplist
6961
6962 user: str
6963 username to lookup
6964 group as basegid: int
6965 base group id of the user
6966 /
6967
6968Returns a list of groups to which a user belongs.
6969[clinic start generated code]*/
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006970
6971static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03006972os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
6973/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
6974#else
6975/*[clinic input]
6976os.getgrouplist
6977
6978 user: str
6979 username to lookup
6980 group as basegid: gid_t
6981 base group id of the user
6982 /
6983
6984Returns a list of groups to which a user belongs.
6985[clinic start generated code]*/
6986
6987static PyObject *
6988os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
6989/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
6990#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006991{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006992 int i, ngroups;
6993 PyObject *list;
6994#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03006995 int *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006996#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03006997 gid_t *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006998#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006999
7000 /*
7001 * NGROUPS_MAX is defined by POSIX.1 as the maximum
7002 * number of supplimental groups a users can belong to.
7003 * We have to increment it by one because
7004 * getgrouplist() returns both the supplemental groups
7005 * and the primary group, i.e. all of the groups the
7006 * user belongs to.
7007 */
7008 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007009
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007010 while (1) {
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007011#ifdef __APPLE__
Victor Stinner8ec73702020-03-23 20:00:57 +01007012 groups = PyMem_New(int, ngroups);
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007013#else
7014 groups = PyMem_New(gid_t, ngroups);
7015#endif
Victor Stinner8ec73702020-03-23 20:00:57 +01007016 if (groups == NULL) {
7017 return PyErr_NoMemory();
7018 }
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007019
7020 int old_ngroups = ngroups;
7021 if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
7022 /* Success */
7023 break;
7024 }
7025
7026 /* getgrouplist() fails if the group list is too small */
7027 PyMem_Free(groups);
7028
7029 if (ngroups > old_ngroups) {
7030 /* If the group list is too small, the glibc implementation of
7031 getgrouplist() sets ngroups to the total number of groups and
7032 returns -1. */
7033 }
7034 else {
7035 /* Double the group list size */
7036 if (ngroups > INT_MAX / 2) {
7037 return PyErr_NoMemory();
7038 }
7039 ngroups *= 2;
7040 }
7041
7042 /* Retry getgrouplist() with a larger group list */
Victor Stinner8ec73702020-03-23 20:00:57 +01007043 }
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007044
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007045#ifdef _Py_MEMORY_SANITIZER
7046 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7047 __msan_unpoison(&ngroups, sizeof(ngroups));
7048 __msan_unpoison(groups, ngroups*sizeof(*groups));
7049#endif
7050
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007051 list = PyList_New(ngroups);
7052 if (list == NULL) {
7053 PyMem_Del(groups);
7054 return NULL;
7055 }
7056
7057 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007058#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007059 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007060#else
7061 PyObject *o = _PyLong_FromGid(groups[i]);
7062#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007063 if (o == NULL) {
7064 Py_DECREF(list);
7065 PyMem_Del(groups);
7066 return NULL;
7067 }
7068 PyList_SET_ITEM(list, i, o);
7069 }
7070
7071 PyMem_Del(groups);
7072
7073 return list;
7074}
Larry Hastings2f936352014-08-05 14:04:04 +10007075#endif /* HAVE_GETGROUPLIST */
7076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007077
Fred Drakec9680921999-12-13 16:37:25 +00007078#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007079/*[clinic input]
7080os.getgroups
7081
7082Return list of supplemental group IDs for the process.
7083[clinic start generated code]*/
7084
Larry Hastings2f936352014-08-05 14:04:04 +10007085static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007086os_getgroups_impl(PyObject *module)
7087/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007088{
7089 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007090 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007091
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007092 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007093 * This is a helper variable to store the intermediate result when
7094 * that happens.
7095 *
7096 * To keep the code readable the OSX behaviour is unconditional,
7097 * according to the POSIX spec this should be safe on all unix-y
7098 * systems.
7099 */
7100 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007101 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007102
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007103#ifdef __APPLE__
7104 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7105 * there are more groups than can fit in grouplist. Therefore, on OS X
7106 * always first call getgroups with length 0 to get the actual number
7107 * of groups.
7108 */
7109 n = getgroups(0, NULL);
7110 if (n < 0) {
7111 return posix_error();
7112 } else if (n <= MAX_GROUPS) {
7113 /* groups will fit in existing array */
7114 alt_grouplist = grouplist;
7115 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007116 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007117 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007118 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007119 }
7120 }
7121
7122 n = getgroups(n, alt_grouplist);
7123 if (n == -1) {
7124 if (alt_grouplist != grouplist) {
7125 PyMem_Free(alt_grouplist);
7126 }
7127 return posix_error();
7128 }
7129#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007130 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007131 if (n < 0) {
7132 if (errno == EINVAL) {
7133 n = getgroups(0, NULL);
7134 if (n == -1) {
7135 return posix_error();
7136 }
7137 if (n == 0) {
7138 /* Avoid malloc(0) */
7139 alt_grouplist = grouplist;
7140 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007141 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007142 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007143 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007144 }
7145 n = getgroups(n, alt_grouplist);
7146 if (n == -1) {
7147 PyMem_Free(alt_grouplist);
7148 return posix_error();
7149 }
7150 }
7151 } else {
7152 return posix_error();
7153 }
7154 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007155#endif
7156
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007157 result = PyList_New(n);
7158 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 int i;
7160 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007161 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007163 Py_DECREF(result);
7164 result = NULL;
7165 break;
Fred Drakec9680921999-12-13 16:37:25 +00007166 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007167 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007168 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007169 }
7170
7171 if (alt_grouplist != grouplist) {
7172 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007173 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007174
Fred Drakec9680921999-12-13 16:37:25 +00007175 return result;
7176}
Larry Hastings2f936352014-08-05 14:04:04 +10007177#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007178
Antoine Pitroub7572f02009-12-02 20:46:48 +00007179#ifdef HAVE_INITGROUPS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007180#ifdef __APPLE__
7181/*[clinic input]
7182os.initgroups
Antoine Pitroub7572f02009-12-02 20:46:48 +00007183
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007184 username as oname: FSConverter
7185 gid: int
7186 /
7187
7188Initialize the group access list.
7189
7190Call the system initgroups() to initialize the group access list with all of
7191the groups of which the specified username is a member, plus the specified
7192group id.
7193[clinic start generated code]*/
7194
Antoine Pitroub7572f02009-12-02 20:46:48 +00007195static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007196os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7197/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7198#else
7199/*[clinic input]
7200os.initgroups
7201
7202 username as oname: FSConverter
7203 gid: gid_t
7204 /
7205
7206Initialize the group access list.
7207
7208Call the system initgroups() to initialize the group access list with all of
7209the groups of which the specified username is a member, plus the specified
7210group id.
7211[clinic start generated code]*/
7212
7213static PyObject *
7214os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7215/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7216#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007217{
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007218 const char *username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007219
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007220 if (initgroups(username, gid) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007221 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007222
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007223 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007224}
Larry Hastings2f936352014-08-05 14:04:04 +10007225#endif /* HAVE_INITGROUPS */
7226
Antoine Pitroub7572f02009-12-02 20:46:48 +00007227
Martin v. Löwis606edc12002-06-13 21:09:11 +00007228#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007229/*[clinic input]
7230os.getpgid
7231
7232 pid: pid_t
7233
7234Call the system call getpgid(), and return the result.
7235[clinic start generated code]*/
7236
Larry Hastings2f936352014-08-05 14:04:04 +10007237static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007238os_getpgid_impl(PyObject *module, pid_t pid)
7239/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007240{
7241 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007242 if (pgid < 0)
7243 return posix_error();
7244 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007245}
7246#endif /* HAVE_GETPGID */
7247
7248
Guido van Rossumb6775db1994-08-01 11:34:53 +00007249#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007250/*[clinic input]
7251os.getpgrp
7252
7253Return the current process group id.
7254[clinic start generated code]*/
7255
Larry Hastings2f936352014-08-05 14:04:04 +10007256static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007257os_getpgrp_impl(PyObject *module)
7258/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007259{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007260#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007261 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007262#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007263 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007264#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007265}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007266#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007268
Guido van Rossumb6775db1994-08-01 11:34:53 +00007269#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007270/*[clinic input]
7271os.setpgrp
7272
7273Make the current process the leader of its process group.
7274[clinic start generated code]*/
7275
Larry Hastings2f936352014-08-05 14:04:04 +10007276static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007277os_setpgrp_impl(PyObject *module)
7278/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007279{
Guido van Rossum64933891994-10-20 21:56:42 +00007280#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007281 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007282#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007283 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007284#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007285 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007286 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007287}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007288#endif /* HAVE_SETPGRP */
7289
Guido van Rossumad0ee831995-03-01 10:34:45 +00007290#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007291
7292#ifdef MS_WINDOWS
7293#include <tlhelp32.h>
7294
7295static PyObject*
7296win32_getppid()
7297{
7298 HANDLE snapshot;
7299 pid_t mypid;
7300 PyObject* result = NULL;
7301 BOOL have_record;
7302 PROCESSENTRY32 pe;
7303
7304 mypid = getpid(); /* This function never fails */
7305
7306 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7307 if (snapshot == INVALID_HANDLE_VALUE)
7308 return PyErr_SetFromWindowsErr(GetLastError());
7309
7310 pe.dwSize = sizeof(pe);
7311 have_record = Process32First(snapshot, &pe);
7312 while (have_record) {
7313 if (mypid == (pid_t)pe.th32ProcessID) {
7314 /* We could cache the ulong value in a static variable. */
7315 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7316 break;
7317 }
7318
7319 have_record = Process32Next(snapshot, &pe);
7320 }
7321
7322 /* If our loop exits and our pid was not found (result will be NULL)
7323 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7324 * error anyway, so let's raise it. */
7325 if (!result)
7326 result = PyErr_SetFromWindowsErr(GetLastError());
7327
7328 CloseHandle(snapshot);
7329
7330 return result;
7331}
7332#endif /*MS_WINDOWS*/
7333
Larry Hastings2f936352014-08-05 14:04:04 +10007334
7335/*[clinic input]
7336os.getppid
7337
7338Return the parent's process id.
7339
7340If the parent process has already exited, Windows machines will still
7341return its id; others systems will return the id of the 'init' process (1).
7342[clinic start generated code]*/
7343
Larry Hastings2f936352014-08-05 14:04:04 +10007344static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007345os_getppid_impl(PyObject *module)
7346/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007347{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007348#ifdef MS_WINDOWS
7349 return win32_getppid();
7350#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007351 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007352#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007353}
7354#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007356
Fred Drake12c6e2d1999-12-14 21:25:03 +00007357#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007358/*[clinic input]
7359os.getlogin
7360
7361Return the actual login name.
7362[clinic start generated code]*/
7363
Larry Hastings2f936352014-08-05 14:04:04 +10007364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007365os_getlogin_impl(PyObject *module)
7366/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007367{
Victor Stinner8c62be82010-05-06 00:08:46 +00007368 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007369#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007370 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007371 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007372
7373 if (GetUserNameW(user_name, &num_chars)) {
7374 /* num_chars is the number of unicode chars plus null terminator */
7375 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007376 }
7377 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007378 result = PyErr_SetFromWindowsErr(GetLastError());
7379#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007380 char *name;
7381 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007382
Victor Stinner8c62be82010-05-06 00:08:46 +00007383 errno = 0;
7384 name = getlogin();
7385 if (name == NULL) {
7386 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007387 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007388 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007389 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007390 }
7391 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007392 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007393 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007394#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007395 return result;
7396}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007397#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007398
Larry Hastings2f936352014-08-05 14:04:04 +10007399
Guido van Rossumad0ee831995-03-01 10:34:45 +00007400#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007401/*[clinic input]
7402os.getuid
7403
7404Return the current process's user id.
7405[clinic start generated code]*/
7406
Larry Hastings2f936352014-08-05 14:04:04 +10007407static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007408os_getuid_impl(PyObject *module)
7409/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007410{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007411 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007412}
Larry Hastings2f936352014-08-05 14:04:04 +10007413#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007414
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007415
Brian Curtineb24d742010-04-12 17:16:38 +00007416#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007417#define HAVE_KILL
7418#endif /* MS_WINDOWS */
7419
7420#ifdef HAVE_KILL
7421/*[clinic input]
7422os.kill
7423
7424 pid: pid_t
7425 signal: Py_ssize_t
7426 /
7427
7428Kill a process with a signal.
7429[clinic start generated code]*/
7430
Larry Hastings2f936352014-08-05 14:04:04 +10007431static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007432os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7433/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007434{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007435 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7436 return NULL;
7437 }
7438#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007439 if (kill(pid, (int)signal) == -1)
7440 return posix_error();
7441 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007442#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007443 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007444 DWORD sig = (DWORD)signal;
7445 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007446 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007447
Victor Stinner8c62be82010-05-06 00:08:46 +00007448 /* Console processes which share a common console can be sent CTRL+C or
7449 CTRL+BREAK events, provided they handle said events. */
7450 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007451 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007452 err = GetLastError();
7453 PyErr_SetFromWindowsErr(err);
7454 }
7455 else
7456 Py_RETURN_NONE;
7457 }
Brian Curtineb24d742010-04-12 17:16:38 +00007458
Victor Stinner8c62be82010-05-06 00:08:46 +00007459 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7460 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007461 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007462 if (handle == NULL) {
7463 err = GetLastError();
7464 return PyErr_SetFromWindowsErr(err);
7465 }
Brian Curtineb24d742010-04-12 17:16:38 +00007466
Victor Stinner8c62be82010-05-06 00:08:46 +00007467 if (TerminateProcess(handle, sig) == 0) {
7468 err = GetLastError();
7469 result = PyErr_SetFromWindowsErr(err);
7470 } else {
7471 Py_INCREF(Py_None);
7472 result = Py_None;
7473 }
Brian Curtineb24d742010-04-12 17:16:38 +00007474
Victor Stinner8c62be82010-05-06 00:08:46 +00007475 CloseHandle(handle);
7476 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007477#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007478}
Larry Hastings2f936352014-08-05 14:04:04 +10007479#endif /* HAVE_KILL */
7480
7481
7482#ifdef HAVE_KILLPG
7483/*[clinic input]
7484os.killpg
7485
7486 pgid: pid_t
7487 signal: int
7488 /
7489
7490Kill a process group with a signal.
7491[clinic start generated code]*/
7492
Larry Hastings2f936352014-08-05 14:04:04 +10007493static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007494os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7495/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007496{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007497 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7498 return NULL;
7499 }
Larry Hastings2f936352014-08-05 14:04:04 +10007500 /* XXX some man pages make the `pgid` parameter an int, others
7501 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7502 take the same type. Moreover, pid_t is always at least as wide as
7503 int (else compilation of this module fails), which is safe. */
7504 if (killpg(pgid, signal) == -1)
7505 return posix_error();
7506 Py_RETURN_NONE;
7507}
7508#endif /* HAVE_KILLPG */
7509
Brian Curtineb24d742010-04-12 17:16:38 +00007510
Guido van Rossumc0125471996-06-28 18:55:32 +00007511#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007512#ifdef HAVE_SYS_LOCK_H
7513#include <sys/lock.h>
7514#endif
7515
Larry Hastings2f936352014-08-05 14:04:04 +10007516/*[clinic input]
7517os.plock
7518 op: int
7519 /
7520
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007521Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007522[clinic start generated code]*/
7523
Larry Hastings2f936352014-08-05 14:04:04 +10007524static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007525os_plock_impl(PyObject *module, int op)
7526/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007527{
Victor Stinner8c62be82010-05-06 00:08:46 +00007528 if (plock(op) == -1)
7529 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007530 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007531}
Larry Hastings2f936352014-08-05 14:04:04 +10007532#endif /* HAVE_PLOCK */
7533
Guido van Rossumc0125471996-06-28 18:55:32 +00007534
Guido van Rossumb6775db1994-08-01 11:34:53 +00007535#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007536/*[clinic input]
7537os.setuid
7538
7539 uid: uid_t
7540 /
7541
7542Set the current process's user id.
7543[clinic start generated code]*/
7544
Larry Hastings2f936352014-08-05 14:04:04 +10007545static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007546os_setuid_impl(PyObject *module, uid_t uid)
7547/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007548{
Victor Stinner8c62be82010-05-06 00:08:46 +00007549 if (setuid(uid) < 0)
7550 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007551 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007552}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007553#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007554
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007555
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007556#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007557/*[clinic input]
7558os.seteuid
7559
7560 euid: uid_t
7561 /
7562
7563Set the current process's effective user id.
7564[clinic start generated code]*/
7565
Larry Hastings2f936352014-08-05 14:04:04 +10007566static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007567os_seteuid_impl(PyObject *module, uid_t euid)
7568/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007569{
7570 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007571 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007572 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007573}
7574#endif /* HAVE_SETEUID */
7575
Larry Hastings2f936352014-08-05 14:04:04 +10007576
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007577#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007578/*[clinic input]
7579os.setegid
7580
7581 egid: gid_t
7582 /
7583
7584Set the current process's effective group id.
7585[clinic start generated code]*/
7586
Larry Hastings2f936352014-08-05 14:04:04 +10007587static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007588os_setegid_impl(PyObject *module, gid_t egid)
7589/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007590{
7591 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007592 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007593 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007594}
7595#endif /* HAVE_SETEGID */
7596
Larry Hastings2f936352014-08-05 14:04:04 +10007597
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007598#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007599/*[clinic input]
7600os.setreuid
7601
7602 ruid: uid_t
7603 euid: uid_t
7604 /
7605
7606Set the current process's real and effective user ids.
7607[clinic start generated code]*/
7608
Larry Hastings2f936352014-08-05 14:04:04 +10007609static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007610os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7611/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007612{
Victor Stinner8c62be82010-05-06 00:08:46 +00007613 if (setreuid(ruid, euid) < 0) {
7614 return posix_error();
7615 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007616 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007617 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007618}
7619#endif /* HAVE_SETREUID */
7620
Larry Hastings2f936352014-08-05 14:04:04 +10007621
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007622#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007623/*[clinic input]
7624os.setregid
7625
7626 rgid: gid_t
7627 egid: gid_t
7628 /
7629
7630Set the current process's real and effective group ids.
7631[clinic start generated code]*/
7632
Larry Hastings2f936352014-08-05 14:04:04 +10007633static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007634os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7635/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007636{
7637 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007639 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007640}
7641#endif /* HAVE_SETREGID */
7642
Larry Hastings2f936352014-08-05 14:04:04 +10007643
Guido van Rossumb6775db1994-08-01 11:34:53 +00007644#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007645/*[clinic input]
7646os.setgid
7647 gid: gid_t
7648 /
7649
7650Set the current process's group id.
7651[clinic start generated code]*/
7652
Larry Hastings2f936352014-08-05 14:04:04 +10007653static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007654os_setgid_impl(PyObject *module, gid_t gid)
7655/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007656{
Victor Stinner8c62be82010-05-06 00:08:46 +00007657 if (setgid(gid) < 0)
7658 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007659 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007660}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007661#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007662
Larry Hastings2f936352014-08-05 14:04:04 +10007663
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007664#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007665/*[clinic input]
7666os.setgroups
7667
7668 groups: object
7669 /
7670
7671Set the groups of the current process to list.
7672[clinic start generated code]*/
7673
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007675os_setgroups(PyObject *module, PyObject *groups)
7676/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007677{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007678 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007679 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007680
Victor Stinner8c62be82010-05-06 00:08:46 +00007681 if (!PySequence_Check(groups)) {
7682 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7683 return NULL;
7684 }
7685 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007686 if (len < 0) {
7687 return NULL;
7688 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 if (len > MAX_GROUPS) {
7690 PyErr_SetString(PyExc_ValueError, "too many groups");
7691 return NULL;
7692 }
7693 for(i = 0; i < len; i++) {
7694 PyObject *elem;
7695 elem = PySequence_GetItem(groups, i);
7696 if (!elem)
7697 return NULL;
7698 if (!PyLong_Check(elem)) {
7699 PyErr_SetString(PyExc_TypeError,
7700 "groups must be integers");
7701 Py_DECREF(elem);
7702 return NULL;
7703 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007704 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007705 Py_DECREF(elem);
7706 return NULL;
7707 }
7708 }
7709 Py_DECREF(elem);
7710 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007711
Victor Stinner8c62be82010-05-06 00:08:46 +00007712 if (setgroups(len, grouplist) < 0)
7713 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007714 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007715}
7716#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007717
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007718#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7719static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02007720wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007721{
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08007723 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007724
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 if (pid == -1)
7726 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007727
Zackery Spytz682107c2019-09-09 09:48:32 -06007728 // If wait succeeded but no child was ready to report status, ru will not
7729 // have been populated.
7730 if (pid == 0) {
7731 memset(ru, 0, sizeof(*ru));
7732 }
7733
Eddie Elizondob3966632019-11-05 07:16:14 -08007734 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7735 if (m == NULL)
7736 return NULL;
Victor Stinner1c2fa782020-05-10 11:05:29 +02007737 struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08007738 Py_DECREF(m);
7739 if (struct_rusage == NULL)
7740 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007741
Victor Stinner8c62be82010-05-06 00:08:46 +00007742 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7743 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08007744 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007745 if (!result)
7746 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007747
7748#ifndef doubletime
7749#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7750#endif
7751
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007753 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007755 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007756#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007757 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7758 SET_INT(result, 2, ru->ru_maxrss);
7759 SET_INT(result, 3, ru->ru_ixrss);
7760 SET_INT(result, 4, ru->ru_idrss);
7761 SET_INT(result, 5, ru->ru_isrss);
7762 SET_INT(result, 6, ru->ru_minflt);
7763 SET_INT(result, 7, ru->ru_majflt);
7764 SET_INT(result, 8, ru->ru_nswap);
7765 SET_INT(result, 9, ru->ru_inblock);
7766 SET_INT(result, 10, ru->ru_oublock);
7767 SET_INT(result, 11, ru->ru_msgsnd);
7768 SET_INT(result, 12, ru->ru_msgrcv);
7769 SET_INT(result, 13, ru->ru_nsignals);
7770 SET_INT(result, 14, ru->ru_nvcsw);
7771 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007772#undef SET_INT
7773
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 if (PyErr_Occurred()) {
7775 Py_DECREF(result);
7776 return NULL;
7777 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007778
Victor Stinner8c62be82010-05-06 00:08:46 +00007779 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007780}
7781#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7782
Larry Hastings2f936352014-08-05 14:04:04 +10007783
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007784#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007785/*[clinic input]
7786os.wait3
7787
7788 options: int
7789Wait for completion of a child process.
7790
7791Returns a tuple of information about the child process:
7792 (pid, status, rusage)
7793[clinic start generated code]*/
7794
Larry Hastings2f936352014-08-05 14:04:04 +10007795static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007796os_wait3_impl(PyObject *module, int options)
7797/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007798{
Victor Stinner8c62be82010-05-06 00:08:46 +00007799 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007800 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007801 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007802 WAIT_TYPE status;
7803 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007804
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007805 do {
7806 Py_BEGIN_ALLOW_THREADS
7807 pid = wait3(&status, options, &ru);
7808 Py_END_ALLOW_THREADS
7809 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7810 if (pid < 0)
7811 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007812
Victor Stinner1c2fa782020-05-10 11:05:29 +02007813 return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007814}
7815#endif /* HAVE_WAIT3 */
7816
Larry Hastings2f936352014-08-05 14:04:04 +10007817
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007818#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007819/*[clinic input]
7820
7821os.wait4
7822
7823 pid: pid_t
7824 options: int
7825
7826Wait for completion of a specific child process.
7827
7828Returns a tuple of information about the child process:
7829 (pid, status, rusage)
7830[clinic start generated code]*/
7831
Larry Hastings2f936352014-08-05 14:04:04 +10007832static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007833os_wait4_impl(PyObject *module, pid_t pid, int options)
7834/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007835{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007836 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007837 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007838 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 WAIT_TYPE status;
7840 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007841
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007842 do {
7843 Py_BEGIN_ALLOW_THREADS
7844 res = wait4(pid, &status, options, &ru);
7845 Py_END_ALLOW_THREADS
7846 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7847 if (res < 0)
7848 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007849
Victor Stinner1c2fa782020-05-10 11:05:29 +02007850 return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007851}
7852#endif /* HAVE_WAIT4 */
7853
Larry Hastings2f936352014-08-05 14:04:04 +10007854
Ross Lagerwall7807c352011-03-17 20:20:30 +02007855#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007856/*[clinic input]
7857os.waitid
7858
7859 idtype: idtype_t
7860 Must be one of be P_PID, P_PGID or P_ALL.
7861 id: id_t
7862 The id to wait on.
7863 options: int
7864 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7865 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7866 /
7867
7868Returns the result of waiting for a process or processes.
7869
7870Returns either waitid_result or None if WNOHANG is specified and there are
7871no children in a waitable state.
7872[clinic start generated code]*/
7873
Larry Hastings2f936352014-08-05 14:04:04 +10007874static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007875os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7876/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007877{
7878 PyObject *result;
7879 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007880 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007881 siginfo_t si;
7882 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007883
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007884 do {
7885 Py_BEGIN_ALLOW_THREADS
7886 res = waitid(idtype, id, &si, options);
7887 Py_END_ALLOW_THREADS
7888 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7889 if (res < 0)
7890 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007891
7892 if (si.si_pid == 0)
7893 Py_RETURN_NONE;
7894
Hai Shif707d942020-03-16 21:15:01 +08007895 PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08007896 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007897 if (!result)
7898 return NULL;
7899
7900 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007901 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007902 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7903 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7904 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7905 if (PyErr_Occurred()) {
7906 Py_DECREF(result);
7907 return NULL;
7908 }
7909
7910 return result;
7911}
Larry Hastings2f936352014-08-05 14:04:04 +10007912#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007913
Larry Hastings2f936352014-08-05 14:04:04 +10007914
7915#if defined(HAVE_WAITPID)
7916/*[clinic input]
7917os.waitpid
7918 pid: pid_t
7919 options: int
7920 /
7921
7922Wait for completion of a given child process.
7923
7924Returns a tuple of information regarding the child process:
7925 (pid, status)
7926
7927The options argument is ignored on Windows.
7928[clinic start generated code]*/
7929
Larry Hastings2f936352014-08-05 14:04:04 +10007930static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007931os_waitpid_impl(PyObject *module, pid_t pid, int options)
7932/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007933{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007934 pid_t res;
7935 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 WAIT_TYPE status;
7937 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007938
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007939 do {
7940 Py_BEGIN_ALLOW_THREADS
7941 res = waitpid(pid, &status, options);
7942 Py_END_ALLOW_THREADS
7943 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7944 if (res < 0)
7945 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007946
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007947 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007948}
Tim Petersab034fa2002-02-01 11:27:43 +00007949#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007950/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007951/*[clinic input]
7952os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007953 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007954 options: int
7955 /
7956
7957Wait for completion of a given process.
7958
7959Returns a tuple of information regarding the process:
7960 (pid, status << 8)
7961
7962The options argument is ignored on Windows.
7963[clinic start generated code]*/
7964
Larry Hastings2f936352014-08-05 14:04:04 +10007965static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007966os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007967/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007968{
7969 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007970 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007971 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007972
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007973 do {
7974 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007975 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007976 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007977 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007978 Py_END_ALLOW_THREADS
7979 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007980 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007981 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007982
Victor Stinner9bee32b2020-04-22 16:30:35 +02007983 unsigned long long ustatus = (unsigned int)status;
7984
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 /* shift the status left a byte so this is more like the POSIX waitpid */
Victor Stinner9bee32b2020-04-22 16:30:35 +02007986 return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007987}
Larry Hastings2f936352014-08-05 14:04:04 +10007988#endif
7989
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007990
Guido van Rossumad0ee831995-03-01 10:34:45 +00007991#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007992/*[clinic input]
7993os.wait
7994
7995Wait for completion of a child process.
7996
7997Returns a tuple of information about the child process:
7998 (pid, status)
7999[clinic start generated code]*/
8000
Larry Hastings2f936352014-08-05 14:04:04 +10008001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008002os_wait_impl(PyObject *module)
8003/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00008004{
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008006 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 WAIT_TYPE status;
8008 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00008009
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008010 do {
8011 Py_BEGIN_ALLOW_THREADS
8012 pid = wait(&status);
8013 Py_END_ALLOW_THREADS
8014 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8015 if (pid < 0)
8016 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008017
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00008019}
Larry Hastings2f936352014-08-05 14:04:04 +10008020#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008021
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08008022#if defined(__linux__) && defined(__NR_pidfd_open)
8023/*[clinic input]
8024os.pidfd_open
8025 pid: pid_t
8026 flags: unsigned_int = 0
8027
8028Return a file descriptor referring to the process *pid*.
8029
8030The descriptor can be used to perform process management without races and
8031signals.
8032[clinic start generated code]*/
8033
8034static PyObject *
8035os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8036/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8037{
8038 int fd = syscall(__NR_pidfd_open, pid, flags);
8039 if (fd < 0) {
8040 return posix_error();
8041 }
8042 return PyLong_FromLong(fd);
8043}
8044#endif
8045
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008046
Larry Hastings9cf065c2012-06-22 16:30:09 -07008047#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008048/*[clinic input]
8049os.readlink
8050
8051 path: path_t
8052 *
8053 dir_fd: dir_fd(requires='readlinkat') = None
8054
8055Return a string representing the path to which the symbolic link points.
8056
8057If dir_fd is not None, it should be a file descriptor open to a directory,
8058and path should be relative; path will then be relative to that directory.
8059
8060dir_fd may not be implemented on your platform. If it is unavailable,
8061using it will raise a NotImplementedError.
8062[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008063
Barry Warsaw53699e91996-12-10 23:23:01 +00008064static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008065os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8066/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008067{
Berker Peksage0b5b202018-08-15 13:03:41 +03008068#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008069 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008070 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008071
8072 Py_BEGIN_ALLOW_THREADS
8073#ifdef HAVE_READLINKAT
8074 if (dir_fd != DEFAULT_DIR_FD)
8075 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8076 else
8077#endif
8078 length = readlink(path->narrow, buffer, MAXPATHLEN);
8079 Py_END_ALLOW_THREADS
8080
8081 if (length < 0) {
8082 return path_error(path);
8083 }
8084 buffer[length] = '\0';
8085
8086 if (PyUnicode_Check(path->object))
8087 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8088 else
8089 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008090#elif defined(MS_WINDOWS)
8091 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008092 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008093 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008094 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8095 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008096 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008097
Larry Hastings2f936352014-08-05 14:04:04 +10008098 /* First get a handle to the reparse point */
8099 Py_BEGIN_ALLOW_THREADS
8100 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008101 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008102 0,
8103 0,
8104 0,
8105 OPEN_EXISTING,
8106 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8107 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008108 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8109 /* New call DeviceIoControl to read the reparse point */
8110 io_result = DeviceIoControl(
8111 reparse_point_handle,
8112 FSCTL_GET_REPARSE_POINT,
8113 0, 0, /* in buffer */
8114 target_buffer, sizeof(target_buffer),
8115 &n_bytes_returned,
8116 0 /* we're not using OVERLAPPED_IO */
8117 );
8118 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008119 }
Larry Hastings2f936352014-08-05 14:04:04 +10008120 Py_END_ALLOW_THREADS
8121
Berker Peksage0b5b202018-08-15 13:03:41 +03008122 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008123 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008124 }
Larry Hastings2f936352014-08-05 14:04:04 +10008125
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008126 wchar_t *name = NULL;
8127 Py_ssize_t nameLen = 0;
8128 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008129 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008130 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8131 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8132 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008133 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008134 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8135 {
8136 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8137 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8138 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8139 }
8140 else
8141 {
8142 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8143 }
8144 if (name) {
8145 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8146 /* Our buffer is mutable, so this is okay */
8147 name[1] = L'\\';
8148 }
8149 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008150 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008151 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8152 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008153 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008154 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008155#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008156}
Berker Peksage0b5b202018-08-15 13:03:41 +03008157#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008158
Larry Hastings9cf065c2012-06-22 16:30:09 -07008159#if defined(MS_WINDOWS)
8160
Steve Dower6921e732018-03-05 14:26:08 -08008161/* Remove the last portion of the path - return 0 on success */
8162static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008163_dirnameW(WCHAR *path)
8164{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008165 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008166 size_t length = wcsnlen_s(path, MAX_PATH);
8167 if (length == MAX_PATH) {
8168 return -1;
8169 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008170
8171 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008172 for(ptr = path + length; ptr != path; ptr--) {
8173 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008174 break;
Steve Dower6921e732018-03-05 14:26:08 -08008175 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008176 }
8177 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008178 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008179}
8180
Minmin Gong7f21c9a2020-05-18 09:17:19 -07008181#endif
8182
8183#ifdef HAVE_SYMLINK
8184
8185#if defined(MS_WINDOWS)
8186
Victor Stinner31b3b922013-06-05 01:49:17 +02008187/* Is this path absolute? */
8188static int
8189_is_absW(const WCHAR *path)
8190{
Steve Dower6921e732018-03-05 14:26:08 -08008191 return path[0] == L'\\' || path[0] == L'/' ||
8192 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008193}
8194
Steve Dower6921e732018-03-05 14:26:08 -08008195/* join root and rest with a backslash - return 0 on success */
8196static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008197_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8198{
Victor Stinner31b3b922013-06-05 01:49:17 +02008199 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008200 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008201 }
8202
Steve Dower6921e732018-03-05 14:26:08 -08008203 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8204 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008205 }
Steve Dower6921e732018-03-05 14:26:08 -08008206
8207 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8208 return -1;
8209 }
8210
8211 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008212}
8213
Victor Stinner31b3b922013-06-05 01:49:17 +02008214/* Return True if the path at src relative to dest is a directory */
8215static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008216_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008217{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008218 WIN32_FILE_ATTRIBUTE_DATA src_info;
8219 WCHAR dest_parent[MAX_PATH];
8220 WCHAR src_resolved[MAX_PATH] = L"";
8221
8222 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008223 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8224 _dirnameW(dest_parent)) {
8225 return 0;
8226 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008227 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008228 if (_joinW(src_resolved, dest_parent, src)) {
8229 return 0;
8230 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008231 return (
8232 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8233 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8234 );
8235}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008236#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008237
Larry Hastings2f936352014-08-05 14:04:04 +10008238
8239/*[clinic input]
8240os.symlink
8241 src: path_t
8242 dst: path_t
8243 target_is_directory: bool = False
8244 *
8245 dir_fd: dir_fd(requires='symlinkat')=None
8246
8247# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8248
8249Create a symbolic link pointing to src named dst.
8250
8251target_is_directory is required on Windows if the target is to be
8252 interpreted as a directory. (On Windows, symlink requires
8253 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8254 target_is_directory is ignored on non-Windows platforms.
8255
8256If dir_fd is not None, it should be a file descriptor open to a directory,
8257 and path should be relative; path will then be relative to that directory.
8258dir_fd may not be implemented on your platform.
8259 If it is unavailable, using it will raise a NotImplementedError.
8260
8261[clinic start generated code]*/
8262
Larry Hastings2f936352014-08-05 14:04:04 +10008263static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008264os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008265 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008266/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008267{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008268#ifdef MS_WINDOWS
8269 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008270 DWORD flags = 0;
8271
8272 /* Assumed true, set to false if detected to not be available. */
8273 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008274#else
8275 int result;
8276#endif
8277
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008278 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8279 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8280 return NULL;
8281 }
8282
Larry Hastings9cf065c2012-06-22 16:30:09 -07008283#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008284
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008285 if (windows_has_symlink_unprivileged_flag) {
8286 /* Allow non-admin symlinks if system allows it. */
8287 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8288 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008289
Larry Hastings9cf065c2012-06-22 16:30:09 -07008290 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008291 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008292 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8293 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8294 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8295 }
8296
8297 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008298 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008299 Py_END_ALLOW_THREADS
8300
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008301 if (windows_has_symlink_unprivileged_flag && !result &&
8302 ERROR_INVALID_PARAMETER == GetLastError()) {
8303
8304 Py_BEGIN_ALLOW_THREADS
8305 _Py_BEGIN_SUPPRESS_IPH
8306 /* This error might be caused by
8307 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8308 Try again, and update windows_has_symlink_unprivileged_flag if we
8309 are successful this time.
8310
8311 NOTE: There is a risk of a race condition here if there are other
8312 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8313 another process (or thread) changes that condition in between our
8314 calls to CreateSymbolicLink.
8315 */
8316 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8317 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8318 _Py_END_SUPPRESS_IPH
8319 Py_END_ALLOW_THREADS
8320
8321 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8322 windows_has_symlink_unprivileged_flag = FALSE;
8323 }
8324 }
8325
Larry Hastings2f936352014-08-05 14:04:04 +10008326 if (!result)
8327 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008328
8329#else
8330
Steve Dower6921e732018-03-05 14:26:08 -08008331 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8332 PyErr_SetString(PyExc_ValueError,
8333 "symlink: src and dst must be the same type");
8334 return NULL;
8335 }
8336
Larry Hastings9cf065c2012-06-22 16:30:09 -07008337 Py_BEGIN_ALLOW_THREADS
8338#if HAVE_SYMLINKAT
8339 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10008340 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008341 else
8342#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008343 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008344 Py_END_ALLOW_THREADS
8345
Larry Hastings2f936352014-08-05 14:04:04 +10008346 if (result)
8347 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008348#endif
8349
Larry Hastings2f936352014-08-05 14:04:04 +10008350 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008351}
8352#endif /* HAVE_SYMLINK */
8353
Larry Hastings9cf065c2012-06-22 16:30:09 -07008354
Brian Curtind40e6f72010-07-08 21:39:08 +00008355
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008356
Larry Hastings605a62d2012-06-24 04:33:36 -07008357static PyStructSequence_Field times_result_fields[] = {
8358 {"user", "user time"},
8359 {"system", "system time"},
8360 {"children_user", "user time of children"},
8361 {"children_system", "system time of children"},
8362 {"elapsed", "elapsed time since an arbitrary point in the past"},
8363 {NULL}
8364};
8365
8366PyDoc_STRVAR(times_result__doc__,
8367"times_result: Result from os.times().\n\n\
8368This object may be accessed either as a tuple of\n\
8369 (user, system, children_user, children_system, elapsed),\n\
8370or via the attributes user, system, children_user, children_system,\n\
8371and elapsed.\n\
8372\n\
8373See os.times for more information.");
8374
8375static PyStructSequence_Desc times_result_desc = {
8376 "times_result", /* name */
8377 times_result__doc__, /* doc */
8378 times_result_fields,
8379 5
8380};
8381
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008382#ifdef MS_WINDOWS
8383#define HAVE_TIMES /* mandatory, for the method table */
8384#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008385
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008386#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008387
8388static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008389build_times_result(PyObject *module, double user, double system,
Larry Hastings605a62d2012-06-24 04:33:36 -07008390 double children_user, double children_system,
8391 double elapsed)
8392{
Victor Stinner1c2fa782020-05-10 11:05:29 +02008393 PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008394 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008395 if (value == NULL)
8396 return NULL;
8397
8398#define SET(i, field) \
8399 { \
8400 PyObject *o = PyFloat_FromDouble(field); \
8401 if (!o) { \
8402 Py_DECREF(value); \
8403 return NULL; \
8404 } \
8405 PyStructSequence_SET_ITEM(value, i, o); \
8406 } \
8407
8408 SET(0, user);
8409 SET(1, system);
8410 SET(2, children_user);
8411 SET(3, children_system);
8412 SET(4, elapsed);
8413
8414#undef SET
8415
8416 return value;
8417}
8418
Larry Hastings605a62d2012-06-24 04:33:36 -07008419
Larry Hastings2f936352014-08-05 14:04:04 +10008420#ifndef MS_WINDOWS
8421#define NEED_TICKS_PER_SECOND
8422static long ticks_per_second = -1;
8423#endif /* MS_WINDOWS */
8424
8425/*[clinic input]
8426os.times
8427
8428Return a collection containing process timing information.
8429
8430The object returned behaves like a named tuple with these fields:
8431 (utime, stime, cutime, cstime, elapsed_time)
8432All fields are floating point numbers.
8433[clinic start generated code]*/
8434
Larry Hastings2f936352014-08-05 14:04:04 +10008435static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008436os_times_impl(PyObject *module)
8437/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008438#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008439{
Victor Stinner8c62be82010-05-06 00:08:46 +00008440 FILETIME create, exit, kernel, user;
8441 HANDLE hProc;
8442 hProc = GetCurrentProcess();
8443 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8444 /* The fields of a FILETIME structure are the hi and lo part
8445 of a 64-bit value expressed in 100 nanosecond units.
8446 1e7 is one second in such units; 1e-7 the inverse.
8447 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8448 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02008449 return build_times_result(module,
Victor Stinner8c62be82010-05-06 00:08:46 +00008450 (double)(user.dwHighDateTime*429.4967296 +
8451 user.dwLowDateTime*1e-7),
8452 (double)(kernel.dwHighDateTime*429.4967296 +
8453 kernel.dwLowDateTime*1e-7),
8454 (double)0,
8455 (double)0,
8456 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008457}
Larry Hastings2f936352014-08-05 14:04:04 +10008458#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008459{
Larry Hastings2f936352014-08-05 14:04:04 +10008460
8461
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008462 struct tms t;
8463 clock_t c;
8464 errno = 0;
8465 c = times(&t);
8466 if (c == (clock_t) -1)
8467 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02008468 return build_times_result(module,
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008469 (double)t.tms_utime / ticks_per_second,
8470 (double)t.tms_stime / ticks_per_second,
8471 (double)t.tms_cutime / ticks_per_second,
8472 (double)t.tms_cstime / ticks_per_second,
8473 (double)c / ticks_per_second);
8474}
Larry Hastings2f936352014-08-05 14:04:04 +10008475#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008476#endif /* HAVE_TIMES */
8477
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008478
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008479#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008480/*[clinic input]
8481os.getsid
8482
8483 pid: pid_t
8484 /
8485
8486Call the system call getsid(pid) and return the result.
8487[clinic start generated code]*/
8488
Larry Hastings2f936352014-08-05 14:04:04 +10008489static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008490os_getsid_impl(PyObject *module, pid_t pid)
8491/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008492{
Victor Stinner8c62be82010-05-06 00:08:46 +00008493 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008494 sid = getsid(pid);
8495 if (sid < 0)
8496 return posix_error();
8497 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008498}
8499#endif /* HAVE_GETSID */
8500
8501
Guido van Rossumb6775db1994-08-01 11:34:53 +00008502#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008503/*[clinic input]
8504os.setsid
8505
8506Call the system call setsid().
8507[clinic start generated code]*/
8508
Larry Hastings2f936352014-08-05 14:04:04 +10008509static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008510os_setsid_impl(PyObject *module)
8511/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008512{
Victor Stinner8c62be82010-05-06 00:08:46 +00008513 if (setsid() < 0)
8514 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008515 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008516}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008517#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008518
Larry Hastings2f936352014-08-05 14:04:04 +10008519
Guido van Rossumb6775db1994-08-01 11:34:53 +00008520#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008521/*[clinic input]
8522os.setpgid
8523
8524 pid: pid_t
8525 pgrp: pid_t
8526 /
8527
8528Call the system call setpgid(pid, pgrp).
8529[clinic start generated code]*/
8530
Larry Hastings2f936352014-08-05 14:04:04 +10008531static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008532os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8533/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008534{
Victor Stinner8c62be82010-05-06 00:08:46 +00008535 if (setpgid(pid, pgrp) < 0)
8536 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008537 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008538}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008539#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008540
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008541
Guido van Rossumb6775db1994-08-01 11:34:53 +00008542#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008543/*[clinic input]
8544os.tcgetpgrp
8545
8546 fd: int
8547 /
8548
8549Return the process group associated with the terminal specified by fd.
8550[clinic start generated code]*/
8551
Larry Hastings2f936352014-08-05 14:04:04 +10008552static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008553os_tcgetpgrp_impl(PyObject *module, int fd)
8554/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008555{
8556 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008557 if (pgid < 0)
8558 return posix_error();
8559 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008560}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008561#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008562
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008563
Guido van Rossumb6775db1994-08-01 11:34:53 +00008564#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008565/*[clinic input]
8566os.tcsetpgrp
8567
8568 fd: int
8569 pgid: pid_t
8570 /
8571
8572Set the process group associated with the terminal specified by fd.
8573[clinic start generated code]*/
8574
Larry Hastings2f936352014-08-05 14:04:04 +10008575static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008576os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8577/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008578{
Victor Stinner8c62be82010-05-06 00:08:46 +00008579 if (tcsetpgrp(fd, pgid) < 0)
8580 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008581 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008582}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008583#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008584
Guido van Rossum687dd131993-05-17 08:34:16 +00008585/* Functions acting on file descriptors */
8586
Victor Stinnerdaf45552013-08-28 00:53:59 +02008587#ifdef O_CLOEXEC
8588extern int _Py_open_cloexec_works;
8589#endif
8590
Larry Hastings2f936352014-08-05 14:04:04 +10008591
8592/*[clinic input]
8593os.open -> int
8594 path: path_t
8595 flags: int
8596 mode: int = 0o777
8597 *
8598 dir_fd: dir_fd(requires='openat') = None
8599
8600# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8601
8602Open a file for low level IO. Returns a file descriptor (integer).
8603
8604If dir_fd is not None, it should be a file descriptor open to a directory,
8605 and path should be relative; path will then be relative to that directory.
8606dir_fd may not be implemented on your platform.
8607 If it is unavailable, using it will raise a NotImplementedError.
8608[clinic start generated code]*/
8609
Larry Hastings2f936352014-08-05 14:04:04 +10008610static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008611os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8612/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008613{
8614 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008615 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008616
Victor Stinnerdaf45552013-08-28 00:53:59 +02008617#ifdef O_CLOEXEC
8618 int *atomic_flag_works = &_Py_open_cloexec_works;
8619#elif !defined(MS_WINDOWS)
8620 int *atomic_flag_works = NULL;
8621#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008622
Victor Stinnerdaf45552013-08-28 00:53:59 +02008623#ifdef MS_WINDOWS
8624 flags |= O_NOINHERIT;
8625#elif defined(O_CLOEXEC)
8626 flags |= O_CLOEXEC;
8627#endif
8628
Steve Dowerb82e17e2019-05-23 08:45:22 -07008629 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
8630 return -1;
8631 }
8632
Steve Dower8fc89802015-04-12 00:26:27 -04008633 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008634 do {
8635 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008636#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008637 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008638#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008639#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008640 if (dir_fd != DEFAULT_DIR_FD)
8641 fd = openat(dir_fd, path->narrow, flags, mode);
8642 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008643#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008644 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008645#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008646 Py_END_ALLOW_THREADS
8647 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008648 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008649
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008650 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008651 if (!async_err)
8652 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008653 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008654 }
8655
Victor Stinnerdaf45552013-08-28 00:53:59 +02008656#ifndef MS_WINDOWS
8657 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8658 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008659 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008660 }
8661#endif
8662
Larry Hastings2f936352014-08-05 14:04:04 +10008663 return fd;
8664}
8665
8666
8667/*[clinic input]
8668os.close
8669
8670 fd: int
8671
8672Close a file descriptor.
8673[clinic start generated code]*/
8674
Barry Warsaw53699e91996-12-10 23:23:01 +00008675static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008676os_close_impl(PyObject *module, int fd)
8677/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008678{
Larry Hastings2f936352014-08-05 14:04:04 +10008679 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008680 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8681 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8682 * for more details.
8683 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008684 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008685 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008686 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008687 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 Py_END_ALLOW_THREADS
8689 if (res < 0)
8690 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008691 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008692}
8693
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008694
Jakub Kulíke20134f2019-09-11 17:11:57 +02008695#ifdef HAVE_FDWALK
8696static int
8697_fdwalk_close_func(void *lohi, int fd)
8698{
8699 int lo = ((int *)lohi)[0];
8700 int hi = ((int *)lohi)[1];
8701
Victor Stinner162c5672020-04-24 12:00:51 +02008702 if (fd >= hi) {
Jakub Kulíke20134f2019-09-11 17:11:57 +02008703 return 1;
Victor Stinner162c5672020-04-24 12:00:51 +02008704 }
8705 else if (fd >= lo) {
8706 /* Ignore errors */
8707 (void)close(fd);
8708 }
Jakub Kulíke20134f2019-09-11 17:11:57 +02008709 return 0;
8710}
8711#endif /* HAVE_FDWALK */
8712
Larry Hastings2f936352014-08-05 14:04:04 +10008713/*[clinic input]
8714os.closerange
8715
8716 fd_low: int
8717 fd_high: int
8718 /
8719
8720Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8721[clinic start generated code]*/
8722
Larry Hastings2f936352014-08-05 14:04:04 +10008723static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008724os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8725/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008726{
Jakub Kulíke20134f2019-09-11 17:11:57 +02008727#ifdef HAVE_FDWALK
8728 int lohi[2];
Jakub Kulíke20134f2019-09-11 17:11:57 +02008729#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008730 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008731 _Py_BEGIN_SUPPRESS_IPH
Jakub Kulíke20134f2019-09-11 17:11:57 +02008732#ifdef HAVE_FDWALK
8733 lohi[0] = Py_MAX(fd_low, 0);
8734 lohi[1] = fd_high;
8735 fdwalk(_fdwalk_close_func, lohi);
8736#else
Victor Stinner162c5672020-04-24 12:00:51 +02008737 fd_low = Py_MAX(fd_low, 0);
8738#ifdef __FreeBSD__
8739 if (fd_high >= sysconf(_SC_OPEN_MAX)) {
8740 /* Any errors encountered while closing file descriptors are ignored */
8741 closefrom(fd_low);
8742 }
8743 else
8744#endif
8745 {
8746 for (int i = fd_low; i < fd_high; i++) {
8747 /* Ignore errors */
8748 (void)close(i);
8749 }
8750 }
Jakub Kulíke20134f2019-09-11 17:11:57 +02008751#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008752 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008753 Py_END_ALLOW_THREADS
8754 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008755}
8756
8757
Larry Hastings2f936352014-08-05 14:04:04 +10008758/*[clinic input]
8759os.dup -> int
8760
8761 fd: int
8762 /
8763
8764Return a duplicate of a file descriptor.
8765[clinic start generated code]*/
8766
Larry Hastings2f936352014-08-05 14:04:04 +10008767static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008768os_dup_impl(PyObject *module, int fd)
8769/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008770{
8771 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008772}
8773
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008774
Larry Hastings2f936352014-08-05 14:04:04 +10008775/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008776os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008777 fd: int
8778 fd2: int
8779 inheritable: bool=True
8780
8781Duplicate file descriptor.
8782[clinic start generated code]*/
8783
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008784static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008785os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008786/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008787{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008788 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008789#if defined(HAVE_DUP3) && \
8790 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8791 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008792 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008793#endif
8794
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008795 if (fd < 0 || fd2 < 0) {
8796 posix_error();
8797 return -1;
8798 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008799
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008800 /* dup2() can fail with EINTR if the target FD is already open, because it
8801 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8802 * upon close(), and therefore below.
8803 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008804#ifdef MS_WINDOWS
8805 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008806 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008807 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008808 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008809 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008810 if (res < 0) {
8811 posix_error();
8812 return -1;
8813 }
8814 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008815
8816 /* Character files like console cannot be make non-inheritable */
8817 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8818 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008819 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008820 }
8821
8822#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8823 Py_BEGIN_ALLOW_THREADS
8824 if (!inheritable)
8825 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8826 else
8827 res = dup2(fd, fd2);
8828 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008829 if (res < 0) {
8830 posix_error();
8831 return -1;
8832 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008833
8834#else
8835
8836#ifdef HAVE_DUP3
8837 if (!inheritable && dup3_works != 0) {
8838 Py_BEGIN_ALLOW_THREADS
8839 res = dup3(fd, fd2, O_CLOEXEC);
8840 Py_END_ALLOW_THREADS
8841 if (res < 0) {
8842 if (dup3_works == -1)
8843 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008844 if (dup3_works) {
8845 posix_error();
8846 return -1;
8847 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008848 }
8849 }
8850
8851 if (inheritable || dup3_works == 0)
8852 {
8853#endif
8854 Py_BEGIN_ALLOW_THREADS
8855 res = dup2(fd, fd2);
8856 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008857 if (res < 0) {
8858 posix_error();
8859 return -1;
8860 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008861
8862 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8863 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008864 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008865 }
8866#ifdef HAVE_DUP3
8867 }
8868#endif
8869
8870#endif
8871
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008872 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008873}
8874
Larry Hastings2f936352014-08-05 14:04:04 +10008875
Ross Lagerwall7807c352011-03-17 20:20:30 +02008876#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008877/*[clinic input]
8878os.lockf
8879
8880 fd: int
8881 An open file descriptor.
8882 command: int
8883 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8884 length: Py_off_t
8885 The number of bytes to lock, starting at the current position.
8886 /
8887
8888Apply, test or remove a POSIX lock on an open file descriptor.
8889
8890[clinic start generated code]*/
8891
Larry Hastings2f936352014-08-05 14:04:04 +10008892static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008893os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8894/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008895{
8896 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008897
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008898 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
8899 return NULL;
8900 }
8901
Ross Lagerwall7807c352011-03-17 20:20:30 +02008902 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008903 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008904 Py_END_ALLOW_THREADS
8905
8906 if (res < 0)
8907 return posix_error();
8908
8909 Py_RETURN_NONE;
8910}
Larry Hastings2f936352014-08-05 14:04:04 +10008911#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008912
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008913
Larry Hastings2f936352014-08-05 14:04:04 +10008914/*[clinic input]
8915os.lseek -> Py_off_t
8916
8917 fd: int
8918 position: Py_off_t
8919 how: int
8920 /
8921
8922Set the position of a file descriptor. Return the new position.
8923
8924Return the new cursor position in number of bytes
8925relative to the beginning of the file.
8926[clinic start generated code]*/
8927
Larry Hastings2f936352014-08-05 14:04:04 +10008928static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008929os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8930/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008931{
8932 Py_off_t result;
8933
Guido van Rossum687dd131993-05-17 08:34:16 +00008934#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8936 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008937 case 0: how = SEEK_SET; break;
8938 case 1: how = SEEK_CUR; break;
8939 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008940 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008941#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008942
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008944 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008945#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008946 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008947#else
Larry Hastings2f936352014-08-05 14:04:04 +10008948 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008949#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008950 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008952 if (result < 0)
8953 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008954
Larry Hastings2f936352014-08-05 14:04:04 +10008955 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008956}
8957
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008958
Larry Hastings2f936352014-08-05 14:04:04 +10008959/*[clinic input]
8960os.read
8961 fd: int
8962 length: Py_ssize_t
8963 /
8964
8965Read from a file descriptor. Returns a bytes object.
8966[clinic start generated code]*/
8967
Larry Hastings2f936352014-08-05 14:04:04 +10008968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008969os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8970/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008971{
Victor Stinner8c62be82010-05-06 00:08:46 +00008972 Py_ssize_t n;
8973 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008974
8975 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008976 errno = EINVAL;
8977 return posix_error();
8978 }
Larry Hastings2f936352014-08-05 14:04:04 +10008979
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008980 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008981
8982 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008983 if (buffer == NULL)
8984 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008985
Victor Stinner66aab0c2015-03-19 22:53:20 +01008986 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8987 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008988 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008989 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008990 }
Larry Hastings2f936352014-08-05 14:04:04 +10008991
8992 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008993 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008994
Victor Stinner8c62be82010-05-06 00:08:46 +00008995 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008996}
8997
Ross Lagerwall7807c352011-03-17 20:20:30 +02008998#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008999 || defined(__APPLE__))) \
9000 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
9001 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9002static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009003iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009004{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009005 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009006
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009007 *iov = PyMem_New(struct iovec, cnt);
9008 if (*iov == NULL) {
9009 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009010 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009011 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009012
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009013 *buf = PyMem_New(Py_buffer, cnt);
9014 if (*buf == NULL) {
9015 PyMem_Del(*iov);
9016 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009017 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009018 }
9019
9020 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009021 PyObject *item = PySequence_GetItem(seq, i);
9022 if (item == NULL)
9023 goto fail;
9024 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
9025 Py_DECREF(item);
9026 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009027 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009028 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009029 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009030 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009031 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009032 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009033
9034fail:
9035 PyMem_Del(*iov);
9036 for (j = 0; j < i; j++) {
9037 PyBuffer_Release(&(*buf)[j]);
9038 }
9039 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01009040 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009041}
9042
9043static void
9044iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9045{
9046 int i;
9047 PyMem_Del(iov);
9048 for (i = 0; i < cnt; i++) {
9049 PyBuffer_Release(&buf[i]);
9050 }
9051 PyMem_Del(buf);
9052}
9053#endif
9054
Larry Hastings2f936352014-08-05 14:04:04 +10009055
Ross Lagerwall7807c352011-03-17 20:20:30 +02009056#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10009057/*[clinic input]
9058os.readv -> Py_ssize_t
9059
9060 fd: int
9061 buffers: object
9062 /
9063
9064Read from a file descriptor fd into an iterable of buffers.
9065
9066The buffers should be mutable buffers accepting bytes.
9067readv will transfer data into each buffer until it is full
9068and then move on to the next buffer in the sequence to hold
9069the rest of the data.
9070
9071readv returns the total number of bytes read,
9072which may be less than the total capacity of all the buffers.
9073[clinic start generated code]*/
9074
Larry Hastings2f936352014-08-05 14:04:04 +10009075static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009076os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9077/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009078{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009079 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009080 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009081 struct iovec *iov;
9082 Py_buffer *buf;
9083
Larry Hastings2f936352014-08-05 14:04:04 +10009084 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009085 PyErr_SetString(PyExc_TypeError,
9086 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009087 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009088 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009089
Larry Hastings2f936352014-08-05 14:04:04 +10009090 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009091 if (cnt < 0)
9092 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009093
9094 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9095 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009096
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009097 do {
9098 Py_BEGIN_ALLOW_THREADS
9099 n = readv(fd, iov, cnt);
9100 Py_END_ALLOW_THREADS
9101 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009102
9103 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009104 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009105 if (!async_err)
9106 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009107 return -1;
9108 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009109
Larry Hastings2f936352014-08-05 14:04:04 +10009110 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009111}
Larry Hastings2f936352014-08-05 14:04:04 +10009112#endif /* HAVE_READV */
9113
Ross Lagerwall7807c352011-03-17 20:20:30 +02009114
9115#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009116/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009117os.pread
9118
9119 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009120 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009121 offset: Py_off_t
9122 /
9123
9124Read a number of bytes from a file descriptor starting at a particular offset.
9125
9126Read length bytes from file descriptor fd, starting at offset bytes from
9127the beginning of the file. The file offset remains unchanged.
9128[clinic start generated code]*/
9129
Larry Hastings2f936352014-08-05 14:04:04 +10009130static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009131os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9132/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009133{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009134 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009135 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009136 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009137
Larry Hastings2f936352014-08-05 14:04:04 +10009138 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009139 errno = EINVAL;
9140 return posix_error();
9141 }
Larry Hastings2f936352014-08-05 14:04:04 +10009142 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009143 if (buffer == NULL)
9144 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009145
9146 do {
9147 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009148 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009149 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009150 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009151 Py_END_ALLOW_THREADS
9152 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9153
Ross Lagerwall7807c352011-03-17 20:20:30 +02009154 if (n < 0) {
9155 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009156 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009157 }
Larry Hastings2f936352014-08-05 14:04:04 +10009158 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009159 _PyBytes_Resize(&buffer, n);
9160 return buffer;
9161}
Larry Hastings2f936352014-08-05 14:04:04 +10009162#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009163
Pablo Galindo4defba32018-01-27 16:16:37 +00009164#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9165/*[clinic input]
9166os.preadv -> Py_ssize_t
9167
9168 fd: int
9169 buffers: object
9170 offset: Py_off_t
9171 flags: int = 0
9172 /
9173
9174Reads from a file descriptor into a number of mutable bytes-like objects.
9175
9176Combines the functionality of readv() and pread(). As readv(), it will
9177transfer data into each buffer until it is full and then move on to the next
9178buffer in the sequence to hold the rest of the data. Its fourth argument,
9179specifies the file offset at which the input operation is to be performed. It
9180will return the total number of bytes read (which can be less than the total
9181capacity of all the objects).
9182
9183The flags argument contains a bitwise OR of zero or more of the following flags:
9184
9185- RWF_HIPRI
9186- RWF_NOWAIT
9187
9188Using non-zero flags requires Linux 4.6 or newer.
9189[clinic start generated code]*/
9190
9191static Py_ssize_t
9192os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9193 int flags)
9194/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9195{
9196 Py_ssize_t cnt, n;
9197 int async_err = 0;
9198 struct iovec *iov;
9199 Py_buffer *buf;
9200
9201 if (!PySequence_Check(buffers)) {
9202 PyErr_SetString(PyExc_TypeError,
9203 "preadv2() arg 2 must be a sequence");
9204 return -1;
9205 }
9206
9207 cnt = PySequence_Size(buffers);
9208 if (cnt < 0) {
9209 return -1;
9210 }
9211
9212#ifndef HAVE_PREADV2
9213 if(flags != 0) {
9214 argument_unavailable_error("preadv2", "flags");
9215 return -1;
9216 }
9217#endif
9218
9219 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9220 return -1;
9221 }
9222#ifdef HAVE_PREADV2
9223 do {
9224 Py_BEGIN_ALLOW_THREADS
9225 _Py_BEGIN_SUPPRESS_IPH
9226 n = preadv2(fd, iov, cnt, offset, flags);
9227 _Py_END_SUPPRESS_IPH
9228 Py_END_ALLOW_THREADS
9229 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9230#else
9231 do {
9232 Py_BEGIN_ALLOW_THREADS
9233 _Py_BEGIN_SUPPRESS_IPH
9234 n = preadv(fd, iov, cnt, offset);
9235 _Py_END_SUPPRESS_IPH
9236 Py_END_ALLOW_THREADS
9237 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9238#endif
9239
9240 iov_cleanup(iov, buf, cnt);
9241 if (n < 0) {
9242 if (!async_err) {
9243 posix_error();
9244 }
9245 return -1;
9246 }
9247
9248 return n;
9249}
9250#endif /* HAVE_PREADV */
9251
Larry Hastings2f936352014-08-05 14:04:04 +10009252
9253/*[clinic input]
9254os.write -> Py_ssize_t
9255
9256 fd: int
9257 data: Py_buffer
9258 /
9259
9260Write a bytes object to a file descriptor.
9261[clinic start generated code]*/
9262
Larry Hastings2f936352014-08-05 14:04:04 +10009263static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009264os_write_impl(PyObject *module, int fd, Py_buffer *data)
9265/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009266{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009267 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009268}
9269
9270#ifdef HAVE_SENDFILE
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009271#ifdef __APPLE__
9272/*[clinic input]
9273os.sendfile
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009274
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009275 out_fd: int
9276 in_fd: int
9277 offset: Py_off_t
9278 count as sbytes: Py_off_t
9279 headers: object(c_default="NULL") = ()
9280 trailers: object(c_default="NULL") = ()
9281 flags: int = 0
9282
9283Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9284[clinic start generated code]*/
9285
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009286static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009287os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9288 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9289 int flags)
9290/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9291#elif defined(__FreeBSD__) || defined(__DragonFly__)
9292/*[clinic input]
9293os.sendfile
9294
9295 out_fd: int
9296 in_fd: int
9297 offset: Py_off_t
9298 count: Py_ssize_t
9299 headers: object(c_default="NULL") = ()
9300 trailers: object(c_default="NULL") = ()
9301 flags: int = 0
9302
9303Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9304[clinic start generated code]*/
9305
9306static PyObject *
9307os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9308 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9309 int flags)
9310/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9311#else
9312/*[clinic input]
9313os.sendfile
9314
9315 out_fd: int
9316 in_fd: int
9317 offset as offobj: object
9318 count: Py_ssize_t
9319
9320Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9321[clinic start generated code]*/
9322
9323static PyObject *
9324os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9325 Py_ssize_t count)
9326/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9327#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009328{
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009329 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009330 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009331
9332#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9333#ifndef __APPLE__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009334 off_t sbytes;
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009335#endif
9336 Py_buffer *hbuf, *tbuf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009337 struct sf_hdtr sf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009338
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009339 sf.headers = NULL;
9340 sf.trailers = NULL;
9341
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009342 if (headers != NULL) {
9343 if (!PySequence_Check(headers)) {
9344 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009345 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009346 return NULL;
9347 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009348 Py_ssize_t i = PySequence_Size(headers);
9349 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009350 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009351 if (i > INT_MAX) {
9352 PyErr_SetString(PyExc_OverflowError,
9353 "sendfile() header is too large");
9354 return NULL;
9355 }
9356 if (i > 0) {
9357 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009358 if (iov_setup(&(sf.headers), &hbuf,
9359 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009360 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009361#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009362 for (i = 0; i < sf.hdr_cnt; i++) {
9363 Py_ssize_t blen = sf.headers[i].iov_len;
9364# define OFF_T_MAX 0x7fffffffffffffff
9365 if (sbytes >= OFF_T_MAX - blen) {
9366 PyErr_SetString(PyExc_OverflowError,
9367 "sendfile() header is too large");
9368 return NULL;
9369 }
9370 sbytes += blen;
9371 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009372#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009373 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009374 }
9375 }
9376 if (trailers != NULL) {
9377 if (!PySequence_Check(trailers)) {
9378 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009379 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009380 return NULL;
9381 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009382 Py_ssize_t i = PySequence_Size(trailers);
9383 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009384 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009385 if (i > INT_MAX) {
9386 PyErr_SetString(PyExc_OverflowError,
9387 "sendfile() trailer is too large");
9388 return NULL;
9389 }
9390 if (i > 0) {
9391 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009392 if (iov_setup(&(sf.trailers), &tbuf,
9393 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009394 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009395 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009396 }
9397 }
9398
Steve Dower8fc89802015-04-12 00:26:27 -04009399 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009400 do {
9401 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009402#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009403 ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009404#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009405 ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009406#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009407 Py_END_ALLOW_THREADS
9408 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009409 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009410
9411 if (sf.headers != NULL)
9412 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9413 if (sf.trailers != NULL)
9414 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9415
9416 if (ret < 0) {
9417 if ((errno == EAGAIN) || (errno == EBUSY)) {
9418 if (sbytes != 0) {
9419 // some data has been sent
9420 goto done;
9421 }
9422 else {
9423 // no data has been sent; upper application is supposed
9424 // to retry on EAGAIN or EBUSY
9425 return posix_error();
9426 }
9427 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009428 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009429 }
9430 goto done;
9431
9432done:
9433 #if !defined(HAVE_LARGEFILE_SUPPORT)
9434 return Py_BuildValue("l", sbytes);
9435 #else
9436 return Py_BuildValue("L", sbytes);
9437 #endif
9438
9439#else
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009440#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009441 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009442 do {
9443 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009444 ret = sendfile(out_fd, in_fd, NULL, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009445 Py_END_ALLOW_THREADS
9446 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009447 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009448 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009449 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009450 }
9451#endif
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009452 off_t offset;
Larry Hastings2f936352014-08-05 14:04:04 +10009453 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009454 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009455
9456 do {
9457 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009458 ret = sendfile(out_fd, in_fd, &offset, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009459 Py_END_ALLOW_THREADS
9460 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009461 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009462 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009463 return Py_BuildValue("n", ret);
9464#endif
9465}
Larry Hastings2f936352014-08-05 14:04:04 +10009466#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009467
Larry Hastings2f936352014-08-05 14:04:04 +10009468
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009469#if defined(__APPLE__)
9470/*[clinic input]
9471os._fcopyfile
9472
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009473 in_fd: int
9474 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009475 flags: int
9476 /
9477
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009478Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009479[clinic start generated code]*/
9480
9481static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009482os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9483/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009484{
9485 int ret;
9486
9487 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009488 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009489 Py_END_ALLOW_THREADS
9490 if (ret < 0)
9491 return posix_error();
9492 Py_RETURN_NONE;
9493}
9494#endif
9495
9496
Larry Hastings2f936352014-08-05 14:04:04 +10009497/*[clinic input]
9498os.fstat
9499
9500 fd : int
9501
9502Perform a stat system call on the given file descriptor.
9503
9504Like stat(), but for an open file descriptor.
9505Equivalent to os.stat(fd).
9506[clinic start generated code]*/
9507
Larry Hastings2f936352014-08-05 14:04:04 +10009508static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009509os_fstat_impl(PyObject *module, int fd)
9510/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009511{
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 STRUCT_STAT st;
9513 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009514 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009515
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009516 do {
9517 Py_BEGIN_ALLOW_THREADS
9518 res = FSTAT(fd, &st);
9519 Py_END_ALLOW_THREADS
9520 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009521 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009522#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009523 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009524#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009525 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009526#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 }
Tim Peters5aa91602002-01-30 05:46:57 +00009528
Victor Stinner1c2fa782020-05-10 11:05:29 +02009529 return _pystat_fromstructstat(module, &st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009530}
9531
Larry Hastings2f936352014-08-05 14:04:04 +10009532
9533/*[clinic input]
9534os.isatty -> bool
9535 fd: int
9536 /
9537
9538Return True if the fd is connected to a terminal.
9539
9540Return True if the file descriptor is an open file descriptor
9541connected to the slave end of a terminal.
9542[clinic start generated code]*/
9543
Larry Hastings2f936352014-08-05 14:04:04 +10009544static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009545os_isatty_impl(PyObject *module, int fd)
9546/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009547{
Steve Dower8fc89802015-04-12 00:26:27 -04009548 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009549 _Py_BEGIN_SUPPRESS_IPH
9550 return_value = isatty(fd);
9551 _Py_END_SUPPRESS_IPH
9552 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009553}
9554
9555
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009556#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009557/*[clinic input]
9558os.pipe
9559
9560Create a pipe.
9561
9562Returns a tuple of two file descriptors:
9563 (read_fd, write_fd)
9564[clinic start generated code]*/
9565
Larry Hastings2f936352014-08-05 14:04:04 +10009566static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009567os_pipe_impl(PyObject *module)
9568/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009569{
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009571#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009573 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009575#else
9576 int res;
9577#endif
9578
9579#ifdef MS_WINDOWS
9580 attr.nLength = sizeof(attr);
9581 attr.lpSecurityDescriptor = NULL;
9582 attr.bInheritHandle = FALSE;
9583
9584 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009585 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009586 ok = CreatePipe(&read, &write, &attr, 0);
9587 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009588 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9589 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009590 if (fds[0] == -1 || fds[1] == -1) {
9591 CloseHandle(read);
9592 CloseHandle(write);
9593 ok = 0;
9594 }
9595 }
Steve Dowerc3630612016-11-19 18:41:16 -08009596 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009597 Py_END_ALLOW_THREADS
9598
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009600 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009601#else
9602
9603#ifdef HAVE_PIPE2
9604 Py_BEGIN_ALLOW_THREADS
9605 res = pipe2(fds, O_CLOEXEC);
9606 Py_END_ALLOW_THREADS
9607
9608 if (res != 0 && errno == ENOSYS)
9609 {
9610#endif
9611 Py_BEGIN_ALLOW_THREADS
9612 res = pipe(fds);
9613 Py_END_ALLOW_THREADS
9614
9615 if (res == 0) {
9616 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9617 close(fds[0]);
9618 close(fds[1]);
9619 return NULL;
9620 }
9621 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9622 close(fds[0]);
9623 close(fds[1]);
9624 return NULL;
9625 }
9626 }
9627#ifdef HAVE_PIPE2
9628 }
9629#endif
9630
9631 if (res != 0)
9632 return PyErr_SetFromErrno(PyExc_OSError);
9633#endif /* !MS_WINDOWS */
9634 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009635}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009636#endif /* HAVE_PIPE */
9637
Larry Hastings2f936352014-08-05 14:04:04 +10009638
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009639#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009640/*[clinic input]
9641os.pipe2
9642
9643 flags: int
9644 /
9645
9646Create a pipe with flags set atomically.
9647
9648Returns a tuple of two file descriptors:
9649 (read_fd, write_fd)
9650
9651flags can be constructed by ORing together one or more of these values:
9652O_NONBLOCK, O_CLOEXEC.
9653[clinic start generated code]*/
9654
Larry Hastings2f936352014-08-05 14:04:04 +10009655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009656os_pipe2_impl(PyObject *module, int flags)
9657/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009658{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009659 int fds[2];
9660 int res;
9661
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009662 res = pipe2(fds, flags);
9663 if (res != 0)
9664 return posix_error();
9665 return Py_BuildValue("(ii)", fds[0], fds[1]);
9666}
9667#endif /* HAVE_PIPE2 */
9668
Larry Hastings2f936352014-08-05 14:04:04 +10009669
Ross Lagerwall7807c352011-03-17 20:20:30 +02009670#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009671/*[clinic input]
9672os.writev -> Py_ssize_t
9673 fd: int
9674 buffers: object
9675 /
9676
9677Iterate over buffers, and write the contents of each to a file descriptor.
9678
9679Returns the total number of bytes written.
9680buffers must be a sequence of bytes-like objects.
9681[clinic start generated code]*/
9682
Larry Hastings2f936352014-08-05 14:04:04 +10009683static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009684os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9685/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009686{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009687 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009688 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009689 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009690 struct iovec *iov;
9691 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009692
9693 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009694 PyErr_SetString(PyExc_TypeError,
9695 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009696 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009697 }
Larry Hastings2f936352014-08-05 14:04:04 +10009698 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009699 if (cnt < 0)
9700 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009701
Larry Hastings2f936352014-08-05 14:04:04 +10009702 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9703 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009704 }
9705
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009706 do {
9707 Py_BEGIN_ALLOW_THREADS
9708 result = writev(fd, iov, cnt);
9709 Py_END_ALLOW_THREADS
9710 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009711
9712 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009713 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009714 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009715
Georg Brandl306336b2012-06-24 12:55:33 +02009716 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009717}
Larry Hastings2f936352014-08-05 14:04:04 +10009718#endif /* HAVE_WRITEV */
9719
9720
9721#ifdef HAVE_PWRITE
9722/*[clinic input]
9723os.pwrite -> Py_ssize_t
9724
9725 fd: int
9726 buffer: Py_buffer
9727 offset: Py_off_t
9728 /
9729
9730Write bytes to a file descriptor starting at a particular offset.
9731
9732Write buffer to fd, starting at offset bytes from the beginning of
9733the file. Returns the number of bytes writte. Does not change the
9734current file offset.
9735[clinic start generated code]*/
9736
Larry Hastings2f936352014-08-05 14:04:04 +10009737static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009738os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9739/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009740{
9741 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009742 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009743
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009744 do {
9745 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009746 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009747 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009748 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009749 Py_END_ALLOW_THREADS
9750 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009751
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009752 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009753 posix_error();
9754 return size;
9755}
9756#endif /* HAVE_PWRITE */
9757
Pablo Galindo4defba32018-01-27 16:16:37 +00009758#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9759/*[clinic input]
9760os.pwritev -> Py_ssize_t
9761
9762 fd: int
9763 buffers: object
9764 offset: Py_off_t
9765 flags: int = 0
9766 /
9767
9768Writes the contents of bytes-like objects to a file descriptor at a given offset.
9769
9770Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9771of bytes-like objects. Buffers are processed in array order. Entire contents of first
9772buffer is written before proceeding to second, and so on. The operating system may
9773set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9774This function writes the contents of each object to the file descriptor and returns
9775the total number of bytes written.
9776
9777The flags argument contains a bitwise OR of zero or more of the following flags:
9778
9779- RWF_DSYNC
9780- RWF_SYNC
YoSTEALTH76ef2552020-05-27 15:32:22 -06009781- RWF_APPEND
Pablo Galindo4defba32018-01-27 16:16:37 +00009782
9783Using non-zero flags requires Linux 4.7 or newer.
9784[clinic start generated code]*/
9785
9786static Py_ssize_t
9787os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9788 int flags)
YoSTEALTH76ef2552020-05-27 15:32:22 -06009789/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=35358c327e1a2a8e]*/
Pablo Galindo4defba32018-01-27 16:16:37 +00009790{
9791 Py_ssize_t cnt;
9792 Py_ssize_t result;
9793 int async_err = 0;
9794 struct iovec *iov;
9795 Py_buffer *buf;
9796
9797 if (!PySequence_Check(buffers)) {
9798 PyErr_SetString(PyExc_TypeError,
9799 "pwritev() arg 2 must be a sequence");
9800 return -1;
9801 }
9802
9803 cnt = PySequence_Size(buffers);
9804 if (cnt < 0) {
9805 return -1;
9806 }
9807
9808#ifndef HAVE_PWRITEV2
9809 if(flags != 0) {
9810 argument_unavailable_error("pwritev2", "flags");
9811 return -1;
9812 }
9813#endif
9814
9815 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9816 return -1;
9817 }
9818#ifdef HAVE_PWRITEV2
9819 do {
9820 Py_BEGIN_ALLOW_THREADS
9821 _Py_BEGIN_SUPPRESS_IPH
9822 result = pwritev2(fd, iov, cnt, offset, flags);
9823 _Py_END_SUPPRESS_IPH
9824 Py_END_ALLOW_THREADS
9825 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9826#else
9827 do {
9828 Py_BEGIN_ALLOW_THREADS
9829 _Py_BEGIN_SUPPRESS_IPH
9830 result = pwritev(fd, iov, cnt, offset);
9831 _Py_END_SUPPRESS_IPH
9832 Py_END_ALLOW_THREADS
9833 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9834#endif
9835
9836 iov_cleanup(iov, buf, cnt);
9837 if (result < 0) {
9838 if (!async_err) {
9839 posix_error();
9840 }
9841 return -1;
9842 }
9843
9844 return result;
9845}
9846#endif /* HAVE_PWRITEV */
9847
Pablo Galindoaac4d032019-05-31 19:39:47 +01009848#ifdef HAVE_COPY_FILE_RANGE
9849/*[clinic input]
9850
9851os.copy_file_range
9852 src: int
9853 Source file descriptor.
9854 dst: int
9855 Destination file descriptor.
9856 count: Py_ssize_t
9857 Number of bytes to copy.
9858 offset_src: object = None
9859 Starting offset in src.
9860 offset_dst: object = None
9861 Starting offset in dst.
9862
9863Copy count bytes from one file descriptor to another.
9864
9865If offset_src is None, then src is read from the current position;
9866respectively for offset_dst.
9867[clinic start generated code]*/
9868
9869static PyObject *
9870os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
9871 PyObject *offset_src, PyObject *offset_dst)
9872/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
9873{
9874 off_t offset_src_val, offset_dst_val;
9875 off_t *p_offset_src = NULL;
9876 off_t *p_offset_dst = NULL;
9877 Py_ssize_t ret;
9878 int async_err = 0;
9879 /* The flags argument is provided to allow
9880 * for future extensions and currently must be to 0. */
9881 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +00009882
9883
Pablo Galindoaac4d032019-05-31 19:39:47 +01009884 if (count < 0) {
9885 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
9886 return NULL;
9887 }
9888
9889 if (offset_src != Py_None) {
9890 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
9891 return NULL;
9892 }
9893 p_offset_src = &offset_src_val;
9894 }
9895
9896 if (offset_dst != Py_None) {
9897 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
9898 return NULL;
9899 }
9900 p_offset_dst = &offset_dst_val;
9901 }
9902
9903 do {
9904 Py_BEGIN_ALLOW_THREADS
9905 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
9906 Py_END_ALLOW_THREADS
9907 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9908
9909 if (ret < 0) {
9910 return (!async_err) ? posix_error() : NULL;
9911 }
9912
9913 return PyLong_FromSsize_t(ret);
9914}
9915#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +10009916
9917#ifdef HAVE_MKFIFO
9918/*[clinic input]
9919os.mkfifo
9920
9921 path: path_t
9922 mode: int=0o666
9923 *
9924 dir_fd: dir_fd(requires='mkfifoat')=None
9925
9926Create a "fifo" (a POSIX named pipe).
9927
9928If dir_fd is not None, it should be a file descriptor open to a directory,
9929 and path should be relative; path will then be relative to that directory.
9930dir_fd may not be implemented on your platform.
9931 If it is unavailable, using it will raise a NotImplementedError.
9932[clinic start generated code]*/
9933
Larry Hastings2f936352014-08-05 14:04:04 +10009934static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009935os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9936/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009937{
9938 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009939 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009940
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009941 do {
9942 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009943#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009944 if (dir_fd != DEFAULT_DIR_FD)
9945 result = mkfifoat(dir_fd, path->narrow, mode);
9946 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009947#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009948 result = mkfifo(path->narrow, mode);
9949 Py_END_ALLOW_THREADS
9950 } while (result != 0 && errno == EINTR &&
9951 !(async_err = PyErr_CheckSignals()));
9952 if (result != 0)
9953 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009954
9955 Py_RETURN_NONE;
9956}
9957#endif /* HAVE_MKFIFO */
9958
9959
9960#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9961/*[clinic input]
9962os.mknod
9963
9964 path: path_t
9965 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009966 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009967 *
9968 dir_fd: dir_fd(requires='mknodat')=None
9969
9970Create a node in the file system.
9971
9972Create a node in the file system (file, device special file or named pipe)
9973at path. mode specifies both the permissions to use and the
9974type of node to be created, being combined (bitwise OR) with one of
9975S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9976device defines the newly created device special file (probably using
9977os.makedev()). Otherwise device is ignored.
9978
9979If dir_fd is not None, it should be a file descriptor open to a directory,
9980 and path should be relative; path will then be relative to that directory.
9981dir_fd may not be implemented on your platform.
9982 If it is unavailable, using it will raise a NotImplementedError.
9983[clinic start generated code]*/
9984
Larry Hastings2f936352014-08-05 14:04:04 +10009985static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009986os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009987 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009988/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009989{
9990 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009991 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009992
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009993 do {
9994 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009995#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009996 if (dir_fd != DEFAULT_DIR_FD)
9997 result = mknodat(dir_fd, path->narrow, mode, device);
9998 else
Larry Hastings2f936352014-08-05 14:04:04 +10009999#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010000 result = mknod(path->narrow, mode, device);
10001 Py_END_ALLOW_THREADS
10002 } while (result != 0 && errno == EINTR &&
10003 !(async_err = PyErr_CheckSignals()));
10004 if (result != 0)
10005 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010006
10007 Py_RETURN_NONE;
10008}
10009#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10010
10011
10012#ifdef HAVE_DEVICE_MACROS
10013/*[clinic input]
10014os.major -> unsigned_int
10015
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010016 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010017 /
10018
10019Extracts a device major number from a raw device number.
10020[clinic start generated code]*/
10021
Larry Hastings2f936352014-08-05 14:04:04 +100010022static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010023os_major_impl(PyObject *module, dev_t device)
10024/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010025{
10026 return major(device);
10027}
10028
10029
10030/*[clinic input]
10031os.minor -> unsigned_int
10032
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010033 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010034 /
10035
10036Extracts a device minor number from a raw device number.
10037[clinic start generated code]*/
10038
Larry Hastings2f936352014-08-05 14:04:04 +100010039static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010040os_minor_impl(PyObject *module, dev_t device)
10041/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010042{
10043 return minor(device);
10044}
10045
10046
10047/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010048os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010049
10050 major: int
10051 minor: int
10052 /
10053
10054Composes a raw device number from the major and minor device numbers.
10055[clinic start generated code]*/
10056
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010057static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010058os_makedev_impl(PyObject *module, int major, int minor)
10059/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010060{
10061 return makedev(major, minor);
10062}
10063#endif /* HAVE_DEVICE_MACROS */
10064
10065
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010066#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010067/*[clinic input]
10068os.ftruncate
10069
10070 fd: int
10071 length: Py_off_t
10072 /
10073
10074Truncate a file, specified by file descriptor, to a specific length.
10075[clinic start generated code]*/
10076
Larry Hastings2f936352014-08-05 14:04:04 +100010077static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010078os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10079/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010080{
10081 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010082 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010083
Steve Dowerb82e17e2019-05-23 08:45:22 -070010084 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
10085 return NULL;
10086 }
10087
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010088 do {
10089 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010090 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010091#ifdef MS_WINDOWS
10092 result = _chsize_s(fd, length);
10093#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010094 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010095#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010096 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010097 Py_END_ALLOW_THREADS
10098 } while (result != 0 && errno == EINTR &&
10099 !(async_err = PyErr_CheckSignals()));
10100 if (result != 0)
10101 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010102 Py_RETURN_NONE;
10103}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010104#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010105
10106
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010107#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010108/*[clinic input]
10109os.truncate
10110 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10111 length: Py_off_t
10112
10113Truncate a file, specified by path, to a specific length.
10114
10115On some platforms, path may also be specified as an open file descriptor.
10116 If this functionality is unavailable, using it raises an exception.
10117[clinic start generated code]*/
10118
Larry Hastings2f936352014-08-05 14:04:04 +100010119static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010120os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10121/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010122{
10123 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010124#ifdef MS_WINDOWS
10125 int fd;
10126#endif
10127
10128 if (path->fd != -1)
10129 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010130
Steve Dowerb82e17e2019-05-23 08:45:22 -070010131 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10132 return NULL;
10133 }
10134
Larry Hastings2f936352014-08-05 14:04:04 +100010135 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010136 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010137#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010138 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010139 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010140 result = -1;
10141 else {
10142 result = _chsize_s(fd, length);
10143 close(fd);
10144 if (result < 0)
10145 errno = result;
10146 }
10147#else
10148 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010149#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010150 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010151 Py_END_ALLOW_THREADS
10152 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010153 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010154
10155 Py_RETURN_NONE;
10156}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010157#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010158
Ross Lagerwall7807c352011-03-17 20:20:30 +020010159
Victor Stinnerd6b17692014-09-30 12:20:05 +020010160/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10161 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10162 defined, which is the case in Python on AIX. AIX bug report:
10163 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10164#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10165# define POSIX_FADVISE_AIX_BUG
10166#endif
10167
Victor Stinnerec39e262014-09-30 12:35:58 +020010168
Victor Stinnerd6b17692014-09-30 12:20:05 +020010169#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010170/*[clinic input]
10171os.posix_fallocate
10172
10173 fd: int
10174 offset: Py_off_t
10175 length: Py_off_t
10176 /
10177
10178Ensure a file has allocated at least a particular number of bytes on disk.
10179
10180Ensure that the file specified by fd encompasses a range of bytes
10181starting at offset bytes from the beginning and continuing for length bytes.
10182[clinic start generated code]*/
10183
Larry Hastings2f936352014-08-05 14:04:04 +100010184static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010185os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010186 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010187/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010188{
10189 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010190 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010191
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010192 do {
10193 Py_BEGIN_ALLOW_THREADS
10194 result = posix_fallocate(fd, offset, length);
10195 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010196 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10197
10198 if (result == 0)
10199 Py_RETURN_NONE;
10200
10201 if (async_err)
10202 return NULL;
10203
10204 errno = result;
10205 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010206}
Victor Stinnerec39e262014-09-30 12:35:58 +020010207#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010208
Ross Lagerwall7807c352011-03-17 20:20:30 +020010209
Victor Stinnerd6b17692014-09-30 12:20:05 +020010210#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010211/*[clinic input]
10212os.posix_fadvise
10213
10214 fd: int
10215 offset: Py_off_t
10216 length: Py_off_t
10217 advice: int
10218 /
10219
10220Announce an intention to access data in a specific pattern.
10221
10222Announce an intention to access data in a specific pattern, thus allowing
10223the kernel to make optimizations.
10224The advice applies to the region of the file specified by fd starting at
10225offset and continuing for length bytes.
10226advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10227POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10228POSIX_FADV_DONTNEED.
10229[clinic start generated code]*/
10230
Larry Hastings2f936352014-08-05 14:04:04 +100010231static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010232os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010233 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010234/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010235{
10236 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010237 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010238
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010239 do {
10240 Py_BEGIN_ALLOW_THREADS
10241 result = posix_fadvise(fd, offset, length, advice);
10242 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010243 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10244
10245 if (result == 0)
10246 Py_RETURN_NONE;
10247
10248 if (async_err)
10249 return NULL;
10250
10251 errno = result;
10252 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010253}
Victor Stinnerec39e262014-09-30 12:35:58 +020010254#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010255
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010256
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010257#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010258static PyObject*
10259win32_putenv(PyObject *name, PyObject *value)
10260{
10261 /* Search from index 1 because on Windows starting '=' is allowed for
10262 defining hidden environment variables. */
10263 if (PyUnicode_GET_LENGTH(name) == 0 ||
10264 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10265 {
10266 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10267 return NULL;
10268 }
10269 PyObject *unicode;
10270 if (value != NULL) {
10271 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10272 }
10273 else {
10274 unicode = PyUnicode_FromFormat("%U=", name);
10275 }
10276 if (unicode == NULL) {
10277 return NULL;
10278 }
10279
10280 Py_ssize_t size;
10281 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10282 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10283 Py_DECREF(unicode);
10284
10285 if (env == NULL) {
10286 return NULL;
10287 }
10288 if (size > _MAX_ENV) {
10289 PyErr_Format(PyExc_ValueError,
10290 "the environment variable is longer than %u characters",
10291 _MAX_ENV);
10292 PyMem_Free(env);
10293 return NULL;
10294 }
10295
10296 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10297 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10298 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10299
10300 Prefer _wputenv() to be compatible with C libraries using CRT
10301 variables and CRT functions using these variables (ex: getenv()). */
10302 int err = _wputenv(env);
10303 PyMem_Free(env);
10304
10305 if (err) {
10306 posix_error();
10307 return NULL;
10308 }
10309
10310 Py_RETURN_NONE;
10311}
10312#endif
10313
10314
10315#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010316/*[clinic input]
10317os.putenv
10318
10319 name: unicode
10320 value: unicode
10321 /
10322
10323Change or add an environment variable.
10324[clinic start generated code]*/
10325
Larry Hastings2f936352014-08-05 14:04:04 +100010326static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010327os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10328/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010329{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010330 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10331 return NULL;
10332 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010333 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010334}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010335#else
Larry Hastings2f936352014-08-05 14:04:04 +100010336/*[clinic input]
10337os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010338
Larry Hastings2f936352014-08-05 14:04:04 +100010339 name: FSConverter
10340 value: FSConverter
10341 /
10342
10343Change or add an environment variable.
10344[clinic start generated code]*/
10345
Larry Hastings2f936352014-08-05 14:04:04 +100010346static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010347os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10348/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010349{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010350 const char *name_string = PyBytes_AS_STRING(name);
10351 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010352
Serhiy Storchaka77703942017-06-25 07:33:01 +030010353 if (strchr(name_string, '=') != NULL) {
10354 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10355 return NULL;
10356 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010357
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010358 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10359 return NULL;
10360 }
10361
Victor Stinnerb477d192020-01-22 22:48:16 +010010362 if (setenv(name_string, value_string, 1)) {
10363 return posix_error();
10364 }
Larry Hastings2f936352014-08-05 14:04:04 +100010365 Py_RETURN_NONE;
10366}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010367#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010368
10369
Victor Stinner161e7b32020-01-24 11:53:44 +010010370#ifdef MS_WINDOWS
10371/*[clinic input]
10372os.unsetenv
10373 name: unicode
10374 /
10375
10376Delete an environment variable.
10377[clinic start generated code]*/
10378
10379static PyObject *
10380os_unsetenv_impl(PyObject *module, PyObject *name)
10381/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10382{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010383 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10384 return NULL;
10385 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010386 return win32_putenv(name, NULL);
10387}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010388#else
Larry Hastings2f936352014-08-05 14:04:04 +100010389/*[clinic input]
10390os.unsetenv
10391 name: FSConverter
10392 /
10393
10394Delete an environment variable.
10395[clinic start generated code]*/
10396
Larry Hastings2f936352014-08-05 14:04:04 +100010397static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010398os_unsetenv_impl(PyObject *module, PyObject *name)
10399/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010400{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010401 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10402 return NULL;
10403 }
Victor Stinner984890f2011-11-24 13:53:38 +010010404#ifdef HAVE_BROKEN_UNSETENV
10405 unsetenv(PyBytes_AS_STRING(name));
10406#else
Victor Stinner161e7b32020-01-24 11:53:44 +010010407 int err = unsetenv(PyBytes_AS_STRING(name));
10408 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010010409 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010010410 }
Victor Stinner984890f2011-11-24 13:53:38 +010010411#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010412
Victor Stinner84ae1182010-05-06 22:05:07 +000010413 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010414}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010415#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000010416
Larry Hastings2f936352014-08-05 14:04:04 +100010417
10418/*[clinic input]
10419os.strerror
10420
10421 code: int
10422 /
10423
10424Translate an error code to a message string.
10425[clinic start generated code]*/
10426
Larry Hastings2f936352014-08-05 14:04:04 +100010427static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010428os_strerror_impl(PyObject *module, int code)
10429/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010430{
10431 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010432 if (message == NULL) {
10433 PyErr_SetString(PyExc_ValueError,
10434 "strerror() argument out of range");
10435 return NULL;
10436 }
Victor Stinner1b579672011-12-17 05:47:23 +010010437 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010438}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010439
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010440
Guido van Rossumc9641791998-08-04 15:26:23 +000010441#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010442#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010443/*[clinic input]
10444os.WCOREDUMP -> bool
10445
10446 status: int
10447 /
10448
10449Return True if the process returning status was dumped to a core file.
10450[clinic start generated code]*/
10451
Larry Hastings2f936352014-08-05 14:04:04 +100010452static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010453os_WCOREDUMP_impl(PyObject *module, int status)
10454/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010455{
10456 WAIT_TYPE wait_status;
10457 WAIT_STATUS_INT(wait_status) = status;
10458 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010459}
10460#endif /* WCOREDUMP */
10461
Larry Hastings2f936352014-08-05 14:04:04 +100010462
Fred Drake106c1a02002-04-23 15:58:02 +000010463#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010464/*[clinic input]
10465os.WIFCONTINUED -> bool
10466
10467 status: int
10468
10469Return True if a particular process was continued from a job control stop.
10470
10471Return True if the process returning status was continued from a
10472job control stop.
10473[clinic start generated code]*/
10474
Larry Hastings2f936352014-08-05 14:04:04 +100010475static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010476os_WIFCONTINUED_impl(PyObject *module, int status)
10477/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010478{
10479 WAIT_TYPE wait_status;
10480 WAIT_STATUS_INT(wait_status) = status;
10481 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010482}
10483#endif /* WIFCONTINUED */
10484
Larry Hastings2f936352014-08-05 14:04:04 +100010485
Guido van Rossumc9641791998-08-04 15:26:23 +000010486#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010487/*[clinic input]
10488os.WIFSTOPPED -> bool
10489
10490 status: int
10491
10492Return True if the process returning status was stopped.
10493[clinic start generated code]*/
10494
Larry Hastings2f936352014-08-05 14:04:04 +100010495static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010496os_WIFSTOPPED_impl(PyObject *module, int status)
10497/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010498{
10499 WAIT_TYPE wait_status;
10500 WAIT_STATUS_INT(wait_status) = status;
10501 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010502}
10503#endif /* WIFSTOPPED */
10504
Larry Hastings2f936352014-08-05 14:04:04 +100010505
Guido van Rossumc9641791998-08-04 15:26:23 +000010506#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010507/*[clinic input]
10508os.WIFSIGNALED -> bool
10509
10510 status: int
10511
10512Return True if the process returning status was terminated by a signal.
10513[clinic start generated code]*/
10514
Larry Hastings2f936352014-08-05 14:04:04 +100010515static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010516os_WIFSIGNALED_impl(PyObject *module, int status)
10517/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010518{
10519 WAIT_TYPE wait_status;
10520 WAIT_STATUS_INT(wait_status) = status;
10521 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010522}
10523#endif /* WIFSIGNALED */
10524
Larry Hastings2f936352014-08-05 14:04:04 +100010525
Guido van Rossumc9641791998-08-04 15:26:23 +000010526#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010527/*[clinic input]
10528os.WIFEXITED -> bool
10529
10530 status: int
10531
10532Return True if the process returning status exited via the exit() system call.
10533[clinic start generated code]*/
10534
Larry Hastings2f936352014-08-05 14:04:04 +100010535static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010536os_WIFEXITED_impl(PyObject *module, int status)
10537/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010538{
10539 WAIT_TYPE wait_status;
10540 WAIT_STATUS_INT(wait_status) = status;
10541 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010542}
10543#endif /* WIFEXITED */
10544
Larry Hastings2f936352014-08-05 14:04:04 +100010545
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010546#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010547/*[clinic input]
10548os.WEXITSTATUS -> int
10549
10550 status: int
10551
10552Return the process return code from status.
10553[clinic start generated code]*/
10554
Larry Hastings2f936352014-08-05 14:04:04 +100010555static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010556os_WEXITSTATUS_impl(PyObject *module, int status)
10557/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010558{
10559 WAIT_TYPE wait_status;
10560 WAIT_STATUS_INT(wait_status) = status;
10561 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010562}
10563#endif /* WEXITSTATUS */
10564
Larry Hastings2f936352014-08-05 14:04:04 +100010565
Guido van Rossumc9641791998-08-04 15:26:23 +000010566#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010567/*[clinic input]
10568os.WTERMSIG -> int
10569
10570 status: int
10571
10572Return the signal that terminated the process that provided the status value.
10573[clinic start generated code]*/
10574
Larry Hastings2f936352014-08-05 14:04:04 +100010575static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010576os_WTERMSIG_impl(PyObject *module, int status)
10577/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010578{
10579 WAIT_TYPE wait_status;
10580 WAIT_STATUS_INT(wait_status) = status;
10581 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010582}
10583#endif /* WTERMSIG */
10584
Larry Hastings2f936352014-08-05 14:04:04 +100010585
Guido van Rossumc9641791998-08-04 15:26:23 +000010586#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010587/*[clinic input]
10588os.WSTOPSIG -> int
10589
10590 status: int
10591
10592Return the signal that stopped the process that provided the status value.
10593[clinic start generated code]*/
10594
Larry Hastings2f936352014-08-05 14:04:04 +100010595static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010596os_WSTOPSIG_impl(PyObject *module, int status)
10597/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010598{
10599 WAIT_TYPE wait_status;
10600 WAIT_STATUS_INT(wait_status) = status;
10601 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010602}
10603#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010604#endif /* HAVE_SYS_WAIT_H */
10605
10606
Thomas Wouters477c8d52006-05-27 19:21:47 +000010607#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010608#ifdef _SCO_DS
10609/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10610 needed definitions in sys/statvfs.h */
10611#define _SVID3
10612#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010613#include <sys/statvfs.h>
10614
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010615static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +020010616_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
10617 PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080010618 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010619 if (v == NULL)
10620 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010621
10622#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010623 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10624 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10625 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10626 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10627 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10628 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10629 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10630 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10631 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10632 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010633#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010634 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10635 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10636 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010637 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010638 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010639 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010640 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010641 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010642 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010643 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010644 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010645 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010647 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10649 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010650#endif
Michael Felt502d5512018-01-05 13:01:58 +010010651/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10652 * (issue #32390). */
10653#if defined(_AIX) && defined(_ALL_SOURCE)
10654 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10655#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010656 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010657#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010658 if (PyErr_Occurred()) {
10659 Py_DECREF(v);
10660 return NULL;
10661 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010662
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010664}
10665
Larry Hastings2f936352014-08-05 14:04:04 +100010666
10667/*[clinic input]
10668os.fstatvfs
10669 fd: int
10670 /
10671
10672Perform an fstatvfs system call on the given fd.
10673
10674Equivalent to statvfs(fd).
10675[clinic start generated code]*/
10676
Larry Hastings2f936352014-08-05 14:04:04 +100010677static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010678os_fstatvfs_impl(PyObject *module, int fd)
10679/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010680{
10681 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010682 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010683 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010684
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010685 do {
10686 Py_BEGIN_ALLOW_THREADS
10687 result = fstatvfs(fd, &st);
10688 Py_END_ALLOW_THREADS
10689 } while (result != 0 && errno == EINTR &&
10690 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010691 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010692 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010693
Victor Stinner1c2fa782020-05-10 11:05:29 +020010694 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010695}
Larry Hastings2f936352014-08-05 14:04:04 +100010696#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010697
10698
Thomas Wouters477c8d52006-05-27 19:21:47 +000010699#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010700#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010701/*[clinic input]
10702os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010703
Larry Hastings2f936352014-08-05 14:04:04 +100010704 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10705
10706Perform a statvfs system call on the given path.
10707
10708path may always be specified as a string.
10709On some platforms, path may also be specified as an open file descriptor.
10710 If this functionality is unavailable, using it raises an exception.
10711[clinic start generated code]*/
10712
Larry Hastings2f936352014-08-05 14:04:04 +100010713static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010714os_statvfs_impl(PyObject *module, path_t *path)
10715/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010716{
10717 int result;
10718 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010719
10720 Py_BEGIN_ALLOW_THREADS
10721#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010722 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010723#ifdef __APPLE__
10724 /* handle weak-linking on Mac OS X 10.3 */
10725 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010726 fd_specified("statvfs", path->fd);
10727 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010728 }
10729#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010730 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010731 }
10732 else
10733#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010734 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010735 Py_END_ALLOW_THREADS
10736
10737 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010738 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010739 }
10740
Victor Stinner1c2fa782020-05-10 11:05:29 +020010741 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010742}
Larry Hastings2f936352014-08-05 14:04:04 +100010743#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10744
Guido van Rossum94f6f721999-01-06 18:42:14 +000010745
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010746#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010747/*[clinic input]
10748os._getdiskusage
10749
Steve Dower23ad6d02018-02-22 10:39:10 -080010750 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010751
10752Return disk usage statistics about the given path as a (total, free) tuple.
10753[clinic start generated code]*/
10754
Larry Hastings2f936352014-08-05 14:04:04 +100010755static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010756os__getdiskusage_impl(PyObject *module, path_t *path)
10757/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010758{
10759 BOOL retval;
10760 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010761 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010762
10763 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010764 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010765 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010766 if (retval == 0) {
10767 if (GetLastError() == ERROR_DIRECTORY) {
10768 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010769
Joe Pamerc8c02492018-09-25 10:57:36 -040010770 dir_path = PyMem_New(wchar_t, path->length + 1);
10771 if (dir_path == NULL) {
10772 return PyErr_NoMemory();
10773 }
10774
10775 wcscpy_s(dir_path, path->length + 1, path->wide);
10776
10777 if (_dirnameW(dir_path) != -1) {
10778 Py_BEGIN_ALLOW_THREADS
10779 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10780 Py_END_ALLOW_THREADS
10781 }
10782 /* Record the last error in case it's modified by PyMem_Free. */
10783 err = GetLastError();
10784 PyMem_Free(dir_path);
10785 if (retval) {
10786 goto success;
10787 }
10788 }
10789 return PyErr_SetFromWindowsErr(err);
10790 }
10791
10792success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010793 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10794}
Larry Hastings2f936352014-08-05 14:04:04 +100010795#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010796
10797
Fred Drakec9680921999-12-13 16:37:25 +000010798/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10799 * It maps strings representing configuration variable names to
10800 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010801 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010802 * rarely-used constants. There are three separate tables that use
10803 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010804 *
10805 * This code is always included, even if none of the interfaces that
10806 * need it are included. The #if hackery needed to avoid it would be
10807 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010808 */
10809struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010810 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010811 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010812};
10813
Fred Drake12c6e2d1999-12-14 21:25:03 +000010814static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010815conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010816 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010817{
Christian Heimes217cfd12007-12-02 14:31:20 +000010818 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010819 int value = _PyLong_AsInt(arg);
10820 if (value == -1 && PyErr_Occurred())
10821 return 0;
10822 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010823 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010824 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010825 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010826 /* look up the value in the table using a binary search */
10827 size_t lo = 0;
10828 size_t mid;
10829 size_t hi = tablesize;
10830 int cmp;
10831 const char *confname;
10832 if (!PyUnicode_Check(arg)) {
10833 PyErr_SetString(PyExc_TypeError,
10834 "configuration names must be strings or integers");
10835 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010836 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010837 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010838 if (confname == NULL)
10839 return 0;
10840 while (lo < hi) {
10841 mid = (lo + hi) / 2;
10842 cmp = strcmp(confname, table[mid].name);
10843 if (cmp < 0)
10844 hi = mid;
10845 else if (cmp > 0)
10846 lo = mid + 1;
10847 else {
10848 *valuep = table[mid].value;
10849 return 1;
10850 }
10851 }
10852 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10853 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010855}
10856
10857
10858#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10859static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010860#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010862#endif
10863#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010864 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010865#endif
Fred Drakec9680921999-12-13 16:37:25 +000010866#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010867 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010868#endif
10869#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010871#endif
10872#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010874#endif
10875#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010877#endif
10878#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010880#endif
10881#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010883#endif
10884#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010886#endif
10887#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010889#endif
10890#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010892#endif
10893#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010895#endif
10896#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010898#endif
10899#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010901#endif
10902#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010904#endif
10905#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010907#endif
10908#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010910#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010911#ifdef _PC_ACL_ENABLED
10912 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10913#endif
10914#ifdef _PC_MIN_HOLE_SIZE
10915 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10916#endif
10917#ifdef _PC_ALLOC_SIZE_MIN
10918 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10919#endif
10920#ifdef _PC_REC_INCR_XFER_SIZE
10921 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10922#endif
10923#ifdef _PC_REC_MAX_XFER_SIZE
10924 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10925#endif
10926#ifdef _PC_REC_MIN_XFER_SIZE
10927 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10928#endif
10929#ifdef _PC_REC_XFER_ALIGN
10930 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10931#endif
10932#ifdef _PC_SYMLINK_MAX
10933 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10934#endif
10935#ifdef _PC_XATTR_ENABLED
10936 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10937#endif
10938#ifdef _PC_XATTR_EXISTS
10939 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10940#endif
10941#ifdef _PC_TIMESTAMP_RESOLUTION
10942 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10943#endif
Fred Drakec9680921999-12-13 16:37:25 +000010944};
10945
Fred Drakec9680921999-12-13 16:37:25 +000010946static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010947conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010948{
10949 return conv_confname(arg, valuep, posix_constants_pathconf,
10950 sizeof(posix_constants_pathconf)
10951 / sizeof(struct constdef));
10952}
10953#endif
10954
Larry Hastings2f936352014-08-05 14:04:04 +100010955
Fred Drakec9680921999-12-13 16:37:25 +000010956#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010957/*[clinic input]
10958os.fpathconf -> long
10959
10960 fd: int
10961 name: path_confname
10962 /
10963
10964Return the configuration limit name for the file descriptor fd.
10965
10966If there is no limit, return -1.
10967[clinic start generated code]*/
10968
Larry Hastings2f936352014-08-05 14:04:04 +100010969static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010970os_fpathconf_impl(PyObject *module, int fd, int name)
10971/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010972{
10973 long limit;
10974
10975 errno = 0;
10976 limit = fpathconf(fd, name);
10977 if (limit == -1 && errno != 0)
10978 posix_error();
10979
10980 return limit;
10981}
10982#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010983
10984
10985#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010986/*[clinic input]
10987os.pathconf -> long
10988 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10989 name: path_confname
10990
10991Return the configuration limit name for the file or directory path.
10992
10993If there is no limit, return -1.
10994On some platforms, path may also be specified as an open file descriptor.
10995 If this functionality is unavailable, using it raises an exception.
10996[clinic start generated code]*/
10997
Larry Hastings2f936352014-08-05 14:04:04 +100010998static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010999os_pathconf_impl(PyObject *module, path_t *path, int name)
11000/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011001{
Victor Stinner8c62be82010-05-06 00:08:46 +000011002 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000011003
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020011005#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011006 if (path->fd != -1)
11007 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020011008 else
11009#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011010 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000011011 if (limit == -1 && errno != 0) {
11012 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000011013 /* could be a path or name problem */
11014 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000011015 else
Larry Hastings2f936352014-08-05 14:04:04 +100011016 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000011017 }
Larry Hastings2f936352014-08-05 14:04:04 +100011018
11019 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000011020}
Larry Hastings2f936352014-08-05 14:04:04 +100011021#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011022
11023#ifdef HAVE_CONFSTR
11024static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011025#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000011027#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000011028#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011030#endif
11031#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011033#endif
Fred Draked86ed291999-12-15 15:34:33 +000011034#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011036#endif
11037#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011038 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011039#endif
11040#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011041 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011042#endif
11043#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011045#endif
Fred Drakec9680921999-12-13 16:37:25 +000011046#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011048#endif
11049#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011051#endif
11052#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011053 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011054#endif
11055#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011057#endif
11058#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011060#endif
11061#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011062 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011063#endif
11064#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011066#endif
11067#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011069#endif
Fred Draked86ed291999-12-15 15:34:33 +000011070#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000011072#endif
Fred Drakec9680921999-12-13 16:37:25 +000011073#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000011075#endif
Fred Draked86ed291999-12-15 15:34:33 +000011076#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000011078#endif
11079#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000011081#endif
11082#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011084#endif
11085#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000011087#endif
Fred Drakec9680921999-12-13 16:37:25 +000011088#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011090#endif
11091#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011093#endif
11094#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011096#endif
11097#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011099#endif
11100#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011102#endif
11103#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011105#endif
11106#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011108#endif
11109#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011111#endif
11112#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011114#endif
11115#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011117#endif
11118#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011120#endif
11121#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011123#endif
11124#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011126#endif
11127#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011129#endif
11130#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011132#endif
11133#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011134 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011135#endif
Fred Draked86ed291999-12-15 15:34:33 +000011136#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011138#endif
11139#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011140 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011141#endif
11142#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011144#endif
11145#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011146 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011147#endif
11148#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011150#endif
11151#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011153#endif
11154#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011156#endif
11157#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011158 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011159#endif
11160#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011161 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011162#endif
11163#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011165#endif
11166#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011168#endif
11169#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011171#endif
11172#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011174#endif
Fred Drakec9680921999-12-13 16:37:25 +000011175};
11176
11177static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011178conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011179{
11180 return conv_confname(arg, valuep, posix_constants_confstr,
11181 sizeof(posix_constants_confstr)
11182 / sizeof(struct constdef));
11183}
11184
Larry Hastings2f936352014-08-05 14:04:04 +100011185
11186/*[clinic input]
11187os.confstr
11188
11189 name: confstr_confname
11190 /
11191
11192Return a string-valued system configuration variable.
11193[clinic start generated code]*/
11194
Larry Hastings2f936352014-08-05 14:04:04 +100011195static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011196os_confstr_impl(PyObject *module, int name)
11197/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011198{
11199 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011200 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011201 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011202
Victor Stinnercb043522010-09-10 23:49:04 +000011203 errno = 0;
11204 len = confstr(name, buffer, sizeof(buffer));
11205 if (len == 0) {
11206 if (errno) {
11207 posix_error();
11208 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011209 }
11210 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011211 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011212 }
11213 }
Victor Stinnercb043522010-09-10 23:49:04 +000011214
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011215 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011216 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011217 char *buf = PyMem_Malloc(len);
11218 if (buf == NULL)
11219 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011220 len2 = confstr(name, buf, len);
11221 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011222 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011223 PyMem_Free(buf);
11224 }
11225 else
11226 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011227 return result;
11228}
Larry Hastings2f936352014-08-05 14:04:04 +100011229#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011230
11231
11232#ifdef HAVE_SYSCONF
11233static struct constdef posix_constants_sysconf[] = {
11234#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011235 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011236#endif
11237#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011239#endif
11240#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011242#endif
11243#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011245#endif
11246#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011248#endif
11249#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011250 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011251#endif
11252#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011254#endif
11255#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011257#endif
11258#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011260#endif
11261#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011263#endif
Fred Draked86ed291999-12-15 15:34:33 +000011264#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011266#endif
11267#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011268 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011269#endif
Fred Drakec9680921999-12-13 16:37:25 +000011270#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011272#endif
Fred Drakec9680921999-12-13 16:37:25 +000011273#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011274 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011275#endif
11276#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011278#endif
11279#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011281#endif
11282#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011284#endif
11285#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011287#endif
Fred Draked86ed291999-12-15 15:34:33 +000011288#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011290#endif
Fred Drakec9680921999-12-13 16:37:25 +000011291#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011293#endif
11294#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011295 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011296#endif
11297#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011299#endif
11300#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011302#endif
11303#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011305#endif
Fred Draked86ed291999-12-15 15:34:33 +000011306#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011308#endif
Fred Drakec9680921999-12-13 16:37:25 +000011309#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011311#endif
11312#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011314#endif
11315#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011317#endif
11318#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011320#endif
11321#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011323#endif
11324#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011326#endif
11327#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011328 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011329#endif
11330#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011331 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011332#endif
11333#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011334 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011335#endif
11336#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011338#endif
11339#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011340 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011341#endif
11342#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011343 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011344#endif
11345#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011346 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011347#endif
11348#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011349 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011350#endif
11351#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011352 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011353#endif
11354#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011355 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011356#endif
11357#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011358 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011359#endif
11360#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011361 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011362#endif
11363#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011364 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011365#endif
11366#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011367 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011368#endif
11369#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011370 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011371#endif
11372#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011373 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011374#endif
11375#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011377#endif
Fred Draked86ed291999-12-15 15:34:33 +000011378#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011379 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011380#endif
Fred Drakec9680921999-12-13 16:37:25 +000011381#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011382 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011383#endif
11384#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011386#endif
11387#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011388 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011389#endif
Fred Draked86ed291999-12-15 15:34:33 +000011390#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011392#endif
Fred Drakec9680921999-12-13 16:37:25 +000011393#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011395#endif
Fred Draked86ed291999-12-15 15:34:33 +000011396#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011397 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011398#endif
11399#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011400 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011401#endif
Fred Drakec9680921999-12-13 16:37:25 +000011402#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011403 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011404#endif
11405#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011406 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011407#endif
11408#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011409 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011410#endif
11411#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011412 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011413#endif
Fred Draked86ed291999-12-15 15:34:33 +000011414#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011415 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011416#endif
Fred Drakec9680921999-12-13 16:37:25 +000011417#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011418 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011419#endif
11420#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011421 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011422#endif
11423#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011424 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011425#endif
11426#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011428#endif
11429#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011430 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011431#endif
11432#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011433 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011434#endif
11435#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011436 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011437#endif
Fred Draked86ed291999-12-15 15:34:33 +000011438#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011439 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011440#endif
Fred Drakec9680921999-12-13 16:37:25 +000011441#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011442 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011443#endif
11444#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011445 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011446#endif
Fred Draked86ed291999-12-15 15:34:33 +000011447#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011448 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011449#endif
Fred Drakec9680921999-12-13 16:37:25 +000011450#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011451 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011452#endif
11453#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011455#endif
11456#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011457 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011458#endif
11459#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011460 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011461#endif
11462#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011464#endif
11465#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011466 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011467#endif
11468#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011469 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011470#endif
11471#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011472 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011473#endif
11474#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011475 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011476#endif
Fred Draked86ed291999-12-15 15:34:33 +000011477#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011478 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011479#endif
11480#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011481 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011482#endif
Fred Drakec9680921999-12-13 16:37:25 +000011483#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011484 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011485#endif
11486#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011487 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011488#endif
11489#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011490 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011491#endif
11492#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011493 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011494#endif
Batuhan Taşkaya909f4a32020-04-05 03:40:49 +030011495#ifdef _SC_AIX_REALMEM
11496 {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
11497#endif
Fred Drakec9680921999-12-13 16:37:25 +000011498#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011499 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011500#endif
11501#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011502 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011503#endif
11504#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011505 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011506#endif
11507#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011508 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011509#endif
11510#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011511 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011512#endif
11513#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011514 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011515#endif
11516#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011517 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011518#endif
11519#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011520 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011521#endif
11522#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011523 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011524#endif
11525#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011527#endif
11528#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011529 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011530#endif
11531#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011532 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011533#endif
11534#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011535 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011536#endif
11537#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011538 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011539#endif
11540#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011541 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011542#endif
11543#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011544 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011545#endif
11546#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011547 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011548#endif
11549#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011550 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011551#endif
11552#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011553 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011554#endif
11555#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011556 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011557#endif
11558#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011559 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011560#endif
11561#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011562 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011563#endif
11564#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011565 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011566#endif
11567#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011568 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011569#endif
11570#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011571 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011572#endif
11573#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011574 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011575#endif
11576#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011577 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011578#endif
11579#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011580 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011581#endif
11582#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011583 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011584#endif
11585#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011586 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011587#endif
11588#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011589 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011590#endif
Fred Draked86ed291999-12-15 15:34:33 +000011591#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011592 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011593#endif
Fred Drakec9680921999-12-13 16:37:25 +000011594#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011595 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011596#endif
11597#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011598 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011599#endif
11600#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011601 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011602#endif
11603#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011604 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011605#endif
11606#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011607 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011608#endif
11609#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011610 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011611#endif
11612#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011613 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011614#endif
11615#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011616 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011617#endif
11618#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011619 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011620#endif
11621#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011622 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011623#endif
11624#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011625 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011626#endif
11627#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011628 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011629#endif
11630#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011631 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011632#endif
11633#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011634 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011635#endif
11636#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011637 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011638#endif
11639#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011640 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011641#endif
11642#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011643 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011644#endif
11645#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011646 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011647#endif
11648#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011649 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011650#endif
11651#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011652 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011653#endif
11654#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011655 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011656#endif
11657#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011658 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011659#endif
11660#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011661 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011662#endif
11663#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011664 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011665#endif
11666#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011667 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011668#endif
11669#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011670 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011671#endif
11672#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011673 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011674#endif
11675#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011676 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011677#endif
11678#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011679 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011680#endif
11681#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011682 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011683#endif
11684#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011685 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011686#endif
11687#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011688 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011689#endif
11690#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011691 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011692#endif
11693#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011694 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011695#endif
11696#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011697 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011698#endif
11699#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011700 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011701#endif
11702#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011703 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011704#endif
11705#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011706 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011707#endif
11708#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011709 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011710#endif
11711#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011712 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011713#endif
11714#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011715 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011716#endif
11717#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011718 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011719#endif
11720#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011721 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011722#endif
11723#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011724 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011725#endif
11726#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011727 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011728#endif
11729};
11730
11731static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011732conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011733{
11734 return conv_confname(arg, valuep, posix_constants_sysconf,
11735 sizeof(posix_constants_sysconf)
11736 / sizeof(struct constdef));
11737}
11738
Larry Hastings2f936352014-08-05 14:04:04 +100011739
11740/*[clinic input]
11741os.sysconf -> long
11742 name: sysconf_confname
11743 /
11744
11745Return an integer-valued system configuration variable.
11746[clinic start generated code]*/
11747
Larry Hastings2f936352014-08-05 14:04:04 +100011748static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011749os_sysconf_impl(PyObject *module, int name)
11750/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011751{
11752 long value;
11753
11754 errno = 0;
11755 value = sysconf(name);
11756 if (value == -1 && errno != 0)
11757 posix_error();
11758 return value;
11759}
11760#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011761
11762
Fred Drakebec628d1999-12-15 18:31:10 +000011763/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011764 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011765 * the exported dictionaries that are used to publish information about the
11766 * names available on the host platform.
11767 *
11768 * Sorting the table at runtime ensures that the table is properly ordered
11769 * when used, even for platforms we're not able to test on. It also makes
11770 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011771 */
Fred Drakebec628d1999-12-15 18:31:10 +000011772
11773static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011774cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011775{
11776 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011777 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011778 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011779 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011780
11781 return strcmp(c1->name, c2->name);
11782}
11783
11784static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011785setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011786 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011787{
Fred Drakebec628d1999-12-15 18:31:10 +000011788 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011789 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011790
11791 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11792 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011793 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011794 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011795
Barry Warsaw3155db32000-04-13 15:20:40 +000011796 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011797 PyObject *o = PyLong_FromLong(table[i].value);
11798 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11799 Py_XDECREF(o);
11800 Py_DECREF(d);
11801 return -1;
11802 }
11803 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011804 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011805 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011806}
11807
Fred Drakebec628d1999-12-15 18:31:10 +000011808/* Return -1 on failure, 0 on success. */
11809static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011810setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011811{
11812#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011813 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011814 sizeof(posix_constants_pathconf)
11815 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011816 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011817 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011818#endif
11819#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011820 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011821 sizeof(posix_constants_confstr)
11822 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011823 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011824 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011825#endif
11826#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011827 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011828 sizeof(posix_constants_sysconf)
11829 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011830 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011831 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011832#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011833 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011834}
Fred Draked86ed291999-12-15 15:34:33 +000011835
11836
Larry Hastings2f936352014-08-05 14:04:04 +100011837/*[clinic input]
11838os.abort
11839
11840Abort the interpreter immediately.
11841
11842This function 'dumps core' or otherwise fails in the hardest way possible
11843on the hosting operating system. This function never returns.
11844[clinic start generated code]*/
11845
Larry Hastings2f936352014-08-05 14:04:04 +100011846static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011847os_abort_impl(PyObject *module)
11848/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011849{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011850 abort();
11851 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011852#ifndef __clang__
11853 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11854 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11855 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011856 Py_FatalError("abort() called from Python code didn't abort!");
11857 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011858#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011859}
Fred Drakebec628d1999-12-15 18:31:10 +000011860
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011861#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011862/* Grab ShellExecute dynamically from shell32 */
11863static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011864static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11865 LPCWSTR, INT);
11866static int
11867check_ShellExecute()
11868{
11869 HINSTANCE hShell32;
11870
11871 /* only recheck */
11872 if (-1 == has_ShellExecute) {
11873 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011874 /* Security note: this call is not vulnerable to "DLL hijacking".
11875 SHELL32 is part of "KnownDLLs" and so Windows always load
11876 the system SHELL32.DLL, even if there is another SHELL32.DLL
11877 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011878 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011879 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011880 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11881 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011882 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011883 } else {
11884 has_ShellExecute = 0;
11885 }
Tony Roberts4860f012019-02-02 18:16:42 +010011886 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011887 }
11888 return has_ShellExecute;
11889}
11890
11891
Steve Dowercc16be82016-09-08 10:35:16 -070011892/*[clinic input]
11893os.startfile
11894 filepath: path_t
11895 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011896
Steve Dowercc16be82016-09-08 10:35:16 -070011897Start a file with its associated application.
11898
11899When "operation" is not specified or "open", this acts like
11900double-clicking the file in Explorer, or giving the file name as an
11901argument to the DOS "start" command: the file is opened with whatever
11902application (if any) its extension is associated.
11903When another "operation" is given, it specifies what should be done with
11904the file. A typical operation is "print".
11905
11906startfile returns as soon as the associated application is launched.
11907There is no option to wait for the application to close, and no way
11908to retrieve the application's exit status.
11909
11910The filepath is relative to the current directory. If you want to use
11911an absolute path, make sure the first character is not a slash ("/");
11912the underlying Win32 ShellExecute function doesn't work if it is.
11913[clinic start generated code]*/
11914
11915static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011916os_startfile_impl(PyObject *module, path_t *filepath,
11917 const Py_UNICODE *operation)
Serhiy Storchaka279f4462019-09-14 12:24:05 +030011918/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011919{
11920 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011921
11922 if(!check_ShellExecute()) {
11923 /* If the OS doesn't have ShellExecute, return a
11924 NotImplementedError. */
11925 return PyErr_Format(PyExc_NotImplementedError,
11926 "startfile not available on this platform");
11927 }
11928
Saiyang Gou7514f4f2020-02-12 23:47:42 -080011929 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080011930 return NULL;
11931 }
11932
Victor Stinner8c62be82010-05-06 00:08:46 +000011933 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011934 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011935 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011936 Py_END_ALLOW_THREADS
11937
Victor Stinner8c62be82010-05-06 00:08:46 +000011938 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011939 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011940 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011941 }
Steve Dowercc16be82016-09-08 10:35:16 -070011942 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011943}
Larry Hastings2f936352014-08-05 14:04:04 +100011944#endif /* MS_WINDOWS */
11945
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011946
Martin v. Löwis438b5342002-12-27 10:16:42 +000011947#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011948/*[clinic input]
11949os.getloadavg
11950
11951Return average recent system load information.
11952
11953Return the number of processes in the system run queue averaged over
11954the last 1, 5, and 15 minutes as a tuple of three floats.
11955Raises OSError if the load average was unobtainable.
11956[clinic start generated code]*/
11957
Larry Hastings2f936352014-08-05 14:04:04 +100011958static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011959os_getloadavg_impl(PyObject *module)
11960/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011961{
11962 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011963 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011964 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11965 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011966 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011967 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011968}
Larry Hastings2f936352014-08-05 14:04:04 +100011969#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011970
Larry Hastings2f936352014-08-05 14:04:04 +100011971
11972/*[clinic input]
11973os.device_encoding
11974 fd: int
11975
11976Return a string describing the encoding of a terminal's file descriptor.
11977
11978The file descriptor must be attached to a terminal.
11979If the device is not a terminal, return None.
11980[clinic start generated code]*/
11981
Larry Hastings2f936352014-08-05 14:04:04 +100011982static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011983os_device_encoding_impl(PyObject *module, int fd)
11984/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011985{
Brett Cannonefb00c02012-02-29 18:31:31 -050011986 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011987}
11988
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011989
Larry Hastings2f936352014-08-05 14:04:04 +100011990#ifdef HAVE_SETRESUID
11991/*[clinic input]
11992os.setresuid
11993
11994 ruid: uid_t
11995 euid: uid_t
11996 suid: uid_t
11997 /
11998
11999Set the current process's real, effective, and saved user ids.
12000[clinic start generated code]*/
12001
Larry Hastings2f936352014-08-05 14:04:04 +100012002static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012003os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
12004/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012005{
Victor Stinner8c62be82010-05-06 00:08:46 +000012006 if (setresuid(ruid, euid, suid) < 0)
12007 return posix_error();
12008 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012009}
Larry Hastings2f936352014-08-05 14:04:04 +100012010#endif /* HAVE_SETRESUID */
12011
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012012
12013#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012014/*[clinic input]
12015os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012016
Larry Hastings2f936352014-08-05 14:04:04 +100012017 rgid: gid_t
12018 egid: gid_t
12019 sgid: gid_t
12020 /
12021
12022Set the current process's real, effective, and saved group ids.
12023[clinic start generated code]*/
12024
Larry Hastings2f936352014-08-05 14:04:04 +100012025static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012026os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12027/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012028{
Victor Stinner8c62be82010-05-06 00:08:46 +000012029 if (setresgid(rgid, egid, sgid) < 0)
12030 return posix_error();
12031 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012032}
Larry Hastings2f936352014-08-05 14:04:04 +100012033#endif /* HAVE_SETRESGID */
12034
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012035
12036#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100012037/*[clinic input]
12038os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012039
Larry Hastings2f936352014-08-05 14:04:04 +100012040Return a tuple of the current process's real, effective, and saved user ids.
12041[clinic start generated code]*/
12042
Larry Hastings2f936352014-08-05 14:04:04 +100012043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012044os_getresuid_impl(PyObject *module)
12045/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012046{
Victor Stinner8c62be82010-05-06 00:08:46 +000012047 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012048 if (getresuid(&ruid, &euid, &suid) < 0)
12049 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012050 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
12051 _PyLong_FromUid(euid),
12052 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012053}
Larry Hastings2f936352014-08-05 14:04:04 +100012054#endif /* HAVE_GETRESUID */
12055
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012056
12057#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012058/*[clinic input]
12059os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012060
Larry Hastings2f936352014-08-05 14:04:04 +100012061Return a tuple of the current process's real, effective, and saved group ids.
12062[clinic start generated code]*/
12063
Larry Hastings2f936352014-08-05 14:04:04 +100012064static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012065os_getresgid_impl(PyObject *module)
12066/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012067{
12068 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012069 if (getresgid(&rgid, &egid, &sgid) < 0)
12070 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012071 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
12072 _PyLong_FromGid(egid),
12073 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012074}
Larry Hastings2f936352014-08-05 14:04:04 +100012075#endif /* HAVE_GETRESGID */
12076
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012077
Benjamin Peterson9428d532011-09-14 11:45:52 -040012078#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100012079/*[clinic input]
12080os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040012081
Larry Hastings2f936352014-08-05 14:04:04 +100012082 path: path_t(allow_fd=True)
12083 attribute: path_t
12084 *
12085 follow_symlinks: bool = True
12086
12087Return the value of extended attribute attribute on path.
12088
BNMetricsb9427072018-11-02 15:20:19 +000012089path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012090If follow_symlinks is False, and the last element of the path is a symbolic
12091 link, getxattr will examine the symbolic link itself instead of the file
12092 the link points to.
12093
12094[clinic start generated code]*/
12095
Larry Hastings2f936352014-08-05 14:04:04 +100012096static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012097os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012098 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012099/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012100{
12101 Py_ssize_t i;
12102 PyObject *buffer = NULL;
12103
12104 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12105 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012106
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012107 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12108 return NULL;
12109 }
12110
Larry Hastings9cf065c2012-06-22 16:30:09 -070012111 for (i = 0; ; i++) {
12112 void *ptr;
12113 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012114 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012115 Py_ssize_t buffer_size = buffer_sizes[i];
12116 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012117 path_error(path);
12118 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012119 }
12120 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12121 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012122 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012123 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012124
Larry Hastings9cf065c2012-06-22 16:30:09 -070012125 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012126 if (path->fd >= 0)
12127 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012128 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012129 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012130 else
Larry Hastings2f936352014-08-05 14:04:04 +100012131 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012132 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012133
Larry Hastings9cf065c2012-06-22 16:30:09 -070012134 if (result < 0) {
12135 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012136 if (errno == ERANGE)
12137 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012138 path_error(path);
12139 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012140 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012141
Larry Hastings9cf065c2012-06-22 16:30:09 -070012142 if (result != buffer_size) {
12143 /* Can only shrink. */
12144 _PyBytes_Resize(&buffer, result);
12145 }
12146 break;
12147 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012148
Larry Hastings9cf065c2012-06-22 16:30:09 -070012149 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012150}
12151
Larry Hastings2f936352014-08-05 14:04:04 +100012152
12153/*[clinic input]
12154os.setxattr
12155
12156 path: path_t(allow_fd=True)
12157 attribute: path_t
12158 value: Py_buffer
12159 flags: int = 0
12160 *
12161 follow_symlinks: bool = True
12162
12163Set extended attribute attribute on path to value.
12164
BNMetricsb9427072018-11-02 15:20:19 +000012165path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012166If follow_symlinks is False, and the last element of the path is a symbolic
12167 link, setxattr will modify the symbolic link itself instead of the file
12168 the link points to.
12169
12170[clinic start generated code]*/
12171
Benjamin Peterson799bd802011-08-31 22:15:17 -040012172static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012173os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012174 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012175/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012176{
Larry Hastings2f936352014-08-05 14:04:04 +100012177 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012178
Larry Hastings2f936352014-08-05 14:04:04 +100012179 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012180 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012181
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012182 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12183 value->buf, value->len, flags) < 0) {
12184 return NULL;
12185 }
12186
Benjamin Peterson799bd802011-08-31 22:15:17 -040012187 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012188 if (path->fd > -1)
12189 result = fsetxattr(path->fd, attribute->narrow,
12190 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012191 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012192 result = setxattr(path->narrow, attribute->narrow,
12193 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012194 else
Larry Hastings2f936352014-08-05 14:04:04 +100012195 result = lsetxattr(path->narrow, attribute->narrow,
12196 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012197 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012198
Larry Hastings9cf065c2012-06-22 16:30:09 -070012199 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012200 path_error(path);
12201 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012202 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012203
Larry Hastings2f936352014-08-05 14:04:04 +100012204 Py_RETURN_NONE;
12205}
12206
12207
12208/*[clinic input]
12209os.removexattr
12210
12211 path: path_t(allow_fd=True)
12212 attribute: path_t
12213 *
12214 follow_symlinks: bool = True
12215
12216Remove extended attribute attribute on path.
12217
BNMetricsb9427072018-11-02 15:20:19 +000012218path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012219If follow_symlinks is False, and the last element of the path is a symbolic
12220 link, removexattr will modify the symbolic link itself instead of the file
12221 the link points to.
12222
12223[clinic start generated code]*/
12224
Larry Hastings2f936352014-08-05 14:04:04 +100012225static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012226os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012227 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012228/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012229{
12230 ssize_t result;
12231
12232 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12233 return NULL;
12234
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012235 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12236 return NULL;
12237 }
12238
Larry Hastings2f936352014-08-05 14:04:04 +100012239 Py_BEGIN_ALLOW_THREADS;
12240 if (path->fd > -1)
12241 result = fremovexattr(path->fd, attribute->narrow);
12242 else if (follow_symlinks)
12243 result = removexattr(path->narrow, attribute->narrow);
12244 else
12245 result = lremovexattr(path->narrow, attribute->narrow);
12246 Py_END_ALLOW_THREADS;
12247
12248 if (result) {
12249 return path_error(path);
12250 }
12251
12252 Py_RETURN_NONE;
12253}
12254
12255
12256/*[clinic input]
12257os.listxattr
12258
12259 path: path_t(allow_fd=True, nullable=True) = None
12260 *
12261 follow_symlinks: bool = True
12262
12263Return a list of extended attributes on path.
12264
BNMetricsb9427072018-11-02 15:20:19 +000012265path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012266if path is None, listxattr will examine the current directory.
12267If follow_symlinks is False, and the last element of the path is a symbolic
12268 link, listxattr will examine the symbolic link itself instead of the file
12269 the link points to.
12270[clinic start generated code]*/
12271
Larry Hastings2f936352014-08-05 14:04:04 +100012272static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012273os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012274/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012275{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012276 Py_ssize_t i;
12277 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012278 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012279 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012280
Larry Hastings2f936352014-08-05 14:04:04 +100012281 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012282 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012283
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012284 if (PySys_Audit("os.listxattr", "(O)",
12285 path->object ? path->object : Py_None) < 0) {
12286 return NULL;
12287 }
12288
Larry Hastings2f936352014-08-05 14:04:04 +100012289 name = path->narrow ? path->narrow : ".";
12290
Larry Hastings9cf065c2012-06-22 16:30:09 -070012291 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012292 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012293 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012294 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012295 Py_ssize_t buffer_size = buffer_sizes[i];
12296 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012297 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012298 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012299 break;
12300 }
12301 buffer = PyMem_MALLOC(buffer_size);
12302 if (!buffer) {
12303 PyErr_NoMemory();
12304 break;
12305 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012306
Larry Hastings9cf065c2012-06-22 16:30:09 -070012307 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012308 if (path->fd > -1)
12309 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012310 else if (follow_symlinks)
12311 length = listxattr(name, buffer, buffer_size);
12312 else
12313 length = llistxattr(name, buffer, buffer_size);
12314 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012315
Larry Hastings9cf065c2012-06-22 16:30:09 -070012316 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012317 if (errno == ERANGE) {
12318 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012319 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012320 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012321 }
Larry Hastings2f936352014-08-05 14:04:04 +100012322 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012323 break;
12324 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012325
Larry Hastings9cf065c2012-06-22 16:30:09 -070012326 result = PyList_New(0);
12327 if (!result) {
12328 goto exit;
12329 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012330
Larry Hastings9cf065c2012-06-22 16:30:09 -070012331 end = buffer + length;
12332 for (trace = start = buffer; trace != end; trace++) {
12333 if (!*trace) {
12334 int error;
12335 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12336 trace - start);
12337 if (!attribute) {
12338 Py_DECREF(result);
12339 result = NULL;
12340 goto exit;
12341 }
12342 error = PyList_Append(result, attribute);
12343 Py_DECREF(attribute);
12344 if (error) {
12345 Py_DECREF(result);
12346 result = NULL;
12347 goto exit;
12348 }
12349 start = trace + 1;
12350 }
12351 }
12352 break;
12353 }
12354exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012355 if (buffer)
12356 PyMem_FREE(buffer);
12357 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012358}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012359#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012360
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012361
Larry Hastings2f936352014-08-05 14:04:04 +100012362/*[clinic input]
12363os.urandom
12364
12365 size: Py_ssize_t
12366 /
12367
12368Return a bytes object containing random bytes suitable for cryptographic use.
12369[clinic start generated code]*/
12370
Larry Hastings2f936352014-08-05 14:04:04 +100012371static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012372os_urandom_impl(PyObject *module, Py_ssize_t size)
12373/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012374{
12375 PyObject *bytes;
12376 int result;
12377
Georg Brandl2fb477c2012-02-21 00:33:36 +010012378 if (size < 0)
12379 return PyErr_Format(PyExc_ValueError,
12380 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012381 bytes = PyBytes_FromStringAndSize(NULL, size);
12382 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012383 return NULL;
12384
Victor Stinnere66987e2016-09-06 16:33:52 -070012385 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012386 if (result == -1) {
12387 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012388 return NULL;
12389 }
Larry Hastings2f936352014-08-05 14:04:04 +100012390 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012391}
12392
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012393#ifdef HAVE_MEMFD_CREATE
12394/*[clinic input]
12395os.memfd_create
12396
12397 name: FSConverter
12398 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12399
12400[clinic start generated code]*/
12401
12402static PyObject *
12403os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12404/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12405{
12406 int fd;
12407 const char *bytes = PyBytes_AS_STRING(name);
12408 Py_BEGIN_ALLOW_THREADS
12409 fd = memfd_create(bytes, flags);
12410 Py_END_ALLOW_THREADS
12411 if (fd == -1) {
12412 return PyErr_SetFromErrno(PyExc_OSError);
12413 }
12414 return PyLong_FromLong(fd);
12415}
12416#endif
12417
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012418/* Terminal size querying */
12419
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012420PyDoc_STRVAR(TerminalSize_docstring,
12421 "A tuple of (columns, lines) for holding terminal window size");
12422
12423static PyStructSequence_Field TerminalSize_fields[] = {
12424 {"columns", "width of the terminal window in characters"},
12425 {"lines", "height of the terminal window in characters"},
12426 {NULL, NULL}
12427};
12428
12429static PyStructSequence_Desc TerminalSize_desc = {
12430 "os.terminal_size",
12431 TerminalSize_docstring,
12432 TerminalSize_fields,
12433 2,
12434};
12435
12436#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012437/*[clinic input]
12438os.get_terminal_size
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012439
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012440 fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
12441 /
12442
12443Return the size of the terminal window as (columns, lines).
12444
12445The optional argument fd (default standard output) specifies
12446which file descriptor should be queried.
12447
12448If the file descriptor is not connected to a terminal, an OSError
12449is thrown.
12450
12451This function will only be defined if an implementation is
12452available for this system.
12453
12454shutil.get_terminal_size is the high-level function which should
12455normally be used, os.get_terminal_size is the low-level implementation.
12456[clinic start generated code]*/
12457
12458static PyObject *
12459os_get_terminal_size_impl(PyObject *module, int fd)
12460/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012461{
12462 int columns, lines;
12463 PyObject *termsize;
12464
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012465 /* Under some conditions stdout may not be connected and
12466 * fileno(stdout) may point to an invalid file descriptor. For example
12467 * GUI apps don't have valid standard streams by default.
12468 *
12469 * If this happens, and the optional fd argument is not present,
12470 * the ioctl below will fail returning EBADF. This is what we want.
12471 */
12472
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012473#ifdef TERMSIZE_USE_IOCTL
12474 {
12475 struct winsize w;
12476 if (ioctl(fd, TIOCGWINSZ, &w))
12477 return PyErr_SetFromErrno(PyExc_OSError);
12478 columns = w.ws_col;
12479 lines = w.ws_row;
12480 }
12481#endif /* TERMSIZE_USE_IOCTL */
12482
12483#ifdef TERMSIZE_USE_CONIO
12484 {
12485 DWORD nhandle;
12486 HANDLE handle;
12487 CONSOLE_SCREEN_BUFFER_INFO csbi;
12488 switch (fd) {
12489 case 0: nhandle = STD_INPUT_HANDLE;
12490 break;
12491 case 1: nhandle = STD_OUTPUT_HANDLE;
12492 break;
12493 case 2: nhandle = STD_ERROR_HANDLE;
12494 break;
12495 default:
12496 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12497 }
12498 handle = GetStdHandle(nhandle);
12499 if (handle == NULL)
12500 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12501 if (handle == INVALID_HANDLE_VALUE)
12502 return PyErr_SetFromWindowsErr(0);
12503
12504 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12505 return PyErr_SetFromWindowsErr(0);
12506
12507 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12508 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12509 }
12510#endif /* TERMSIZE_USE_CONIO */
12511
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012512 PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080012513 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012514 if (termsize == NULL)
12515 return NULL;
12516 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12517 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12518 if (PyErr_Occurred()) {
12519 Py_DECREF(termsize);
12520 return NULL;
12521 }
12522 return termsize;
12523}
12524#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12525
Larry Hastings2f936352014-08-05 14:04:04 +100012526
12527/*[clinic input]
12528os.cpu_count
12529
Charles-François Natali80d62e62015-08-13 20:37:08 +010012530Return the number of CPUs in the system; return None if indeterminable.
12531
12532This number is not equivalent to the number of CPUs the current process can
12533use. The number of usable CPUs can be obtained with
12534``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012535[clinic start generated code]*/
12536
Larry Hastings2f936352014-08-05 14:04:04 +100012537static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012538os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012539/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012540{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012541 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012542#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010012543 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012544#elif defined(__hpux)
12545 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12546#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12547 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012548#elif defined(__DragonFly__) || \
12549 defined(__OpenBSD__) || \
12550 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012551 defined(__NetBSD__) || \
12552 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012553 int mib[2];
12554 size_t len = sizeof(ncpu);
12555 mib[0] = CTL_HW;
12556 mib[1] = HW_NCPU;
12557 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12558 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012559#endif
12560 if (ncpu >= 1)
12561 return PyLong_FromLong(ncpu);
12562 else
12563 Py_RETURN_NONE;
12564}
12565
Victor Stinnerdaf45552013-08-28 00:53:59 +020012566
Larry Hastings2f936352014-08-05 14:04:04 +100012567/*[clinic input]
12568os.get_inheritable -> bool
12569
12570 fd: int
12571 /
12572
12573Get the close-on-exe flag of the specified file descriptor.
12574[clinic start generated code]*/
12575
Larry Hastings2f936352014-08-05 14:04:04 +100012576static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012577os_get_inheritable_impl(PyObject *module, int fd)
12578/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012579{
Steve Dower8fc89802015-04-12 00:26:27 -040012580 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012581 _Py_BEGIN_SUPPRESS_IPH
12582 return_value = _Py_get_inheritable(fd);
12583 _Py_END_SUPPRESS_IPH
12584 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012585}
12586
12587
12588/*[clinic input]
12589os.set_inheritable
12590 fd: int
12591 inheritable: int
12592 /
12593
12594Set the inheritable flag of the specified file descriptor.
12595[clinic start generated code]*/
12596
Larry Hastings2f936352014-08-05 14:04:04 +100012597static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012598os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12599/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012600{
Steve Dower8fc89802015-04-12 00:26:27 -040012601 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012602
Steve Dower8fc89802015-04-12 00:26:27 -040012603 _Py_BEGIN_SUPPRESS_IPH
12604 result = _Py_set_inheritable(fd, inheritable, NULL);
12605 _Py_END_SUPPRESS_IPH
12606 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012607 return NULL;
12608 Py_RETURN_NONE;
12609}
12610
12611
12612#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012613/*[clinic input]
12614os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012615 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012616 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012617
Larry Hastings2f936352014-08-05 14:04:04 +100012618Get the close-on-exe flag of the specified file descriptor.
12619[clinic start generated code]*/
12620
Larry Hastings2f936352014-08-05 14:04:04 +100012621static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012622os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012623/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012624{
12625 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012626
12627 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12628 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012629 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012630 }
12631
Larry Hastings2f936352014-08-05 14:04:04 +100012632 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012633}
12634
Victor Stinnerdaf45552013-08-28 00:53:59 +020012635
Larry Hastings2f936352014-08-05 14:04:04 +100012636/*[clinic input]
12637os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012638 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012639 inheritable: bool
12640 /
12641
12642Set the inheritable flag of the specified handle.
12643[clinic start generated code]*/
12644
Larry Hastings2f936352014-08-05 14:04:04 +100012645static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012646os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012647 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012648/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012649{
12650 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012651 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12652 PyErr_SetFromWindowsErr(0);
12653 return NULL;
12654 }
12655 Py_RETURN_NONE;
12656}
Larry Hastings2f936352014-08-05 14:04:04 +100012657#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012658
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012659#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012660/*[clinic input]
12661os.get_blocking -> bool
12662 fd: int
12663 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012664
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012665Get the blocking mode of the file descriptor.
12666
12667Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12668[clinic start generated code]*/
12669
12670static int
12671os_get_blocking_impl(PyObject *module, int fd)
12672/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012673{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012674 int blocking;
12675
Steve Dower8fc89802015-04-12 00:26:27 -040012676 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012677 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012678 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012679 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012680}
12681
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012682/*[clinic input]
12683os.set_blocking
12684 fd: int
12685 blocking: bool(accept={int})
12686 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012687
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012688Set the blocking mode of the specified file descriptor.
12689
12690Set the O_NONBLOCK flag if blocking is False,
12691clear the O_NONBLOCK flag otherwise.
12692[clinic start generated code]*/
12693
12694static PyObject *
12695os_set_blocking_impl(PyObject *module, int fd, int blocking)
12696/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012697{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012698 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012699
Steve Dower8fc89802015-04-12 00:26:27 -040012700 _Py_BEGIN_SUPPRESS_IPH
12701 result = _Py_set_blocking(fd, blocking);
12702 _Py_END_SUPPRESS_IPH
12703 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012704 return NULL;
12705 Py_RETURN_NONE;
12706}
12707#endif /* !MS_WINDOWS */
12708
12709
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012710/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080012711class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012712[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080012713/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012714
12715typedef struct {
12716 PyObject_HEAD
12717 PyObject *name;
12718 PyObject *path;
12719 PyObject *stat;
12720 PyObject *lstat;
12721#ifdef MS_WINDOWS
12722 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012723 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012724 int got_file_index;
12725#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012726#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012727 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012728#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012729 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012730 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012731#endif
12732} DirEntry;
12733
Eddie Elizondob3966632019-11-05 07:16:14 -080012734static PyObject *
12735_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
12736{
12737 PyErr_Format(PyExc_TypeError,
12738 "cannot create '%.100s' instances", _PyType_Name(type));
12739 return NULL;
12740}
12741
Victor Stinner6036e442015-03-08 01:58:04 +010012742static void
12743DirEntry_dealloc(DirEntry *entry)
12744{
Eddie Elizondob3966632019-11-05 07:16:14 -080012745 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010012746 Py_XDECREF(entry->name);
12747 Py_XDECREF(entry->path);
12748 Py_XDECREF(entry->stat);
12749 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080012750 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
12751 free_func(entry);
12752 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010012753}
12754
12755/* Forward reference */
12756static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012757DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
12758 int follow_symlinks, unsigned short mode_bits);
Victor Stinner6036e442015-03-08 01:58:04 +010012759
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012760/*[clinic input]
12761os.DirEntry.is_symlink -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020012762 defining_class: defining_class
12763 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012764
12765Return True if the entry is a symbolic link; cached per entry.
12766[clinic start generated code]*/
12767
Victor Stinner6036e442015-03-08 01:58:04 +010012768static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012769os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
12770/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012771{
12772#ifdef MS_WINDOWS
12773 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012774#elif defined(HAVE_DIRENT_D_TYPE)
12775 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012776 if (self->d_type != DT_UNKNOWN)
12777 return self->d_type == DT_LNK;
12778 else
Victor Stinner97f33c32020-05-14 18:05:58 +020012779 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012780#else
12781 /* POSIX without d_type */
Victor Stinner97f33c32020-05-14 18:05:58 +020012782 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012783#endif
12784}
12785
12786static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020012787DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
Victor Stinner6036e442015-03-08 01:58:04 +010012788{
12789 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012790 STRUCT_STAT st;
12791 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012792
12793#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012794 if (!PyUnicode_FSDecoder(self->path, &ub))
12795 return NULL;
12796 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012797#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012798 if (!PyUnicode_FSConverter(self->path, &ub))
12799 return NULL;
12800 const char *path = PyBytes_AS_STRING(ub);
12801 if (self->dir_fd != DEFAULT_DIR_FD) {
12802#ifdef HAVE_FSTATAT
12803 result = fstatat(self->dir_fd, path, &st,
12804 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12805#else
12806 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12807 return NULL;
12808#endif /* HAVE_FSTATAT */
12809 }
12810 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012811#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012812 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012813 if (follow_symlinks)
12814 result = STAT(path, &st);
12815 else
12816 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012817 }
12818 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012819
12820 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012821 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012822
Victor Stinner97f33c32020-05-14 18:05:58 +020012823 return _pystat_fromstructstat(module, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010012824}
12825
12826static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020012827DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
Victor Stinner6036e442015-03-08 01:58:04 +010012828{
12829 if (!self->lstat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020012830 PyObject *module = PyType_GetModule(defining_class);
Victor Stinner6036e442015-03-08 01:58:04 +010012831#ifdef MS_WINDOWS
Victor Stinner97f33c32020-05-14 18:05:58 +020012832 self->lstat = _pystat_fromstructstat(module, &self->win32_lstat);
Victor Stinner6036e442015-03-08 01:58:04 +010012833#else /* POSIX */
Victor Stinner97f33c32020-05-14 18:05:58 +020012834 self->lstat = DirEntry_fetch_stat(module, self, 0);
Victor Stinner6036e442015-03-08 01:58:04 +010012835#endif
12836 }
12837 Py_XINCREF(self->lstat);
12838 return self->lstat;
12839}
12840
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012841/*[clinic input]
12842os.DirEntry.stat
Victor Stinner97f33c32020-05-14 18:05:58 +020012843 defining_class: defining_class
12844 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012845 *
12846 follow_symlinks: bool = True
12847
12848Return stat_result object for the entry; cached per entry.
12849[clinic start generated code]*/
12850
Victor Stinner6036e442015-03-08 01:58:04 +010012851static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020012852os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
12853 int follow_symlinks)
12854/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012855{
Victor Stinner97f33c32020-05-14 18:05:58 +020012856 if (!follow_symlinks) {
12857 return DirEntry_get_lstat(defining_class, self);
12858 }
Victor Stinner6036e442015-03-08 01:58:04 +010012859
12860 if (!self->stat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020012861 int result = os_DirEntry_is_symlink_impl(self, defining_class);
12862 if (result == -1) {
Victor Stinner6036e442015-03-08 01:58:04 +010012863 return NULL;
Victor Stinner97f33c32020-05-14 18:05:58 +020012864 }
12865 if (result) {
12866 PyObject *module = PyType_GetModule(defining_class);
12867 self->stat = DirEntry_fetch_stat(module, self, 1);
12868 }
12869 else {
12870 self->stat = DirEntry_get_lstat(defining_class, self);
12871 }
Victor Stinner6036e442015-03-08 01:58:04 +010012872 }
12873
12874 Py_XINCREF(self->stat);
12875 return self->stat;
12876}
12877
Victor Stinner6036e442015-03-08 01:58:04 +010012878/* Set exception and return -1 on error, 0 for False, 1 for True */
12879static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012880DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
12881 int follow_symlinks, unsigned short mode_bits)
Victor Stinner6036e442015-03-08 01:58:04 +010012882{
12883 PyObject *stat = NULL;
12884 PyObject *st_mode = NULL;
12885 long mode;
12886 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012887#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012888 int is_symlink;
12889 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012890#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012891#ifdef MS_WINDOWS
12892 unsigned long dir_bits;
12893#endif
12894
12895#ifdef MS_WINDOWS
12896 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12897 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012898#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012899 is_symlink = self->d_type == DT_LNK;
12900 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12901#endif
12902
Victor Stinner35a97c02015-03-08 02:59:09 +010012903#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012904 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012905#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020012906 stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012907 if (!stat) {
12908 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12909 /* If file doesn't exist (anymore), then return False
12910 (i.e., say it's not a file/directory) */
12911 PyErr_Clear();
12912 return 0;
12913 }
12914 goto error;
12915 }
Victor Stinner97f33c32020-05-14 18:05:58 +020012916 _posixstate* state = get_posix_state(PyType_GetModule(defining_class));
12917 st_mode = PyObject_GetAttr(stat, state->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012918 if (!st_mode)
12919 goto error;
12920
12921 mode = PyLong_AsLong(st_mode);
12922 if (mode == -1 && PyErr_Occurred())
12923 goto error;
12924 Py_CLEAR(st_mode);
12925 Py_CLEAR(stat);
12926 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012927#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012928 }
12929 else if (is_symlink) {
12930 assert(mode_bits != S_IFLNK);
12931 result = 0;
12932 }
12933 else {
12934 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12935#ifdef MS_WINDOWS
12936 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12937 if (mode_bits == S_IFDIR)
12938 result = dir_bits != 0;
12939 else
12940 result = dir_bits == 0;
12941#else /* POSIX */
12942 if (mode_bits == S_IFDIR)
12943 result = self->d_type == DT_DIR;
12944 else
12945 result = self->d_type == DT_REG;
12946#endif
12947 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012948#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012949
12950 return result;
12951
12952error:
12953 Py_XDECREF(st_mode);
12954 Py_XDECREF(stat);
12955 return -1;
12956}
12957
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012958/*[clinic input]
12959os.DirEntry.is_dir -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020012960 defining_class: defining_class
12961 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012962 *
12963 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012964
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012965Return True if the entry is a directory; cached per entry.
12966[clinic start generated code]*/
12967
12968static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012969os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
12970 int follow_symlinks)
12971/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012972{
Victor Stinner97f33c32020-05-14 18:05:58 +020012973 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012974}
12975
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012976/*[clinic input]
12977os.DirEntry.is_file -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020012978 defining_class: defining_class
12979 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012980 *
12981 follow_symlinks: bool = True
12982
12983Return True if the entry is a file; cached per entry.
12984[clinic start generated code]*/
12985
12986static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012987os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
12988 int follow_symlinks)
12989/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012990{
Victor Stinner97f33c32020-05-14 18:05:58 +020012991 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012992}
12993
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012994/*[clinic input]
12995os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012996
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012997Return inode of the entry; cached per entry.
12998[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012999
13000static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013001os_DirEntry_inode_impl(DirEntry *self)
13002/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013003{
13004#ifdef MS_WINDOWS
13005 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013006 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013007 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013008 STRUCT_STAT stat;
13009 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010013010
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013011 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010013012 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013013 path = PyUnicode_AsUnicode(unicode);
13014 result = LSTAT(path, &stat);
13015 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010013016
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013017 if (result != 0)
13018 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013019
13020 self->win32_file_index = stat.st_ino;
13021 self->got_file_index = 1;
13022 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010013023 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
13024 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010013025#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020013026 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
13027 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010013028#endif
13029}
13030
13031static PyObject *
13032DirEntry_repr(DirEntry *self)
13033{
13034 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13035}
13036
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013037/*[clinic input]
13038os.DirEntry.__fspath__
13039
13040Returns the path for the entry.
13041[clinic start generated code]*/
13042
Brett Cannon96881cd2016-06-10 14:37:21 -070013043static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013044os_DirEntry___fspath___impl(DirEntry *self)
13045/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070013046{
13047 Py_INCREF(self->path);
13048 return self->path;
13049}
13050
Victor Stinner6036e442015-03-08 01:58:04 +010013051static PyMemberDef DirEntry_members[] = {
13052 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13053 "the entry's base filename, relative to scandir() \"path\" argument"},
13054 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13055 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13056 {NULL}
13057};
13058
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013059#include "clinic/posixmodule.c.h"
13060
Victor Stinner6036e442015-03-08 01:58:04 +010013061static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013062 OS_DIRENTRY_IS_DIR_METHODDEF
13063 OS_DIRENTRY_IS_FILE_METHODDEF
13064 OS_DIRENTRY_IS_SYMLINK_METHODDEF
13065 OS_DIRENTRY_STAT_METHODDEF
13066 OS_DIRENTRY_INODE_METHODDEF
13067 OS_DIRENTRY___FSPATH___METHODDEF
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013068 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
13069 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Victor Stinner6036e442015-03-08 01:58:04 +010013070 {NULL}
13071};
13072
Eddie Elizondob3966632019-11-05 07:16:14 -080013073static PyType_Slot DirEntryType_slots[] = {
13074 {Py_tp_new, _disabled_new},
13075 {Py_tp_dealloc, DirEntry_dealloc},
13076 {Py_tp_repr, DirEntry_repr},
13077 {Py_tp_methods, DirEntry_methods},
13078 {Py_tp_members, DirEntry_members},
13079 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010013080};
13081
Eddie Elizondob3966632019-11-05 07:16:14 -080013082static PyType_Spec DirEntryType_spec = {
13083 MODNAME ".DirEntry",
13084 sizeof(DirEntry),
13085 0,
13086 Py_TPFLAGS_DEFAULT,
13087 DirEntryType_slots
13088};
13089
13090
Victor Stinner6036e442015-03-08 01:58:04 +010013091#ifdef MS_WINDOWS
13092
13093static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013094join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010013095{
13096 Py_ssize_t path_len;
13097 Py_ssize_t size;
13098 wchar_t *result;
13099 wchar_t ch;
13100
13101 if (!path_wide) { /* Default arg: "." */
13102 path_wide = L".";
13103 path_len = 1;
13104 }
13105 else {
13106 path_len = wcslen(path_wide);
13107 }
13108
13109 /* The +1's are for the path separator and the NUL */
13110 size = path_len + 1 + wcslen(filename) + 1;
13111 result = PyMem_New(wchar_t, size);
13112 if (!result) {
13113 PyErr_NoMemory();
13114 return NULL;
13115 }
13116 wcscpy(result, path_wide);
13117 if (path_len > 0) {
13118 ch = result[path_len - 1];
13119 if (ch != SEP && ch != ALTSEP && ch != L':')
13120 result[path_len++] = SEP;
13121 wcscpy(result + path_len, filename);
13122 }
13123 return result;
13124}
13125
13126static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013127DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
Victor Stinner6036e442015-03-08 01:58:04 +010013128{
13129 DirEntry *entry;
13130 BY_HANDLE_FILE_INFORMATION file_info;
13131 ULONG reparse_tag;
13132 wchar_t *joined_path;
13133
Victor Stinner1c2fa782020-05-10 11:05:29 +020013134 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013135 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013136 if (!entry)
13137 return NULL;
13138 entry->name = NULL;
13139 entry->path = NULL;
13140 entry->stat = NULL;
13141 entry->lstat = NULL;
13142 entry->got_file_index = 0;
13143
13144 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13145 if (!entry->name)
13146 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013147 if (path->narrow) {
13148 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13149 if (!entry->name)
13150 goto error;
13151 }
Victor Stinner6036e442015-03-08 01:58:04 +010013152
13153 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13154 if (!joined_path)
13155 goto error;
13156
13157 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13158 PyMem_Free(joined_path);
13159 if (!entry->path)
13160 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013161 if (path->narrow) {
13162 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13163 if (!entry->path)
13164 goto error;
13165 }
Victor Stinner6036e442015-03-08 01:58:04 +010013166
Steve Dowercc16be82016-09-08 10:35:16 -070013167 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013168 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13169
13170 return (PyObject *)entry;
13171
13172error:
13173 Py_DECREF(entry);
13174 return NULL;
13175}
13176
13177#else /* POSIX */
13178
13179static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013180join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013181{
13182 Py_ssize_t path_len;
13183 Py_ssize_t size;
13184 char *result;
13185
13186 if (!path_narrow) { /* Default arg: "." */
13187 path_narrow = ".";
13188 path_len = 1;
13189 }
13190 else {
13191 path_len = strlen(path_narrow);
13192 }
13193
13194 if (filename_len == -1)
13195 filename_len = strlen(filename);
13196
13197 /* The +1's are for the path separator and the NUL */
13198 size = path_len + 1 + filename_len + 1;
13199 result = PyMem_New(char, size);
13200 if (!result) {
13201 PyErr_NoMemory();
13202 return NULL;
13203 }
13204 strcpy(result, path_narrow);
13205 if (path_len > 0 && result[path_len - 1] != '/')
13206 result[path_len++] = '/';
13207 strcpy(result + path_len, filename);
13208 return result;
13209}
13210
13211static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013212DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13213 Py_ssize_t name_len, ino_t d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013214#ifdef HAVE_DIRENT_D_TYPE
13215 , unsigned char d_type
13216#endif
13217 )
Victor Stinner6036e442015-03-08 01:58:04 +010013218{
13219 DirEntry *entry;
13220 char *joined_path;
13221
Victor Stinner1c2fa782020-05-10 11:05:29 +020013222 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013223 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013224 if (!entry)
13225 return NULL;
13226 entry->name = NULL;
13227 entry->path = NULL;
13228 entry->stat = NULL;
13229 entry->lstat = NULL;
13230
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013231 if (path->fd != -1) {
13232 entry->dir_fd = path->fd;
13233 joined_path = NULL;
13234 }
13235 else {
13236 entry->dir_fd = DEFAULT_DIR_FD;
13237 joined_path = join_path_filename(path->narrow, name, name_len);
13238 if (!joined_path)
13239 goto error;
13240 }
Victor Stinner6036e442015-03-08 01:58:04 +010013241
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013242 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013243 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013244 if (joined_path)
13245 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013246 }
13247 else {
13248 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013249 if (joined_path)
13250 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013251 }
13252 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013253 if (!entry->name)
13254 goto error;
13255
13256 if (path->fd != -1) {
13257 entry->path = entry->name;
13258 Py_INCREF(entry->path);
13259 }
13260 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013261 goto error;
13262
Victor Stinner35a97c02015-03-08 02:59:09 +010013263#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013264 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013265#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013266 entry->d_ino = d_ino;
13267
13268 return (PyObject *)entry;
13269
13270error:
13271 Py_XDECREF(entry);
13272 return NULL;
13273}
13274
13275#endif
13276
13277
13278typedef struct {
13279 PyObject_HEAD
13280 path_t path;
13281#ifdef MS_WINDOWS
13282 HANDLE handle;
13283 WIN32_FIND_DATAW file_data;
13284 int first_time;
13285#else /* POSIX */
13286 DIR *dirp;
13287#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013288#ifdef HAVE_FDOPENDIR
13289 int fd;
13290#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013291} ScandirIterator;
13292
13293#ifdef MS_WINDOWS
13294
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013295static int
13296ScandirIterator_is_closed(ScandirIterator *iterator)
13297{
13298 return iterator->handle == INVALID_HANDLE_VALUE;
13299}
13300
Victor Stinner6036e442015-03-08 01:58:04 +010013301static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013302ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013303{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013304 HANDLE handle = iterator->handle;
13305
13306 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013307 return;
13308
Victor Stinner6036e442015-03-08 01:58:04 +010013309 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013310 Py_BEGIN_ALLOW_THREADS
13311 FindClose(handle);
13312 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013313}
13314
13315static PyObject *
13316ScandirIterator_iternext(ScandirIterator *iterator)
13317{
13318 WIN32_FIND_DATAW *file_data = &iterator->file_data;
13319 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013320 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013321
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013322 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013323 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013324 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013325
13326 while (1) {
13327 if (!iterator->first_time) {
13328 Py_BEGIN_ALLOW_THREADS
13329 success = FindNextFileW(iterator->handle, file_data);
13330 Py_END_ALLOW_THREADS
13331 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013332 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013333 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013334 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013335 break;
13336 }
13337 }
13338 iterator->first_time = 0;
13339
13340 /* Skip over . and .. */
13341 if (wcscmp(file_data->cFileName, L".") != 0 &&
Victor Stinner1c2fa782020-05-10 11:05:29 +020013342 wcscmp(file_data->cFileName, L"..") != 0)
13343 {
13344 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13345 entry = DirEntry_from_find_data(module, &iterator->path, file_data);
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013346 if (!entry)
13347 break;
13348 return entry;
13349 }
Victor Stinner6036e442015-03-08 01:58:04 +010013350
13351 /* Loop till we get a non-dot directory or finish iterating */
13352 }
13353
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013354 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013355 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013356 return NULL;
13357}
13358
13359#else /* POSIX */
13360
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013361static int
13362ScandirIterator_is_closed(ScandirIterator *iterator)
13363{
13364 return !iterator->dirp;
13365}
13366
Victor Stinner6036e442015-03-08 01:58:04 +010013367static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013368ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013369{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013370 DIR *dirp = iterator->dirp;
13371
13372 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013373 return;
13374
Victor Stinner6036e442015-03-08 01:58:04 +010013375 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013376 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013377#ifdef HAVE_FDOPENDIR
13378 if (iterator->path.fd != -1)
13379 rewinddir(dirp);
13380#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013381 closedir(dirp);
13382 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013383 return;
13384}
13385
13386static PyObject *
13387ScandirIterator_iternext(ScandirIterator *iterator)
13388{
13389 struct dirent *direntp;
13390 Py_ssize_t name_len;
13391 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013392 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013393
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013394 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013395 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013396 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013397
13398 while (1) {
13399 errno = 0;
13400 Py_BEGIN_ALLOW_THREADS
13401 direntp = readdir(iterator->dirp);
13402 Py_END_ALLOW_THREADS
13403
13404 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013405 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013406 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013407 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013408 break;
13409 }
13410
13411 /* Skip over . and .. */
13412 name_len = NAMLEN(direntp);
13413 is_dot = direntp->d_name[0] == '.' &&
13414 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
13415 if (!is_dot) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020013416 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13417 entry = DirEntry_from_posix_info(module,
13418 &iterator->path, direntp->d_name,
13419 name_len, direntp->d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013420#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner1c2fa782020-05-10 11:05:29 +020013421 , direntp->d_type
Victor Stinner35a97c02015-03-08 02:59:09 +010013422#endif
13423 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013424 if (!entry)
13425 break;
13426 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013427 }
13428
13429 /* Loop till we get a non-dot directory or finish iterating */
13430 }
13431
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013432 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013433 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013434 return NULL;
13435}
13436
13437#endif
13438
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013439static PyObject *
13440ScandirIterator_close(ScandirIterator *self, PyObject *args)
13441{
13442 ScandirIterator_closedir(self);
13443 Py_RETURN_NONE;
13444}
13445
13446static PyObject *
13447ScandirIterator_enter(PyObject *self, PyObject *args)
13448{
13449 Py_INCREF(self);
13450 return self;
13451}
13452
13453static PyObject *
13454ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13455{
13456 ScandirIterator_closedir(self);
13457 Py_RETURN_NONE;
13458}
13459
Victor Stinner6036e442015-03-08 01:58:04 +010013460static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013461ScandirIterator_finalize(ScandirIterator *iterator)
13462{
13463 PyObject *error_type, *error_value, *error_traceback;
13464
13465 /* Save the current exception, if any. */
13466 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13467
13468 if (!ScandirIterator_is_closed(iterator)) {
13469 ScandirIterator_closedir(iterator);
13470
13471 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13472 "unclosed scandir iterator %R", iterator)) {
13473 /* Spurious errors can appear at shutdown */
13474 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13475 PyErr_WriteUnraisable((PyObject *) iterator);
13476 }
13477 }
13478 }
13479
Victor Stinner7bfa4092016-03-23 00:43:54 +010013480 path_cleanup(&iterator->path);
13481
13482 /* Restore the saved exception. */
13483 PyErr_Restore(error_type, error_value, error_traceback);
13484}
13485
13486static void
Victor Stinner6036e442015-03-08 01:58:04 +010013487ScandirIterator_dealloc(ScandirIterator *iterator)
13488{
Eddie Elizondob3966632019-11-05 07:16:14 -080013489 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010013490 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13491 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013492
Eddie Elizondob3966632019-11-05 07:16:14 -080013493 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13494 free_func(iterator);
13495 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013496}
13497
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013498static PyMethodDef ScandirIterator_methods[] = {
13499 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13500 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13501 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13502 {NULL}
13503};
13504
Eddie Elizondob3966632019-11-05 07:16:14 -080013505static PyType_Slot ScandirIteratorType_slots[] = {
13506 {Py_tp_new, _disabled_new},
13507 {Py_tp_dealloc, ScandirIterator_dealloc},
13508 {Py_tp_finalize, ScandirIterator_finalize},
13509 {Py_tp_iter, PyObject_SelfIter},
13510 {Py_tp_iternext, ScandirIterator_iternext},
13511 {Py_tp_methods, ScandirIterator_methods},
13512 {0, 0},
13513};
13514
13515static PyType_Spec ScandirIteratorType_spec = {
13516 MODNAME ".ScandirIterator",
13517 sizeof(ScandirIterator),
13518 0,
Victor Stinner97f33c32020-05-14 18:05:58 +020013519 // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
13520 // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
Eddie Elizondob3966632019-11-05 07:16:14 -080013521 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
13522 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010013523};
13524
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013525/*[clinic input]
13526os.scandir
13527
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013528 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013529
13530Return an iterator of DirEntry objects for given path.
13531
BNMetricsb9427072018-11-02 15:20:19 +000013532path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013533is bytes, the names of yielded DirEntry objects will also be bytes; in
13534all other circumstances they will be str.
13535
13536If path is None, uses the path='.'.
13537[clinic start generated code]*/
13538
Victor Stinner6036e442015-03-08 01:58:04 +010013539static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013540os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013541/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013542{
13543 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013544#ifdef MS_WINDOWS
13545 wchar_t *path_strW;
13546#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013547 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013548#ifdef HAVE_FDOPENDIR
13549 int fd = -1;
13550#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013551#endif
13552
Steve Dower60419a72019-06-24 08:42:54 -070013553 if (PySys_Audit("os.scandir", "O",
13554 path->object ? path->object : Py_None) < 0) {
13555 return NULL;
13556 }
13557
Hai Shif707d942020-03-16 21:15:01 +080013558 PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013559 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010013560 if (!iterator)
13561 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013562
13563#ifdef MS_WINDOWS
13564 iterator->handle = INVALID_HANDLE_VALUE;
13565#else
13566 iterator->dirp = NULL;
13567#endif
13568
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013569 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013570 /* Move the ownership to iterator->path */
13571 path->object = NULL;
13572 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013573
13574#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013575 iterator->first_time = 1;
13576
13577 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13578 if (!path_strW)
13579 goto error;
13580
13581 Py_BEGIN_ALLOW_THREADS
13582 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13583 Py_END_ALLOW_THREADS
13584
13585 PyMem_Free(path_strW);
13586
13587 if (iterator->handle == INVALID_HANDLE_VALUE) {
13588 path_error(&iterator->path);
13589 goto error;
13590 }
13591#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013592 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013593#ifdef HAVE_FDOPENDIR
13594 if (path->fd != -1) {
13595 /* closedir() closes the FD, so we duplicate it */
13596 fd = _Py_dup(path->fd);
13597 if (fd == -1)
13598 goto error;
13599
13600 Py_BEGIN_ALLOW_THREADS
13601 iterator->dirp = fdopendir(fd);
13602 Py_END_ALLOW_THREADS
13603 }
13604 else
13605#endif
13606 {
13607 if (iterator->path.narrow)
13608 path_str = iterator->path.narrow;
13609 else
13610 path_str = ".";
13611
13612 Py_BEGIN_ALLOW_THREADS
13613 iterator->dirp = opendir(path_str);
13614 Py_END_ALLOW_THREADS
13615 }
Victor Stinner6036e442015-03-08 01:58:04 +010013616
13617 if (!iterator->dirp) {
13618 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013619#ifdef HAVE_FDOPENDIR
13620 if (fd != -1) {
13621 Py_BEGIN_ALLOW_THREADS
13622 close(fd);
13623 Py_END_ALLOW_THREADS
13624 }
13625#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013626 goto error;
13627 }
13628#endif
13629
13630 return (PyObject *)iterator;
13631
13632error:
13633 Py_DECREF(iterator);
13634 return NULL;
13635}
13636
Ethan Furman410ef8e2016-06-04 12:06:26 -070013637/*
13638 Return the file system path representation of the object.
13639
13640 If the object is str or bytes, then allow it to pass through with
13641 an incremented refcount. If the object defines __fspath__(), then
13642 return the result of that method. All other types raise a TypeError.
13643*/
13644PyObject *
13645PyOS_FSPath(PyObject *path)
13646{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013647 /* For error message reasons, this function is manually inlined in
13648 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013649 PyObject *func = NULL;
13650 PyObject *path_repr = NULL;
13651
13652 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13653 Py_INCREF(path);
13654 return path;
13655 }
13656
13657 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13658 if (NULL == func) {
13659 return PyErr_Format(PyExc_TypeError,
13660 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013661 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080013662 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070013663 }
13664
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013665 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013666 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013667 if (NULL == path_repr) {
13668 return NULL;
13669 }
13670
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013671 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13672 PyErr_Format(PyExc_TypeError,
13673 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080013674 "not %.200s", _PyType_Name(Py_TYPE(path)),
13675 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013676 Py_DECREF(path_repr);
13677 return NULL;
13678 }
13679
Ethan Furman410ef8e2016-06-04 12:06:26 -070013680 return path_repr;
13681}
13682
13683/*[clinic input]
13684os.fspath
13685
13686 path: object
13687
13688Return the file system path representation of the object.
13689
Brett Cannonb4f43e92016-06-09 14:32:08 -070013690If the object is str or bytes, then allow it to pass through as-is. If the
13691object defines __fspath__(), then return the result of that method. All other
13692types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013693[clinic start generated code]*/
13694
13695static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013696os_fspath_impl(PyObject *module, PyObject *path)
13697/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013698{
13699 return PyOS_FSPath(path);
13700}
Victor Stinner6036e442015-03-08 01:58:04 +010013701
Victor Stinner9b1f4742016-09-06 16:18:52 -070013702#ifdef HAVE_GETRANDOM_SYSCALL
13703/*[clinic input]
13704os.getrandom
13705
13706 size: Py_ssize_t
13707 flags: int=0
13708
13709Obtain a series of random bytes.
13710[clinic start generated code]*/
13711
13712static PyObject *
13713os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13714/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13715{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013716 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013717 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013718
13719 if (size < 0) {
13720 errno = EINVAL;
13721 return posix_error();
13722 }
13723
Victor Stinnerec2319c2016-09-20 23:00:59 +020013724 bytes = PyBytes_FromStringAndSize(NULL, size);
13725 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013726 PyErr_NoMemory();
13727 return NULL;
13728 }
13729
13730 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013731 n = syscall(SYS_getrandom,
13732 PyBytes_AS_STRING(bytes),
13733 PyBytes_GET_SIZE(bytes),
13734 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013735 if (n < 0 && errno == EINTR) {
13736 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013737 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013738 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013739
13740 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013741 continue;
13742 }
13743 break;
13744 }
13745
13746 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013747 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013748 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013749 }
13750
Victor Stinnerec2319c2016-09-20 23:00:59 +020013751 if (n != size) {
13752 _PyBytes_Resize(&bytes, n);
13753 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013754
13755 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013756
13757error:
13758 Py_DECREF(bytes);
13759 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013760}
13761#endif /* HAVE_GETRANDOM_SYSCALL */
13762
Steve Dower2438cdf2019-03-29 16:37:16 -070013763#ifdef MS_WINDOWS
13764/* bpo-36085: Helper functions for managing DLL search directories
13765 * on win32
13766 */
13767
13768typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13769typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13770
13771/*[clinic input]
13772os._add_dll_directory
13773
13774 path: path_t
13775
13776Add a path to the DLL search path.
13777
13778This search path is used when resolving dependencies for imported
13779extension modules (the module itself is resolved through sys.path),
13780and also by ctypes.
13781
13782Returns an opaque value that may be passed to os.remove_dll_directory
13783to remove this directory from the search path.
13784[clinic start generated code]*/
13785
13786static PyObject *
13787os__add_dll_directory_impl(PyObject *module, path_t *path)
13788/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13789{
13790 HMODULE hKernel32;
13791 PAddDllDirectory AddDllDirectory;
13792 DLL_DIRECTORY_COOKIE cookie = 0;
13793 DWORD err = 0;
13794
Saiyang Gou7514f4f2020-02-12 23:47:42 -080013795 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
13796 return NULL;
13797 }
13798
Steve Dower2438cdf2019-03-29 16:37:16 -070013799 /* For Windows 7, we have to load this. As this will be a fairly
13800 infrequent operation, just do it each time. Kernel32 is always
13801 loaded. */
13802 Py_BEGIN_ALLOW_THREADS
13803 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13804 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13805 hKernel32, "AddDllDirectory")) ||
13806 !(cookie = (*AddDllDirectory)(path->wide))) {
13807 err = GetLastError();
13808 }
13809 Py_END_ALLOW_THREADS
13810
13811 if (err) {
13812 return win32_error_object_err("add_dll_directory",
13813 path->object, err);
13814 }
13815
13816 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13817}
13818
13819/*[clinic input]
13820os._remove_dll_directory
13821
13822 cookie: object
13823
13824Removes a path from the DLL search path.
13825
13826The parameter is an opaque value that was returned from
13827os.add_dll_directory. You can only remove directories that you added
13828yourself.
13829[clinic start generated code]*/
13830
13831static PyObject *
13832os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13833/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13834{
13835 HMODULE hKernel32;
13836 PRemoveDllDirectory RemoveDllDirectory;
13837 DLL_DIRECTORY_COOKIE cookieValue;
13838 DWORD err = 0;
13839
13840 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13841 PyErr_SetString(PyExc_TypeError,
13842 "Provided cookie was not returned from os.add_dll_directory");
13843 return NULL;
13844 }
13845
13846 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13847 cookie, "DLL directory cookie");
13848
13849 /* For Windows 7, we have to load this. As this will be a fairly
13850 infrequent operation, just do it each time. Kernel32 is always
13851 loaded. */
13852 Py_BEGIN_ALLOW_THREADS
13853 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13854 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13855 hKernel32, "RemoveDllDirectory")) ||
13856 !(*RemoveDllDirectory)(cookieValue)) {
13857 err = GetLastError();
13858 }
13859 Py_END_ALLOW_THREADS
13860
13861 if (err) {
13862 return win32_error_object_err("remove_dll_directory",
13863 NULL, err);
13864 }
13865
13866 if (PyCapsule_SetName(cookie, NULL)) {
13867 return NULL;
13868 }
13869
13870 Py_RETURN_NONE;
13871}
13872
13873#endif
Larry Hastings31826802013-10-19 00:09:25 -070013874
Victor Stinner65a796e2020-04-01 18:49:29 +020013875
13876/* Only check if WIFEXITED is available: expect that it comes
13877 with WEXITSTATUS, WIFSIGNALED, etc.
13878
13879 os.waitstatus_to_exitcode() is implemented in C and not in Python, so
13880 subprocess can safely call it during late Python finalization without
13881 risking that used os attributes were set to None by _PyImport_Cleanup(). */
13882#if defined(WIFEXITED) || defined(MS_WINDOWS)
13883/*[clinic input]
13884os.waitstatus_to_exitcode
13885
Victor Stinner9bee32b2020-04-22 16:30:35 +020013886 status as status_obj: object
Victor Stinner65a796e2020-04-01 18:49:29 +020013887
13888Convert a wait status to an exit code.
13889
13890On Unix:
13891
13892* If WIFEXITED(status) is true, return WEXITSTATUS(status).
13893* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
13894* Otherwise, raise a ValueError.
13895
13896On Windows, return status shifted right by 8 bits.
13897
13898On Unix, if the process is being traced or if waitpid() was called with
13899WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
13900This function must not be called if WIFSTOPPED(status) is true.
13901[clinic start generated code]*/
13902
13903static PyObject *
Victor Stinner9bee32b2020-04-22 16:30:35 +020013904os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
13905/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
Victor Stinner65a796e2020-04-01 18:49:29 +020013906{
13907#ifndef MS_WINDOWS
Victor Stinner9bee32b2020-04-22 16:30:35 +020013908 int status = _PyLong_AsInt(status_obj);
13909 if (status == -1 && PyErr_Occurred()) {
13910 return NULL;
13911 }
13912
Victor Stinner65a796e2020-04-01 18:49:29 +020013913 WAIT_TYPE wait_status;
13914 WAIT_STATUS_INT(wait_status) = status;
13915 int exitcode;
13916 if (WIFEXITED(wait_status)) {
13917 exitcode = WEXITSTATUS(wait_status);
13918 /* Sanity check to provide warranty on the function behavior.
13919 It should not occur in practice */
13920 if (exitcode < 0) {
13921 PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
13922 return NULL;
13923 }
13924 }
13925 else if (WIFSIGNALED(wait_status)) {
13926 int signum = WTERMSIG(wait_status);
13927 /* Sanity check to provide warranty on the function behavior.
13928 It should not occurs in practice */
13929 if (signum <= 0) {
13930 PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
13931 return NULL;
13932 }
13933 exitcode = -signum;
13934 } else if (WIFSTOPPED(wait_status)) {
13935 /* Status only received if the process is being traced
13936 or if waitpid() was called with WUNTRACED option. */
13937 int signum = WSTOPSIG(wait_status);
13938 PyErr_Format(PyExc_ValueError,
13939 "process stopped by delivery of signal %i",
13940 signum);
13941 return NULL;
13942 }
13943 else {
13944 PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
13945 return NULL;
13946 }
13947 return PyLong_FromLong(exitcode);
13948#else
13949 /* Windows implementation: see os.waitpid() implementation
13950 which uses _cwait(). */
Victor Stinner9bee32b2020-04-22 16:30:35 +020013951 unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
13952 if (status == (unsigned long long)-1 && PyErr_Occurred()) {
13953 return NULL;
13954 }
13955
13956 unsigned long long exitcode = (status >> 8);
13957 /* ExitProcess() accepts an UINT type:
13958 reject exit code which doesn't fit in an UINT */
13959 if (exitcode > UINT_MAX) {
13960 PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
13961 return NULL;
13962 }
13963 return PyLong_FromUnsignedLong((unsigned long)exitcode);
Victor Stinner65a796e2020-04-01 18:49:29 +020013964#endif
13965}
13966#endif
13967
13968
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013969static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013970
13971 OS_STAT_METHODDEF
13972 OS_ACCESS_METHODDEF
13973 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013974 OS_CHDIR_METHODDEF
13975 OS_CHFLAGS_METHODDEF
13976 OS_CHMOD_METHODDEF
13977 OS_FCHMOD_METHODDEF
13978 OS_LCHMOD_METHODDEF
13979 OS_CHOWN_METHODDEF
13980 OS_FCHOWN_METHODDEF
13981 OS_LCHOWN_METHODDEF
13982 OS_LCHFLAGS_METHODDEF
13983 OS_CHROOT_METHODDEF
13984 OS_CTERMID_METHODDEF
13985 OS_GETCWD_METHODDEF
13986 OS_GETCWDB_METHODDEF
13987 OS_LINK_METHODDEF
13988 OS_LISTDIR_METHODDEF
13989 OS_LSTAT_METHODDEF
13990 OS_MKDIR_METHODDEF
13991 OS_NICE_METHODDEF
13992 OS_GETPRIORITY_METHODDEF
13993 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013994 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013995 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013996 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010013997 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013998 OS_RENAME_METHODDEF
13999 OS_REPLACE_METHODDEF
14000 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014001 OS_SYMLINK_METHODDEF
14002 OS_SYSTEM_METHODDEF
14003 OS_UMASK_METHODDEF
14004 OS_UNAME_METHODDEF
14005 OS_UNLINK_METHODDEF
14006 OS_REMOVE_METHODDEF
14007 OS_UTIME_METHODDEF
14008 OS_TIMES_METHODDEF
14009 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014010 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014011 OS_EXECV_METHODDEF
14012 OS_EXECVE_METHODDEF
14013 OS_SPAWNV_METHODDEF
14014 OS_SPAWNVE_METHODDEF
14015 OS_FORK1_METHODDEF
14016 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020014017 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014018 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14019 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14020 OS_SCHED_GETPARAM_METHODDEF
14021 OS_SCHED_GETSCHEDULER_METHODDEF
14022 OS_SCHED_RR_GET_INTERVAL_METHODDEF
14023 OS_SCHED_SETPARAM_METHODDEF
14024 OS_SCHED_SETSCHEDULER_METHODDEF
14025 OS_SCHED_YIELD_METHODDEF
14026 OS_SCHED_SETAFFINITY_METHODDEF
14027 OS_SCHED_GETAFFINITY_METHODDEF
14028 OS_OPENPTY_METHODDEF
14029 OS_FORKPTY_METHODDEF
14030 OS_GETEGID_METHODDEF
14031 OS_GETEUID_METHODDEF
14032 OS_GETGID_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014033 OS_GETGROUPLIST_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014034 OS_GETGROUPS_METHODDEF
14035 OS_GETPID_METHODDEF
14036 OS_GETPGRP_METHODDEF
14037 OS_GETPPID_METHODDEF
14038 OS_GETUID_METHODDEF
14039 OS_GETLOGIN_METHODDEF
14040 OS_KILL_METHODDEF
14041 OS_KILLPG_METHODDEF
14042 OS_PLOCK_METHODDEF
Steve Dowercc16be82016-09-08 10:35:16 -070014043 OS_STARTFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014044 OS_SETUID_METHODDEF
14045 OS_SETEUID_METHODDEF
14046 OS_SETREUID_METHODDEF
14047 OS_SETGID_METHODDEF
14048 OS_SETEGID_METHODDEF
14049 OS_SETREGID_METHODDEF
14050 OS_SETGROUPS_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014051 OS_INITGROUPS_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014052 OS_GETPGID_METHODDEF
14053 OS_SETPGRP_METHODDEF
14054 OS_WAIT_METHODDEF
14055 OS_WAIT3_METHODDEF
14056 OS_WAIT4_METHODDEF
14057 OS_WAITID_METHODDEF
14058 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080014059 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014060 OS_GETSID_METHODDEF
14061 OS_SETSID_METHODDEF
14062 OS_SETPGID_METHODDEF
14063 OS_TCGETPGRP_METHODDEF
14064 OS_TCSETPGRP_METHODDEF
14065 OS_OPEN_METHODDEF
14066 OS_CLOSE_METHODDEF
14067 OS_CLOSERANGE_METHODDEF
14068 OS_DEVICE_ENCODING_METHODDEF
14069 OS_DUP_METHODDEF
14070 OS_DUP2_METHODDEF
14071 OS_LOCKF_METHODDEF
14072 OS_LSEEK_METHODDEF
14073 OS_READ_METHODDEF
14074 OS_READV_METHODDEF
14075 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014076 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014077 OS_WRITE_METHODDEF
14078 OS_WRITEV_METHODDEF
14079 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014080 OS_PWRITEV_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014081 OS_SENDFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014082 OS_FSTAT_METHODDEF
14083 OS_ISATTY_METHODDEF
14084 OS_PIPE_METHODDEF
14085 OS_PIPE2_METHODDEF
14086 OS_MKFIFO_METHODDEF
14087 OS_MKNOD_METHODDEF
14088 OS_MAJOR_METHODDEF
14089 OS_MINOR_METHODDEF
14090 OS_MAKEDEV_METHODDEF
14091 OS_FTRUNCATE_METHODDEF
14092 OS_TRUNCATE_METHODDEF
14093 OS_POSIX_FALLOCATE_METHODDEF
14094 OS_POSIX_FADVISE_METHODDEF
14095 OS_PUTENV_METHODDEF
14096 OS_UNSETENV_METHODDEF
14097 OS_STRERROR_METHODDEF
14098 OS_FCHDIR_METHODDEF
14099 OS_FSYNC_METHODDEF
14100 OS_SYNC_METHODDEF
14101 OS_FDATASYNC_METHODDEF
14102 OS_WCOREDUMP_METHODDEF
14103 OS_WIFCONTINUED_METHODDEF
14104 OS_WIFSTOPPED_METHODDEF
14105 OS_WIFSIGNALED_METHODDEF
14106 OS_WIFEXITED_METHODDEF
14107 OS_WEXITSTATUS_METHODDEF
14108 OS_WTERMSIG_METHODDEF
14109 OS_WSTOPSIG_METHODDEF
14110 OS_FSTATVFS_METHODDEF
14111 OS_STATVFS_METHODDEF
14112 OS_CONFSTR_METHODDEF
14113 OS_SYSCONF_METHODDEF
14114 OS_FPATHCONF_METHODDEF
14115 OS_PATHCONF_METHODDEF
14116 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030014117 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014118 OS__GETDISKUSAGE_METHODDEF
14119 OS__GETFINALPATHNAME_METHODDEF
14120 OS__GETVOLUMEPATHNAME_METHODDEF
14121 OS_GETLOADAVG_METHODDEF
14122 OS_URANDOM_METHODDEF
14123 OS_SETRESUID_METHODDEF
14124 OS_SETRESGID_METHODDEF
14125 OS_GETRESUID_METHODDEF
14126 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000014127
Larry Hastings2f936352014-08-05 14:04:04 +100014128 OS_GETXATTR_METHODDEF
14129 OS_SETXATTR_METHODDEF
14130 OS_REMOVEXATTR_METHODDEF
14131 OS_LISTXATTR_METHODDEF
14132
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014133 OS_GET_TERMINAL_SIZE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014134 OS_CPU_COUNT_METHODDEF
14135 OS_GET_INHERITABLE_METHODDEF
14136 OS_SET_INHERITABLE_METHODDEF
14137 OS_GET_HANDLE_INHERITABLE_METHODDEF
14138 OS_SET_HANDLE_INHERITABLE_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014139 OS_GET_BLOCKING_METHODDEF
14140 OS_SET_BLOCKING_METHODDEF
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014141 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070014142 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070014143 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014144 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070014145 OS__ADD_DLL_DIRECTORY_METHODDEF
14146 OS__REMOVE_DLL_DIRECTORY_METHODDEF
Victor Stinner65a796e2020-04-01 18:49:29 +020014147 OS_WAITSTATUS_TO_EXITCODE_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014148 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014149};
14150
Barry Warsaw4a342091996-12-19 23:50:02 +000014151static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014152all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000014153{
Guido van Rossum94f6f721999-01-06 18:42:14 +000014154#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014155 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014156#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014157#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014158 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014159#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014160#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014161 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014162#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014163#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014164 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014165#endif
Fred Drakec9680921999-12-13 16:37:25 +000014166#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014167 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000014168#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014169#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014170 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014171#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014172#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014173 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014174#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014175#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014176 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014177#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014178#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014179 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014180#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014181#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014182 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014183#endif
14184#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014185 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014186#endif
14187#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014188 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014189#endif
14190#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014191 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014192#endif
14193#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014194 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014195#endif
14196#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014197 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014198#endif
14199#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014200 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014201#endif
14202#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014203 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014204#endif
14205#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014206 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014207#endif
14208#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014209 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014210#endif
14211#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014212 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014213#endif
14214#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014215 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014216#endif
14217#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014218 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014219#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014220#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014221 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014222#endif
14223#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014224 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014225#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014226#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014227 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014228#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014229#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014230 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014231#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014232#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014233#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014234 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014235#endif
14236#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014237 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014238#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014239#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014240#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014241 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014242#endif
14243#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014244 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014245#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014246#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014247 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014248#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014249#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014250 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014251#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014252#ifdef O_TMPFILE
14253 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14254#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014255#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014256 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014257#endif
14258#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014259 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014260#endif
14261#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014262 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014263#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014264#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014265 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014266#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014267#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014268 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014269#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014270
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014271
Jesus Cea94363612012-06-22 18:32:07 +020014272#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014273 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014274#endif
14275#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014276 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014277#endif
14278
Tim Peters5aa91602002-01-30 05:46:57 +000014279/* MS Windows */
14280#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014281 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014282 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014283#endif
14284#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000014285 /* Optimize for short life (keep in memory). */
14286 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014287 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014288#endif
14289#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000014290 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014291 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014292#endif
14293#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000014294 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014295 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014296#endif
14297#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014298 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014299 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014300#endif
14301
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014302/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014303#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014304 /* Send a SIGIO signal whenever input or output
14305 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014306 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014307#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014308#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014309 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014310 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014311#endif
14312#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000014313 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014314 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014315#endif
14316#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000014317 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014318 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014319#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014320#ifdef O_NOLINKS
14321 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014322 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014323#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014324#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014325 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014326 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014327#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000014328
Victor Stinner8c62be82010-05-06 00:08:46 +000014329 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014330#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014331 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014332#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014333#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014334 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014335#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014336#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014337 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014338#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014339#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014340 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014341#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014342#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014343 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014344#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014345#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014346 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014347#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014348#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014349 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014350#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014351#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014352 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014353#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014354#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014355 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014356#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014357#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014358 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014359#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014360#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014361 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014362#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014363#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014364 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014365#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014366#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014367 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014368#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014369#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014370 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014371#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014372#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014373 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014374#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014375#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014376 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014377#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014378#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014379 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014380#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014381
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000014382 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014383#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014384 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014385#endif /* ST_RDONLY */
14386#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014387 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014388#endif /* ST_NOSUID */
14389
doko@ubuntu.comca616a22013-12-08 15:23:07 +010014390 /* GNU extensions */
14391#ifdef ST_NODEV
14392 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
14393#endif /* ST_NODEV */
14394#ifdef ST_NOEXEC
14395 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
14396#endif /* ST_NOEXEC */
14397#ifdef ST_SYNCHRONOUS
14398 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
14399#endif /* ST_SYNCHRONOUS */
14400#ifdef ST_MANDLOCK
14401 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
14402#endif /* ST_MANDLOCK */
14403#ifdef ST_WRITE
14404 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
14405#endif /* ST_WRITE */
14406#ifdef ST_APPEND
14407 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
14408#endif /* ST_APPEND */
14409#ifdef ST_NOATIME
14410 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
14411#endif /* ST_NOATIME */
14412#ifdef ST_NODIRATIME
14413 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
14414#endif /* ST_NODIRATIME */
14415#ifdef ST_RELATIME
14416 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
14417#endif /* ST_RELATIME */
14418
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014419 /* FreeBSD sendfile() constants */
14420#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014421 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014422#endif
14423#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014424 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014425#endif
14426#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014427 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014428#endif
14429
Ross Lagerwall7807c352011-03-17 20:20:30 +020014430 /* constants for posix_fadvise */
14431#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014432 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014433#endif
14434#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014435 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014436#endif
14437#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014438 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014439#endif
14440#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014441 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014442#endif
14443#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014444 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014445#endif
14446#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014447 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014448#endif
14449
14450 /* constants for waitid */
14451#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014452 if (PyModule_AddIntMacro(m, P_PID)) return -1;
14453 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
14454 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080014455#ifdef P_PIDFD
14456 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
14457#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014458#endif
14459#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014460 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014461#endif
14462#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014463 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014464#endif
14465#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014466 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014467#endif
14468#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014469 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014470#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014471#ifdef CLD_KILLED
14472 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
14473#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014474#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014475 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014476#endif
14477#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014478 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014479#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014480#ifdef CLD_STOPPED
14481 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
14482#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014483#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014484 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014485#endif
14486
14487 /* constants for lockf */
14488#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014489 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014490#endif
14491#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014492 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014493#endif
14494#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014495 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014496#endif
14497#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014498 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014499#endif
14500
Pablo Galindo4defba32018-01-27 16:16:37 +000014501#ifdef RWF_DSYNC
14502 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14503#endif
14504#ifdef RWF_HIPRI
14505 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14506#endif
14507#ifdef RWF_SYNC
14508 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14509#endif
14510#ifdef RWF_NOWAIT
14511 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14512#endif
YoSTEALTH76ef2552020-05-27 15:32:22 -060014513#ifdef RWF_APPEND
14514 if (PyModule_AddIntConstant(m, "RWF_APPEND", RWF_APPEND)) return -1;
14515#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000014516
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014517/* constants for posix_spawn */
14518#ifdef HAVE_POSIX_SPAWN
14519 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14520 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14521 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14522#endif
14523
pxinwrf2d7ac72019-05-21 18:46:37 +080014524#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014525 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14526 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014527 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014528#endif
14529#ifdef HAVE_SPAWNV
14530 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014531 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014532#endif
14533
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014534#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014535#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014536 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014537#endif
14538#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014539 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014540#endif
14541#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014542 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014543#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014544#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014545 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014546#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014547#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014548 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014549#endif
14550#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014551 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014552#endif
14553#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014554 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014555#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014556#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014557 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014558#endif
14559#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014560 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014561#endif
14562#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014563 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014564#endif
14565#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014566 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014567#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014568#endif
14569
Benjamin Peterson9428d532011-09-14 11:45:52 -040014570#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014571 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
14572 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
14573 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040014574#endif
14575
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014576#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014577 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014578#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014579#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014580 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014581#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014582#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014583 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014584#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014585#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014586 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014587#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014588#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014589 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014590#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014591#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014592 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014593#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014594#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014595 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014596#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010014597#if HAVE_DECL_RTLD_MEMBER
14598 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
14599#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020014600
Victor Stinner9b1f4742016-09-06 16:18:52 -070014601#ifdef HAVE_GETRANDOM_SYSCALL
14602 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
14603 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
14604#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014605#ifdef HAVE_MEMFD_CREATE
14606 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
14607 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
14608#ifdef MFD_HUGETLB
14609 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014610#endif
14611#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014612 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014613#endif
14614#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014615 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014616#endif
14617#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014618 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014619#endif
14620#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014621 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014622#endif
14623#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014624 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014625#endif
14626#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014627 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014628#endif
14629#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014630 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014631#endif
14632#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014633 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014634#endif
14635#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014636 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014637#endif
14638#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014639 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014640#endif
14641#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014642 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014643#endif
14644#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014645 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014646#endif
14647#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014648 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014649#endif
14650#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014651 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
14652#endif
14653#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070014654
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014655#if defined(__APPLE__)
14656 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
14657#endif
14658
Steve Dower2438cdf2019-03-29 16:37:16 -070014659#ifdef MS_WINDOWS
14660 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
14661 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
14662 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
14663 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
14664 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
14665#endif
14666
Victor Stinner8c62be82010-05-06 00:08:46 +000014667 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000014668}
14669
14670
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014671static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014672
14673#ifdef HAVE_FACCESSAT
14674 "HAVE_FACCESSAT",
14675#endif
14676
14677#ifdef HAVE_FCHDIR
14678 "HAVE_FCHDIR",
14679#endif
14680
14681#ifdef HAVE_FCHMOD
14682 "HAVE_FCHMOD",
14683#endif
14684
14685#ifdef HAVE_FCHMODAT
14686 "HAVE_FCHMODAT",
14687#endif
14688
14689#ifdef HAVE_FCHOWN
14690 "HAVE_FCHOWN",
14691#endif
14692
Larry Hastings00964ed2013-08-12 13:49:30 -040014693#ifdef HAVE_FCHOWNAT
14694 "HAVE_FCHOWNAT",
14695#endif
14696
Larry Hastings9cf065c2012-06-22 16:30:09 -070014697#ifdef HAVE_FEXECVE
14698 "HAVE_FEXECVE",
14699#endif
14700
14701#ifdef HAVE_FDOPENDIR
14702 "HAVE_FDOPENDIR",
14703#endif
14704
Georg Brandl306336b2012-06-24 12:55:33 +020014705#ifdef HAVE_FPATHCONF
14706 "HAVE_FPATHCONF",
14707#endif
14708
Larry Hastings9cf065c2012-06-22 16:30:09 -070014709#ifdef HAVE_FSTATAT
14710 "HAVE_FSTATAT",
14711#endif
14712
14713#ifdef HAVE_FSTATVFS
14714 "HAVE_FSTATVFS",
14715#endif
14716
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014717#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014718 "HAVE_FTRUNCATE",
14719#endif
14720
Larry Hastings9cf065c2012-06-22 16:30:09 -070014721#ifdef HAVE_FUTIMENS
14722 "HAVE_FUTIMENS",
14723#endif
14724
14725#ifdef HAVE_FUTIMES
14726 "HAVE_FUTIMES",
14727#endif
14728
14729#ifdef HAVE_FUTIMESAT
14730 "HAVE_FUTIMESAT",
14731#endif
14732
14733#ifdef HAVE_LINKAT
14734 "HAVE_LINKAT",
14735#endif
14736
14737#ifdef HAVE_LCHFLAGS
14738 "HAVE_LCHFLAGS",
14739#endif
14740
14741#ifdef HAVE_LCHMOD
14742 "HAVE_LCHMOD",
14743#endif
14744
14745#ifdef HAVE_LCHOWN
14746 "HAVE_LCHOWN",
14747#endif
14748
14749#ifdef HAVE_LSTAT
14750 "HAVE_LSTAT",
14751#endif
14752
14753#ifdef HAVE_LUTIMES
14754 "HAVE_LUTIMES",
14755#endif
14756
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014757#ifdef HAVE_MEMFD_CREATE
14758 "HAVE_MEMFD_CREATE",
14759#endif
14760
Larry Hastings9cf065c2012-06-22 16:30:09 -070014761#ifdef HAVE_MKDIRAT
14762 "HAVE_MKDIRAT",
14763#endif
14764
14765#ifdef HAVE_MKFIFOAT
14766 "HAVE_MKFIFOAT",
14767#endif
14768
14769#ifdef HAVE_MKNODAT
14770 "HAVE_MKNODAT",
14771#endif
14772
14773#ifdef HAVE_OPENAT
14774 "HAVE_OPENAT",
14775#endif
14776
14777#ifdef HAVE_READLINKAT
14778 "HAVE_READLINKAT",
14779#endif
14780
14781#ifdef HAVE_RENAMEAT
14782 "HAVE_RENAMEAT",
14783#endif
14784
14785#ifdef HAVE_SYMLINKAT
14786 "HAVE_SYMLINKAT",
14787#endif
14788
14789#ifdef HAVE_UNLINKAT
14790 "HAVE_UNLINKAT",
14791#endif
14792
14793#ifdef HAVE_UTIMENSAT
14794 "HAVE_UTIMENSAT",
14795#endif
14796
14797#ifdef MS_WINDOWS
14798 "MS_WINDOWS",
14799#endif
14800
14801 NULL
14802};
14803
14804
Victor Stinner1c2fa782020-05-10 11:05:29 +020014805static int
14806posixmodule_exec(PyObject *m)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014807{
Victor Stinner97f33c32020-05-14 18:05:58 +020014808 _posixstate *state = get_posix_state(m);
Tim Peters5aa91602002-01-30 05:46:57 +000014809
Victor Stinner8c62be82010-05-06 00:08:46 +000014810 /* Initialize environ dictionary */
Victor Stinner97f33c32020-05-14 18:05:58 +020014811 PyObject *v = convertenviron();
Victor Stinner8c62be82010-05-06 00:08:46 +000014812 Py_XINCREF(v);
14813 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014814 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014815 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014816
Victor Stinner8c62be82010-05-06 00:08:46 +000014817 if (all_ins(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020014818 return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014819
Victor Stinner8c62be82010-05-06 00:08:46 +000014820 if (setup_confname_tables(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020014821 return -1;
Fred Drakebec628d1999-12-15 18:31:10 +000014822
Victor Stinner8c62be82010-05-06 00:08:46 +000014823 Py_INCREF(PyExc_OSError);
14824 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014825
Ross Lagerwall7807c352011-03-17 20:20:30 +020014826#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080014827 waitid_result_desc.name = MODNAME ".waitid_result";
14828 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
14829 if (WaitidResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014830 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014831 }
14832 Py_INCREF(WaitidResultType);
14833 PyModule_AddObject(m, "waitid_result", WaitidResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014834 state->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014835#endif
14836
Eddie Elizondob3966632019-11-05 07:16:14 -080014837 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
14838 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14839 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14840 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
14841 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
14842 if (StatResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014843 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014844 }
14845 Py_INCREF(StatResultType);
14846 PyModule_AddObject(m, "stat_result", StatResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014847 state->StatResultType = StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014848 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
14849 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014850
Eddie Elizondob3966632019-11-05 07:16:14 -080014851 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
14852 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
14853 if (StatVFSResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014854 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014855 }
14856 Py_INCREF(StatVFSResultType);
14857 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014858 state->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014859#ifdef NEED_TICKS_PER_SECOND
14860# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080014861 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014862# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080014863 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014864# else
Eddie Elizondob3966632019-11-05 07:16:14 -080014865 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014866# endif
14867#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014868
William Orr81574b82018-10-01 22:19:56 -070014869#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080014870 sched_param_desc.name = MODNAME ".sched_param";
14871 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
14872 if (SchedParamType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014873 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014874 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014875 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080014876 PyModule_AddObject(m, "sched_param", SchedParamType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014877 state->SchedParamType = SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014878 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014879#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014880
Eddie Elizondob3966632019-11-05 07:16:14 -080014881 /* initialize TerminalSize_info */
14882 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
14883 if (TerminalSizeType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014884 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014885 }
14886 Py_INCREF(TerminalSizeType);
14887 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014888 state->TerminalSizeType = TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014889
14890 /* initialize scandir types */
Victor Stinner1c2fa782020-05-10 11:05:29 +020014891 PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080014892 if (ScandirIteratorType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014893 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014894 }
Victor Stinner97f33c32020-05-14 18:05:58 +020014895 state->ScandirIteratorType = ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014896
Victor Stinner1c2fa782020-05-10 11:05:29 +020014897 PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080014898 if (DirEntryType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014899 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014900 }
14901 Py_INCREF(DirEntryType);
14902 PyModule_AddObject(m, "DirEntry", DirEntryType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014903 state->DirEntryType = DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014904
Larry Hastings605a62d2012-06-24 04:33:36 -070014905 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080014906 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014907 if (TimesResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014908 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014909 }
Eddie Elizondob3966632019-11-05 07:16:14 -080014910 Py_INCREF(TimesResultType);
14911 PyModule_AddObject(m, "times_result", TimesResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014912 state->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070014913
Eddie Elizondob3966632019-11-05 07:16:14 -080014914 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014915 if (UnameResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014916 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014917 }
Eddie Elizondob3966632019-11-05 07:16:14 -080014918 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014919 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014920 state->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070014921
Thomas Wouters477c8d52006-05-27 19:21:47 +000014922#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014923 /*
14924 * Step 2 of weak-linking support on Mac OS X.
14925 *
14926 * The code below removes functions that are not available on the
14927 * currently active platform.
14928 *
14929 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014930 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014931 * OSX 10.4.
14932 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014933#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014934 if (fstatvfs == NULL) {
14935 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014936 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014937 }
14938 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014939#endif /* HAVE_FSTATVFS */
14940
14941#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014942 if (statvfs == NULL) {
14943 if (PyObject_DelAttrString(m, "statvfs") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014944 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014945 }
14946 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014947#endif /* HAVE_STATVFS */
14948
14949# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014950 if (lchown == NULL) {
14951 if (PyObject_DelAttrString(m, "lchown") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014952 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014953 }
14954 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014955#endif /* HAVE_LCHOWN */
14956
14957
14958#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014959
Victor Stinner97f33c32020-05-14 18:05:58 +020014960 if ((state->billion = PyLong_FromLong(1000000000)) == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014961 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014962#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +020014963 state->struct_rusage = PyUnicode_InternFromString("struct_rusage");
14964 if (state->struct_rusage == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014965 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014966#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020014967 state->st_mode = PyUnicode_InternFromString("st_mode");
14968 if (state->st_mode == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014969 return -1;
Larry Hastings6fe20b32012-04-19 15:07:49 -070014970
Larry Hastings9cf065c2012-06-22 16:30:09 -070014971 /* suppress "function not used" warnings */
14972 {
14973 int ignored;
14974 fd_specified("", -1);
14975 follow_symlinks_specified("", 1);
14976 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14977 dir_fd_converter(Py_None, &ignored);
14978 dir_fd_unavailable(Py_None, &ignored);
14979 }
14980
14981 /*
14982 * provide list of locally available functions
14983 * so os.py can populate support_* lists
14984 */
Victor Stinner97f33c32020-05-14 18:05:58 +020014985 PyObject *list = PyList_New(0);
14986 if (!list) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014987 return -1;
Victor Stinner97f33c32020-05-14 18:05:58 +020014988 }
14989 for (const char * const *trace = have_functions; *trace; trace++) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014990 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14991 if (!unicode)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014992 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014993 if (PyList_Append(list, unicode))
Victor Stinner1c2fa782020-05-10 11:05:29 +020014994 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014995 Py_DECREF(unicode);
14996 }
14997 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014998
Victor Stinner1c2fa782020-05-10 11:05:29 +020014999 return 0;
15000}
15001
15002
15003static PyModuleDef_Slot posixmodile_slots[] = {
15004 {Py_mod_exec, posixmodule_exec},
15005 {0, NULL}
15006};
15007
15008static struct PyModuleDef posixmodule = {
15009 PyModuleDef_HEAD_INIT,
15010 .m_name = MODNAME,
15011 .m_doc = posix__doc__,
15012 .m_size = sizeof(_posixstate),
15013 .m_methods = posix_methods,
15014 .m_slots = posixmodile_slots,
15015 .m_traverse = _posix_traverse,
15016 .m_clear = _posix_clear,
15017 .m_free = _posix_free,
15018};
15019
15020PyMODINIT_FUNC
15021INITFUNC(void)
15022{
15023 return PyModuleDef_Init(&posixmodule);
Guido van Rossumb6775db1994-08-01 11:34:53 +000015024}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015025
15026#ifdef __cplusplus
15027}
15028#endif