blob: 203f98515dfdad36af489eebbc7689723ac2a5b1 [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"
Kyle Evans79925792020-10-13 15:04:44 -050025#include "pycore_fileutils.h"
Victor Stinnerd5d9e812019-05-13 12:35:37 +020026#ifdef MS_WINDOWS
27 /* include <windows.h> early to avoid conflict with pycore_condvar.h:
28
29 #define WIN32_LEAN_AND_MEAN
30 #include <windows.h>
31
32 FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */
33# include <windows.h>
34#endif
35
pxinwr3405e052020-08-07 13:21:52 +080036#ifdef __VXWORKS__
37# include "pycore_bitutils.h" // _Py_popcount32()
38#endif
Victor Stinner4a21e572020-04-15 02:35:41 +020039#include "pycore_ceval.h" // _PyEval_ReInitThreads()
40#include "pycore_import.h" // _PyImport_ReInitLock()
Victor Stinner26881c82020-06-02 15:51:37 +020041#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
Victor Stinner4a21e572020-04-15 02:35:41 +020042#include "pycore_pystate.h" // _PyInterpreterState_GET()
43#include "structmember.h" // PyMemberDef
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020044#ifndef MS_WINDOWS
Victor Stinnerd5d9e812019-05-13 12:35:37 +020045# include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010046#else
Victor Stinnerd5d9e812019-05-13 12:35:37 +020047# include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020048#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000049
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020050/* On android API level 21, 'AT_EACCESS' is not declared although
51 * HAVE_FACCESSAT is defined. */
52#ifdef __ANDROID__
Victor Stinner5eca75d2020-04-15 15:07:31 +020053# undef HAVE_FACCESSAT
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020054#endif
55
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000056#include <stdio.h> /* needed for ctermid() */
57
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000058#ifdef __cplusplus
59extern "C" {
60#endif
61
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000062PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000063"This module provides access to operating system functionality that is\n\
64standardized by the C Standard and the POSIX standard (a thinly\n\
65disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000066corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000068
Ross Lagerwall4d076da2011-03-18 06:56:53 +020069#ifdef HAVE_SYS_UIO_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020070# include <sys/uio.h>
Ross Lagerwall4d076da2011-03-18 06:56:53 +020071#endif
72
Christian Heimes75b96182017-09-05 15:53:09 +020073#ifdef HAVE_SYS_SYSMACROS_H
74/* GNU C Library: major(), minor(), makedev() */
Victor Stinner5eca75d2020-04-15 15:07:31 +020075# include <sys/sysmacros.h>
Christian Heimes75b96182017-09-05 15:53:09 +020076#endif
77
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#ifdef HAVE_SYS_TYPES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020079# include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000080#endif /* HAVE_SYS_TYPES_H */
81
82#ifdef HAVE_SYS_STAT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020083# include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000084#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000085
Guido van Rossum36bc6801995-06-14 22:54:23 +000086#ifdef HAVE_SYS_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020087# include <sys/wait.h> // WNOHANG
Guido van Rossum36bc6801995-06-14 22:54:23 +000088#endif
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080089#ifdef HAVE_LINUX_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020090# include <linux/wait.h> // P_PIDFD
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080091#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000092
Thomas Wouters0e3f5912006-08-11 14:57:12 +000093#ifdef HAVE_SIGNAL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020094# include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000095#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000096
Guido van Rossumb6775db1994-08-01 11:34:53 +000097#ifdef HAVE_FCNTL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020098# include <fcntl.h>
99#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000100
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000101#ifdef HAVE_GRP_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200102# include <grp.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000103#endif
104
Barry Warsaw5676bd12003-01-07 20:57:09 +0000105#ifdef HAVE_SYSEXITS_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200106# include <sysexits.h>
107#endif
Barry Warsaw5676bd12003-01-07 20:57:09 +0000108
Anthony Baxter8a560de2004-10-13 15:30:56 +0000109#ifdef HAVE_SYS_LOADAVG_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200110# include <sys/loadavg.h>
Anthony Baxter8a560de2004-10-13 15:30:56 +0000111#endif
112
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000113#ifdef HAVE_SYS_SENDFILE_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200114# include <sys/sendfile.h>
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000115#endif
116
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200117#if defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200118# include <copyfile.h>
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200119#endif
120
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500121#ifdef HAVE_SCHED_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200122# include <sched.h>
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500123#endif
124
Pablo Galindoaac4d032019-05-31 19:39:47 +0100125#ifdef HAVE_COPY_FILE_RANGE
Victor Stinner5eca75d2020-04-15 15:07:31 +0200126# include <unistd.h>
Pablo Galindoaac4d032019-05-31 19:39:47 +0100127#endif
128
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500129#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200130# undef HAVE_SCHED_SETAFFINITY
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500131#endif
132
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200133#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200134# define USE_XATTRS
Benjamin Peterson9428d532011-09-14 11:45:52 -0400135#endif
136
137#ifdef USE_XATTRS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200138# include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400139#endif
140
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000141#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200142# ifdef HAVE_SYS_SOCKET_H
143# include <sys/socket.h>
144# endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000145#endif
146
Victor Stinner8b905bd2011-10-25 13:34:04 +0200147#ifdef HAVE_DLFCN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200148# include <dlfcn.h>
Victor Stinner8b905bd2011-10-25 13:34:04 +0200149#endif
150
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200151#ifdef __hpux
Victor Stinner5eca75d2020-04-15 15:07:31 +0200152# include <sys/mpctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200153#endif
154
155#if defined(__DragonFly__) || \
156 defined(__OpenBSD__) || \
157 defined(__FreeBSD__) || \
158 defined(__NetBSD__) || \
159 defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200160# include <sys/sysctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200161#endif
162
Victor Stinner9b1f4742016-09-06 16:18:52 -0700163#ifdef HAVE_LINUX_RANDOM_H
164# include <linux/random.h>
165#endif
166#ifdef HAVE_GETRANDOM_SYSCALL
167# include <sys/syscall.h>
168#endif
169
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100170#if defined(MS_WINDOWS)
171# define TERMSIZE_USE_CONIO
172#elif defined(HAVE_SYS_IOCTL_H)
173# include <sys/ioctl.h>
174# if defined(HAVE_TERMIOS_H)
175# include <termios.h>
176# endif
177# if defined(TIOCGWINSZ)
178# define TERMSIZE_USE_IOCTL
179# endif
180#endif /* MS_WINDOWS */
181
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000183/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000184#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200185# define HAVE_OPENDIR 1
186# define HAVE_SYSTEM 1
187# include <process.h>
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200189# ifdef _MSC_VER
190 /* Microsoft compiler */
191# define HAVE_GETPPID 1
192# define HAVE_GETLOGIN 1
193# define HAVE_SPAWNV 1
194# define HAVE_EXECV 1
195# define HAVE_WSPAWNV 1
196# define HAVE_WEXECV 1
197# define HAVE_PIPE 1
198# define HAVE_SYSTEM 1
199# define HAVE_CWAIT 1
200# define HAVE_FSYNC 1
201# define fsync _commit
202# else
203 /* Unix functions that the configure script doesn't check for */
204# ifndef __VXWORKS__
205# define HAVE_EXECV 1
206# define HAVE_FORK 1
207# if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
208# define HAVE_FORK1 1
209# endif
210# endif
211# define HAVE_GETEGID 1
212# define HAVE_GETEUID 1
213# define HAVE_GETGID 1
214# define HAVE_GETPPID 1
215# define HAVE_GETUID 1
216# define HAVE_KILL 1
217# define HAVE_OPENDIR 1
218# define HAVE_PIPE 1
219# define HAVE_SYSTEM 1
220# define HAVE_WAIT 1
221# define HAVE_TTYNAME 1
222# endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000223#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000224
Eddie Elizondob3966632019-11-05 07:16:14 -0800225_Py_IDENTIFIER(__fspath__);
Victor Stinnera2f7c002012-02-08 03:36:25 +0100226
Larry Hastings61272b72014-01-07 12:41:53 -0800227/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000228# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800229module os
Larry Hastings61272b72014-01-07 12:41:53 -0800230[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000231/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100232
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000233#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000234
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000235#if defined(__sgi)&&_COMPILER_VERSION>=700
236/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
237 (default) */
238extern char *ctermid_r(char *);
239#endif
240
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000241#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000242
pxinwrf2d7ac72019-05-21 18:46:37 +0800243#if defined(__VXWORKS__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200244# include <vxCpuLib.h>
245# include <rtpLib.h>
246# include <wait.h>
247# include <taskLib.h>
248# ifndef _P_WAIT
249# define _P_WAIT 0
250# define _P_NOWAIT 1
251# define _P_NOWAITO 1
252# endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800253#endif /* __VXWORKS__ */
254
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000255#ifdef HAVE_POSIX_SPAWN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200256# include <spawn.h>
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000257#endif
258
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259#ifdef HAVE_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200260# include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000261#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000263#ifdef HAVE_SYS_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200264# include <sys/utime.h>
265# define HAVE_UTIME_H /* pretend we do for the rest of this file */
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000266#endif /* HAVE_SYS_UTIME_H */
267
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268#ifdef HAVE_SYS_TIMES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200269# include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000270#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271
272#ifdef HAVE_SYS_PARAM_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200273# include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000274#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275
276#ifdef HAVE_SYS_UTSNAME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200277# include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000278#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#ifdef HAVE_DIRENT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200281# include <dirent.h>
282# define NAMLEN(dirent) strlen((dirent)->d_name)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200284# if defined(__WATCOMC__) && !defined(__QNX__)
285# include <direct.h>
286# define NAMLEN(dirent) strlen((dirent)->d_name)
287# else
288# define dirent direct
289# define NAMLEN(dirent) (dirent)->d_namlen
290# endif
291# ifdef HAVE_SYS_NDIR_H
292# include <sys/ndir.h>
293# endif
294# ifdef HAVE_SYS_DIR_H
295# include <sys/dir.h>
296# endif
297# ifdef HAVE_NDIR_H
298# include <ndir.h>
299# endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000300#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000302#ifdef _MSC_VER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200303# ifdef HAVE_DIRECT_H
304# include <direct.h>
305# endif
306# ifdef HAVE_IO_H
307# include <io.h>
308# endif
309# ifdef HAVE_PROCESS_H
310# include <process.h>
311# endif
312# ifndef IO_REPARSE_TAG_SYMLINK
313# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
314# endif
315# ifndef IO_REPARSE_TAG_MOUNT_POINT
316# define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
317# endif
318# include "osdefs.h" // SEP
319# include <malloc.h>
320# include <windows.h>
321# include <shellapi.h> // ShellExecute()
322# include <lmcons.h> // UNLEN
323# define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000324#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000325
Tim Petersbc2e10e2002-03-03 23:17:02 +0000326#ifndef MAXPATHLEN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200327# if defined(PATH_MAX) && PATH_MAX > 1024
328# define MAXPATHLEN PATH_MAX
329# else
330# define MAXPATHLEN 1024
331# endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000332#endif /* MAXPATHLEN */
333
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000334#ifdef UNION_WAIT
Victor Stinner5eca75d2020-04-15 15:07:31 +0200335 /* Emulate some macros on systems that have a union instead of macros */
336# ifndef WIFEXITED
337# define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
338# endif
339# ifndef WEXITSTATUS
340# define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
341# endif
342# ifndef WTERMSIG
343# define WTERMSIG(u_wait) ((u_wait).w_termsig)
344# endif
345# define WAIT_TYPE union wait
346# define WAIT_STATUS_INT(s) (s.w_status)
347#else
348 /* !UNION_WAIT */
349# define WAIT_TYPE int
350# define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000351#endif /* UNION_WAIT */
352
Greg Wardb48bc172000-03-01 21:51:56 +0000353/* Don't use the "_r" form if we don't need it (also, won't have a
354 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200355#if defined(HAVE_CTERMID_R)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200356# define USE_CTERMID_R
Greg Wardb48bc172000-03-01 21:51:56 +0000357#endif
358
Fred Drake699f3522000-06-29 21:12:41 +0000359/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000360#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000361#undef FSTAT
362#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200363#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200364# define STAT win32_stat
365# define LSTAT win32_lstat
366# define FSTAT _Py_fstat_noraise
367# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000368#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200369# define STAT stat
370# define LSTAT lstat
371# define FSTAT fstat
372# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000373#endif
374
Tim Peters11b23062003-04-23 02:39:17 +0000375#if defined(MAJOR_IN_MKDEV)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200376# include <sys/mkdev.h>
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000377#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200378# if defined(MAJOR_IN_SYSMACROS)
379# include <sys/sysmacros.h>
380# endif
381# if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
382# include <sys/mkdev.h>
383# endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000384#endif
Fred Drake699f3522000-06-29 21:12:41 +0000385
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200386#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200387# define INITFUNC PyInit_nt
388# define MODNAME "nt"
Victor Stinner6036e442015-03-08 01:58:04 +0100389#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200390# define INITFUNC PyInit_posix
391# define MODNAME "posix"
Victor Stinner6036e442015-03-08 01:58:04 +0100392#endif
393
jcea6c51d512018-01-28 14:00:08 +0100394#if defined(__sun)
395/* Something to implement in autoconf, not present in autoconf 2.69 */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200396# define HAVE_STRUCT_STAT_ST_FSTYPE 1
jcea6c51d512018-01-28 14:00:08 +0100397#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200398
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600399/* memfd_create is either defined in sys/mman.h or sys/memfd.h
400 * linux/memfd.h defines additional flags
401 */
402#ifdef HAVE_SYS_MMAN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200403# include <sys/mman.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600404#endif
405#ifdef HAVE_SYS_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200406# include <sys/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600407#endif
408#ifdef HAVE_LINUX_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200409# include <linux/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600410#endif
411
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800412#ifdef _Py_MEMORY_SANITIZER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200413# include <sanitizer/msan_interface.h>
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800414#endif
415
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200416#ifdef HAVE_FORK
417static void
418run_at_forkers(PyObject *lst, int reverse)
419{
420 Py_ssize_t i;
421 PyObject *cpy;
422
423 if (lst != NULL) {
424 assert(PyList_CheckExact(lst));
425
426 /* Use a list copy in case register_at_fork() is called from
427 * one of the callbacks.
428 */
429 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
430 if (cpy == NULL)
431 PyErr_WriteUnraisable(lst);
432 else {
433 if (reverse)
434 PyList_Reverse(cpy);
435 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
436 PyObject *func, *res;
437 func = PyList_GET_ITEM(cpy, i);
Jeroen Demeyer7f41c8e2019-07-04 12:35:31 +0200438 res = _PyObject_CallNoArg(func);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200439 if (res == NULL)
440 PyErr_WriteUnraisable(func);
441 else
442 Py_DECREF(res);
443 }
444 Py_DECREF(cpy);
445 }
446 }
447}
448
449void
450PyOS_BeforeFork(void)
451{
Victor Stinner81a7be32020-04-14 15:14:01 +0200452 run_at_forkers(_PyInterpreterState_GET()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200453
454 _PyImport_AcquireLock();
455}
456
457void
458PyOS_AfterFork_Parent(void)
459{
460 if (_PyImport_ReleaseLock() <= 0)
461 Py_FatalError("failed releasing import lock after fork");
462
Victor Stinner81a7be32020-04-14 15:14:01 +0200463 run_at_forkers(_PyInterpreterState_GET()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200464}
465
466void
467PyOS_AfterFork_Child(void)
468{
Victor Stinner26881c82020-06-02 15:51:37 +0200469 PyStatus status;
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200470 _PyRuntimeState *runtime = &_PyRuntime;
Victor Stinner26881c82020-06-02 15:51:37 +0200471
472 status = _PyGILState_Reinit(runtime);
473 if (_PyStatus_EXCEPTION(status)) {
474 goto fatal_error;
475 }
476
Victor Stinner317bab02020-06-02 18:44:54 +0200477 PyThreadState *tstate = _PyThreadState_GET();
478 _Py_EnsureTstateNotNULL(tstate);
479
480 status = _PyEval_ReInitThreads(tstate);
Victor Stinner26881c82020-06-02 15:51:37 +0200481 if (_PyStatus_EXCEPTION(status)) {
482 goto fatal_error;
483 }
484
485 status = _PyImport_ReInitLock();
486 if (_PyStatus_EXCEPTION(status)) {
487 goto fatal_error;
488 }
489
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200490 _PySignal_AfterFork();
Victor Stinner26881c82020-06-02 15:51:37 +0200491
492 status = _PyRuntimeState_ReInitThreads(runtime);
493 if (_PyStatus_EXCEPTION(status)) {
494 goto fatal_error;
495 }
496
497 status = _PyInterpreterState_DeleteExceptMain(runtime);
498 if (_PyStatus_EXCEPTION(status)) {
499 goto fatal_error;
500 }
Victor Stinner317bab02020-06-02 18:44:54 +0200501 assert(_PyThreadState_GET() == tstate);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200502
Victor Stinner317bab02020-06-02 18:44:54 +0200503 run_at_forkers(tstate->interp->after_forkers_child, 0);
Victor Stinner26881c82020-06-02 15:51:37 +0200504 return;
505
506fatal_error:
507 Py_ExitStatusException(status);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200508}
509
510static int
511register_at_forker(PyObject **lst, PyObject *func)
512{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700513 if (func == NULL) /* nothing to register? do nothing. */
514 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200515 if (*lst == NULL) {
516 *lst = PyList_New(0);
517 if (*lst == NULL)
518 return -1;
519 }
520 return PyList_Append(*lst, func);
521}
Victor Stinner87255be2020-04-07 23:11:49 +0200522#endif /* HAVE_FORK */
523
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200524
525/* Legacy wrapper */
526void
527PyOS_AfterFork(void)
528{
529#ifdef HAVE_FORK
530 PyOS_AfterFork_Child();
531#endif
532}
533
534
Victor Stinner6036e442015-03-08 01:58:04 +0100535#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200536/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700537void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
538void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200539 ULONG, struct _Py_stat_struct *);
540#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700541
Larry Hastings9cf065c2012-06-22 16:30:09 -0700542
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200543#ifndef MS_WINDOWS
544PyObject *
545_PyLong_FromUid(uid_t uid)
546{
547 if (uid == (uid_t)-1)
548 return PyLong_FromLong(-1);
549 return PyLong_FromUnsignedLong(uid);
550}
551
552PyObject *
553_PyLong_FromGid(gid_t gid)
554{
555 if (gid == (gid_t)-1)
556 return PyLong_FromLong(-1);
557 return PyLong_FromUnsignedLong(gid);
558}
559
560int
561_Py_Uid_Converter(PyObject *obj, void *p)
562{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700563 uid_t uid;
564 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200565 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200566 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700567 unsigned long uresult;
568
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300569 index = _PyNumber_Index(obj);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700570 if (index == NULL) {
571 PyErr_Format(PyExc_TypeError,
572 "uid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800573 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200574 return 0;
575 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700576
577 /*
578 * Handling uid_t is complicated for two reasons:
579 * * Although uid_t is (always?) unsigned, it still
580 * accepts -1.
581 * * We don't know its size in advance--it may be
582 * bigger than an int, or it may be smaller than
583 * a long.
584 *
585 * So a bit of defensive programming is in order.
586 * Start with interpreting the value passed
587 * in as a signed long and see if it works.
588 */
589
590 result = PyLong_AsLongAndOverflow(index, &overflow);
591
592 if (!overflow) {
593 uid = (uid_t)result;
594
595 if (result == -1) {
596 if (PyErr_Occurred())
597 goto fail;
598 /* It's a legitimate -1, we're done. */
599 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200600 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700601
602 /* Any other negative number is disallowed. */
603 if (result < 0)
604 goto underflow;
605
606 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200607 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700608 (long)uid != result)
609 goto underflow;
610 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200611 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700612
613 if (overflow < 0)
614 goto underflow;
615
616 /*
617 * Okay, the value overflowed a signed long. If it
618 * fits in an *unsigned* long, it may still be okay,
619 * as uid_t may be unsigned long on this platform.
620 */
621 uresult = PyLong_AsUnsignedLong(index);
622 if (PyErr_Occurred()) {
623 if (PyErr_ExceptionMatches(PyExc_OverflowError))
624 goto overflow;
625 goto fail;
626 }
627
628 uid = (uid_t)uresult;
629
630 /*
631 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
632 * but this value would get interpreted as (uid_t)-1 by chown
633 * and its siblings. That's not what the user meant! So we
634 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100635 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700636 */
637 if (uid == (uid_t)-1)
638 goto overflow;
639
640 /* Ensure the value wasn't truncated. */
641 if (sizeof(uid_t) < sizeof(long) &&
642 (unsigned long)uid != uresult)
643 goto overflow;
644 /* fallthrough */
645
646success:
647 Py_DECREF(index);
648 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200649 return 1;
650
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700651underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200652 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700653 "uid is less than minimum");
654 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200655
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700656overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200657 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700658 "uid is greater than maximum");
659 /* fallthrough */
660
661fail:
662 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200663 return 0;
664}
665
666int
667_Py_Gid_Converter(PyObject *obj, void *p)
668{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700669 gid_t gid;
670 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200671 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200672 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700673 unsigned long uresult;
674
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300675 index = _PyNumber_Index(obj);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700676 if (index == NULL) {
677 PyErr_Format(PyExc_TypeError,
678 "gid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800679 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200680 return 0;
681 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700682
683 /*
684 * Handling gid_t is complicated for two reasons:
685 * * Although gid_t is (always?) unsigned, it still
686 * accepts -1.
687 * * We don't know its size in advance--it may be
688 * bigger than an int, or it may be smaller than
689 * a long.
690 *
691 * So a bit of defensive programming is in order.
692 * Start with interpreting the value passed
693 * in as a signed long and see if it works.
694 */
695
696 result = PyLong_AsLongAndOverflow(index, &overflow);
697
698 if (!overflow) {
699 gid = (gid_t)result;
700
701 if (result == -1) {
702 if (PyErr_Occurred())
703 goto fail;
704 /* It's a legitimate -1, we're done. */
705 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200706 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700707
708 /* Any other negative number is disallowed. */
709 if (result < 0) {
710 goto underflow;
711 }
712
713 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200714 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700715 (long)gid != result)
716 goto underflow;
717 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200718 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700719
720 if (overflow < 0)
721 goto underflow;
722
723 /*
724 * Okay, the value overflowed a signed long. If it
725 * fits in an *unsigned* long, it may still be okay,
726 * as gid_t may be unsigned long on this platform.
727 */
728 uresult = PyLong_AsUnsignedLong(index);
729 if (PyErr_Occurred()) {
730 if (PyErr_ExceptionMatches(PyExc_OverflowError))
731 goto overflow;
732 goto fail;
733 }
734
735 gid = (gid_t)uresult;
736
737 /*
738 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
739 * but this value would get interpreted as (gid_t)-1 by chown
740 * and its siblings. That's not what the user meant! So we
741 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100742 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700743 */
744 if (gid == (gid_t)-1)
745 goto overflow;
746
747 /* Ensure the value wasn't truncated. */
748 if (sizeof(gid_t) < sizeof(long) &&
749 (unsigned long)gid != uresult)
750 goto overflow;
751 /* fallthrough */
752
753success:
754 Py_DECREF(index);
755 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200756 return 1;
757
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700758underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200759 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700760 "gid is less than minimum");
761 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200762
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700763overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200764 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700765 "gid is greater than maximum");
766 /* fallthrough */
767
768fail:
769 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200770 return 0;
771}
772#endif /* MS_WINDOWS */
773
774
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700775#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800776
777
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200778#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
779static int
780_Py_Dev_Converter(PyObject *obj, void *p)
781{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200782 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200783 if (PyErr_Occurred())
784 return 0;
785 return 1;
786}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800787#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200788
789
Larry Hastings9cf065c2012-06-22 16:30:09 -0700790#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400791/*
792 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
793 * without the int cast, the value gets interpreted as uint (4291925331),
794 * which doesn't play nicely with all the initializer lines in this file that
795 * look like this:
796 * int dir_fd = DEFAULT_DIR_FD;
797 */
798#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700799#else
800#define DEFAULT_DIR_FD (-100)
801#endif
802
803static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300804_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200805{
806 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700807 long long_value;
808
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300809 PyObject *index = _PyNumber_Index(o);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700810 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700811 return 0;
812 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700813
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300814 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700815 long_value = PyLong_AsLongAndOverflow(index, &overflow);
816 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300817 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200818 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700819 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700820 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700821 return 0;
822 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200823 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700824 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700825 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700826 return 0;
827 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700828
Larry Hastings9cf065c2012-06-22 16:30:09 -0700829 *p = (int)long_value;
830 return 1;
831}
832
833static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200834dir_fd_converter(PyObject *o, void *p)
835{
836 if (o == Py_None) {
837 *(int *)p = DEFAULT_DIR_FD;
838 return 1;
839 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300840 else if (PyIndex_Check(o)) {
841 return _fd_converter(o, (int *)p);
842 }
843 else {
844 PyErr_Format(PyExc_TypeError,
845 "argument should be integer or None, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800846 _PyType_Name(Py_TYPE(o)));
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300847 return 0;
848 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700849}
850
Eddie Elizondob3966632019-11-05 07:16:14 -0800851typedef struct {
852 PyObject *billion;
Eddie Elizondob3966632019-11-05 07:16:14 -0800853 PyObject *DirEntryType;
854 PyObject *ScandirIteratorType;
855#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
856 PyObject *SchedParamType;
857#endif
858 PyObject *StatResultType;
859 PyObject *StatVFSResultType;
860 PyObject *TerminalSizeType;
861 PyObject *TimesResultType;
862 PyObject *UnameResultType;
863#if defined(HAVE_WAITID) && !defined(__APPLE__)
864 PyObject *WaitidResultType;
865#endif
866#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
867 PyObject *struct_rusage;
868#endif
869 PyObject *st_mode;
870} _posixstate;
871
Eddie Elizondob3966632019-11-05 07:16:14 -0800872
Hai Shif707d942020-03-16 21:15:01 +0800873static inline _posixstate*
874get_posix_state(PyObject *module)
875{
876 void *state = PyModule_GetState(module);
877 assert(state != NULL);
878 return (_posixstate *)state;
879}
880
Larry Hastings9cf065c2012-06-22 16:30:09 -0700881/*
882 * A PyArg_ParseTuple "converter" function
883 * that handles filesystem paths in the manner
884 * preferred by the os module.
885 *
886 * path_converter accepts (Unicode) strings and their
887 * subclasses, and bytes and their subclasses. What
888 * it does with the argument depends on the platform:
889 *
890 * * On Windows, if we get a (Unicode) string we
891 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700892 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700893 *
894 * * On all other platforms, strings are encoded
895 * to bytes using PyUnicode_FSConverter, then we
896 * extract the char * from the bytes object and
897 * return that.
898 *
899 * path_converter also optionally accepts signed
900 * integers (representing open file descriptors) instead
901 * of path strings.
902 *
903 * Input fields:
904 * path.nullable
905 * If nonzero, the path is permitted to be None.
906 * path.allow_fd
907 * If nonzero, the path is permitted to be a file handle
908 * (a signed int) instead of a string.
909 * path.function_name
910 * If non-NULL, path_converter will use that as the name
911 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700912 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700913 * path.argument_name
914 * If non-NULL, path_converter will use that as the name
915 * of the parameter in error messages.
916 * (If path.argument_name is NULL it uses "path".)
917 *
918 * Output fields:
919 * path.wide
920 * Points to the path if it was expressed as Unicode
921 * and was not encoded. (Only used on Windows.)
922 * path.narrow
923 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700924 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000925 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700926 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700927 * path.fd
928 * Contains a file descriptor if path.accept_fd was true
929 * and the caller provided a signed integer instead of any
930 * sort of string.
931 *
932 * WARNING: if your "path" parameter is optional, and is
933 * unspecified, path_converter will never get called.
934 * So if you set allow_fd, you *MUST* initialize path.fd = -1
935 * yourself!
936 * path.length
937 * The length of the path in characters, if specified as
938 * a string.
939 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800940 * The original object passed in (if get a PathLike object,
941 * the result of PyOS_FSPath() is treated as the original object).
942 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943 * path.cleanup
944 * For internal use only. May point to a temporary object.
945 * (Pay no attention to the man behind the curtain.)
946 *
947 * At most one of path.wide or path.narrow will be non-NULL.
948 * If path was None and path.nullable was set,
949 * or if path was an integer and path.allow_fd was set,
950 * both path.wide and path.narrow will be NULL
951 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200952 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700953 * path_converter takes care to not write to the path_t
954 * unless it's successful. However it must reset the
955 * "cleanup" field each time it's called.
956 *
957 * Use as follows:
958 * path_t path;
959 * memset(&path, 0, sizeof(path));
960 * PyArg_ParseTuple(args, "O&", path_converter, &path);
961 * // ... use values from path ...
962 * path_cleanup(&path);
963 *
964 * (Note that if PyArg_Parse fails you don't need to call
965 * path_cleanup(). However it is safe to do so.)
966 */
967typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100968 const char *function_name;
969 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700970 int nullable;
971 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300972 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700973#ifdef MS_WINDOWS
974 BOOL narrow;
975#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300976 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700977#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700978 int fd;
979 Py_ssize_t length;
980 PyObject *object;
981 PyObject *cleanup;
982} path_t;
983
Steve Dowercc16be82016-09-08 10:35:16 -0700984#ifdef MS_WINDOWS
985#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
986 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
987#else
Larry Hastings2f936352014-08-05 14:04:04 +1000988#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
989 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700990#endif
Larry Hastings31826802013-10-19 00:09:25 -0700991
Larry Hastings9cf065c2012-06-22 16:30:09 -0700992static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800993path_cleanup(path_t *path)
994{
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +0300995#if !USE_UNICODE_WCHAR_CACHE
996 wchar_t *wide = (wchar_t *)path->wide;
997 path->wide = NULL;
998 PyMem_Free(wide);
999#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001000 Py_CLEAR(path->object);
1001 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001002}
1003
1004static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001005path_converter(PyObject *o, void *p)
1006{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +08001008 PyObject *bytes = NULL;
1009 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001010 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001011 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001012#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +08001013 PyObject *wo = NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001014 wchar_t *wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001015#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001016
1017#define FORMAT_EXCEPTION(exc, fmt) \
1018 PyErr_Format(exc, "%s%s" fmt, \
1019 path->function_name ? path->function_name : "", \
1020 path->function_name ? ": " : "", \
1021 path->argument_name ? path->argument_name : "path")
1022
1023 /* Py_CLEANUP_SUPPORTED support */
1024 if (o == NULL) {
1025 path_cleanup(path);
1026 return 1;
1027 }
1028
Brett Cannon3f9183b2016-08-26 14:44:48 -07001029 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +08001030 path->object = path->cleanup = NULL;
1031 /* path->object owns a reference to the original object */
1032 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001033
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001034 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001035 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001036#ifdef MS_WINDOWS
1037 path->narrow = FALSE;
1038#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001039 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001040#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001041 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001042 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001043 }
1044
Brett Cannon3f9183b2016-08-26 14:44:48 -07001045 /* Only call this here so that we don't treat the return value of
1046 os.fspath() as an fd or buffer. */
1047 is_index = path->allow_fd && PyIndex_Check(o);
1048 is_buffer = PyObject_CheckBuffer(o);
1049 is_bytes = PyBytes_Check(o);
1050 is_unicode = PyUnicode_Check(o);
1051
1052 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
1053 /* Inline PyOS_FSPath() for better error messages. */
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001054 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001055
1056 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1057 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001058 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001059 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001060 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001061 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001062 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001063 goto error_exit;
1064 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001065 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001066 is_unicode = 1;
1067 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001068 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001069 is_bytes = 1;
1070 }
1071 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001072 PyErr_Format(PyExc_TypeError,
1073 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -08001074 "not %.200s", _PyType_Name(Py_TYPE(o)),
1075 _PyType_Name(Py_TYPE(res)));
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001076 Py_DECREF(res);
1077 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001078 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001079
1080 /* still owns a reference to the original object */
1081 Py_DECREF(o);
1082 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001083 }
1084
1085 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001086#ifdef MS_WINDOWS
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001087#if USE_UNICODE_WCHAR_CACHE
1088_Py_COMP_DIAG_PUSH
1089_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001090 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001091_Py_COMP_DIAG_POP
1092#else /* USE_UNICODE_WCHAR_CACHE */
1093 wide = PyUnicode_AsWideCharString(o, &length);
1094#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner59799a82013-11-13 14:17:30 +01001095 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001096 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001097 }
Victor Stinner59799a82013-11-13 14:17:30 +01001098 if (length > 32767) {
1099 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001100 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001101 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001102 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001103 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001104 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001105 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001106
1107 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001108 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001109 path->fd = -1;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001110#if !USE_UNICODE_WCHAR_CACHE
1111 wide = NULL;
1112#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001113 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001114#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001115 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001116 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001117 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001118#endif
1119 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001120 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001121 bytes = o;
1122 Py_INCREF(bytes);
1123 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001124 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001125 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001126 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001127 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1128 "%s%s%s should be %s, not %.200s",
1129 path->function_name ? path->function_name : "",
1130 path->function_name ? ": " : "",
1131 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001132 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1133 "integer or None" :
1134 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1135 path->nullable ? "string, bytes, os.PathLike or None" :
1136 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001137 _PyType_Name(Py_TYPE(o)))) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001138 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001139 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001140 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001141 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001142 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001143 }
1144 }
Steve Dowercc16be82016-09-08 10:35:16 -07001145 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001146 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001147 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001148 }
1149 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001150#ifdef MS_WINDOWS
1151 path->narrow = FALSE;
1152#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001153 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001154#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001155 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001156 }
1157 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001158 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001159 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1160 path->function_name ? path->function_name : "",
1161 path->function_name ? ": " : "",
1162 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001163 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1164 "integer or None" :
1165 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1166 path->nullable ? "string, bytes, os.PathLike or None" :
1167 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001168 _PyType_Name(Py_TYPE(o)));
Xiang Zhang04316c42017-01-08 23:26:57 +08001169 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001170 }
1171
Larry Hastings9cf065c2012-06-22 16:30:09 -07001172 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001173 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001174 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001175 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001176 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001177 }
1178
Steve Dowercc16be82016-09-08 10:35:16 -07001179#ifdef MS_WINDOWS
1180 wo = PyUnicode_DecodeFSDefaultAndSize(
1181 narrow,
1182 length
1183 );
1184 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001185 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001186 }
1187
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001188#if USE_UNICODE_WCHAR_CACHE
1189_Py_COMP_DIAG_PUSH
1190_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Xiang Zhang04316c42017-01-08 23:26:57 +08001191 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001192_Py_COMP_DIAG_POP
1193#else /* USE_UNICODE_WCHAR_CACHE */
1194 wide = PyUnicode_AsWideCharString(wo, &length);
1195 Py_DECREF(wo);
1196#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowercc16be82016-09-08 10:35:16 -07001197 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001198 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001199 }
1200 if (length > 32767) {
1201 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001202 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001203 }
1204 if (wcslen(wide) != length) {
1205 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001206 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001207 }
1208 path->wide = wide;
1209 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001210 Py_DECREF(bytes);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001211#if USE_UNICODE_WCHAR_CACHE
1212 path->cleanup = wo;
1213#else /* USE_UNICODE_WCHAR_CACHE */
1214 wide = NULL;
1215#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowercc16be82016-09-08 10:35:16 -07001216#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001217 path->wide = NULL;
1218 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001219 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001220 /* Still a reference owned by path->object, don't have to
1221 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001222 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001223 }
1224 else {
1225 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001226 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001227#endif
1228 path->fd = -1;
1229
1230 success_exit:
1231 path->length = length;
1232 path->object = o;
1233 return Py_CLEANUP_SUPPORTED;
1234
1235 error_exit:
1236 Py_XDECREF(o);
1237 Py_XDECREF(bytes);
1238#ifdef MS_WINDOWS
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001239#if USE_UNICODE_WCHAR_CACHE
Xiang Zhang04316c42017-01-08 23:26:57 +08001240 Py_XDECREF(wo);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001241#else /* USE_UNICODE_WCHAR_CACHE */
1242 PyMem_Free(wide);
1243#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001244#endif
1245 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001246}
1247
1248static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001249argument_unavailable_error(const char *function_name, const char *argument_name)
1250{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001251 PyErr_Format(PyExc_NotImplementedError,
1252 "%s%s%s unavailable on this platform",
1253 (function_name != NULL) ? function_name : "",
1254 (function_name != NULL) ? ": ": "",
1255 argument_name);
1256}
1257
1258static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001259dir_fd_unavailable(PyObject *o, void *p)
1260{
1261 int dir_fd;
1262 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001263 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001264 if (dir_fd != DEFAULT_DIR_FD) {
1265 argument_unavailable_error(NULL, "dir_fd");
1266 return 0;
1267 }
1268 *(int *)p = dir_fd;
1269 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001270}
1271
1272static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001273fd_specified(const char *function_name, int fd)
1274{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001275 if (fd == -1)
1276 return 0;
1277
1278 argument_unavailable_error(function_name, "fd");
1279 return 1;
1280}
1281
1282static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001283follow_symlinks_specified(const char *function_name, int follow_symlinks)
1284{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001285 if (follow_symlinks)
1286 return 0;
1287
1288 argument_unavailable_error(function_name, "follow_symlinks");
1289 return 1;
1290}
1291
1292static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001293path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1294{
Steve Dowercc16be82016-09-08 10:35:16 -07001295 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1296#ifndef MS_WINDOWS
1297 && !path->narrow
1298#endif
1299 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001300 PyErr_Format(PyExc_ValueError,
1301 "%s: can't specify dir_fd without matching path",
1302 function_name);
1303 return 1;
1304 }
1305 return 0;
1306}
1307
1308static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001309dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1310{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001311 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1312 PyErr_Format(PyExc_ValueError,
1313 "%s: can't specify both dir_fd and fd",
1314 function_name);
1315 return 1;
1316 }
1317 return 0;
1318}
1319
1320static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001321fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1322 int follow_symlinks)
1323{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001324 if ((fd > 0) && (!follow_symlinks)) {
1325 PyErr_Format(PyExc_ValueError,
1326 "%s: cannot use fd and follow_symlinks together",
1327 function_name);
1328 return 1;
1329 }
1330 return 0;
1331}
1332
1333static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001334dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1335 int follow_symlinks)
1336{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001337 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1338 PyErr_Format(PyExc_ValueError,
1339 "%s: cannot use dir_fd and follow_symlinks together",
1340 function_name);
1341 return 1;
1342 }
1343 return 0;
1344}
1345
Larry Hastings2f936352014-08-05 14:04:04 +10001346#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001347 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001348#else
Larry Hastings2f936352014-08-05 14:04:04 +10001349 typedef off_t Py_off_t;
1350#endif
1351
1352static int
1353Py_off_t_converter(PyObject *arg, void *addr)
1354{
1355#ifdef HAVE_LARGEFILE_SUPPORT
1356 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1357#else
1358 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001359#endif
1360 if (PyErr_Occurred())
1361 return 0;
1362 return 1;
1363}
Larry Hastings2f936352014-08-05 14:04:04 +10001364
1365static PyObject *
1366PyLong_FromPy_off_t(Py_off_t offset)
1367{
1368#ifdef HAVE_LARGEFILE_SUPPORT
1369 return PyLong_FromLongLong(offset);
1370#else
1371 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001372#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001373}
1374
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001375#ifdef HAVE_SIGSET_T
1376/* Convert an iterable of integers to a sigset.
1377 Return 1 on success, return 0 and raise an exception on error. */
1378int
1379_Py_Sigset_Converter(PyObject *obj, void *addr)
1380{
1381 sigset_t *mask = (sigset_t *)addr;
1382 PyObject *iterator, *item;
1383 long signum;
1384 int overflow;
1385
Rémi Lapeyref0900192019-05-04 01:30:53 +02001386 // The extra parens suppress the unreachable-code warning with clang on MacOS
1387 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001388 /* Probably only if mask == NULL. */
1389 PyErr_SetFromErrno(PyExc_OSError);
1390 return 0;
1391 }
1392
1393 iterator = PyObject_GetIter(obj);
1394 if (iterator == NULL) {
1395 return 0;
1396 }
1397
1398 while ((item = PyIter_Next(iterator)) != NULL) {
1399 signum = PyLong_AsLongAndOverflow(item, &overflow);
1400 Py_DECREF(item);
1401 if (signum <= 0 || signum >= NSIG) {
1402 if (overflow || signum != -1 || !PyErr_Occurred()) {
1403 PyErr_Format(PyExc_ValueError,
1404 "signal number %ld out of range", signum);
1405 }
1406 goto error;
1407 }
1408 if (sigaddset(mask, (int)signum)) {
1409 if (errno != EINVAL) {
1410 /* Probably impossible */
1411 PyErr_SetFromErrno(PyExc_OSError);
1412 goto error;
1413 }
1414 /* For backwards compatibility, allow idioms such as
1415 * `range(1, NSIG)` but warn about invalid signal numbers
1416 */
1417 const char msg[] =
1418 "invalid signal number %ld, please use valid_signals()";
1419 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1420 goto error;
1421 }
1422 }
1423 }
1424 if (!PyErr_Occurred()) {
1425 Py_DECREF(iterator);
1426 return 1;
1427 }
1428
1429error:
1430 Py_DECREF(iterator);
1431 return 0;
1432}
1433#endif /* HAVE_SIGSET_T */
1434
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001435#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001436
1437static int
Brian Curtind25aef52011-06-13 15:16:04 -05001438win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001439{
Martin Panter70214ad2016-08-04 02:38:59 +00001440 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1441 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001442 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001443
1444 if (0 == DeviceIoControl(
1445 reparse_point_handle,
1446 FSCTL_GET_REPARSE_POINT,
1447 NULL, 0, /* in buffer */
1448 target_buffer, sizeof(target_buffer),
1449 &n_bytes_returned,
1450 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001451 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001452
1453 if (reparse_tag)
1454 *reparse_tag = rdb->ReparseTag;
1455
Brian Curtind25aef52011-06-13 15:16:04 -05001456 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001457}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001458
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001459#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001460
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001461/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001462#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001463/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001464** environ directly, we must obtain it with _NSGetEnviron(). See also
1465** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001466*/
1467#include <crt_externs.h>
pxinwrf2d7ac72019-05-21 18:46:37 +08001468#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001469extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001470#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001471
Barry Warsaw53699e91996-12-10 23:23:01 +00001472static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001473convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001474{
Victor Stinner8c62be82010-05-06 00:08:46 +00001475 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001476#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001477 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001478#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001479 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001480#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001481
Victor Stinner8c62be82010-05-06 00:08:46 +00001482 d = PyDict_New();
1483 if (d == NULL)
1484 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001485#ifdef MS_WINDOWS
1486 /* _wenviron must be initialized in this way if the program is started
1487 through main() instead of wmain(). */
1488 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001489 e = _wenviron;
Benoit Hudson723f71a2019-12-06 14:15:03 -05001490#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1491 /* environ is not accessible as an extern in a shared object on OSX; use
1492 _NSGetEnviron to resolve it. The value changes if you add environment
1493 variables between calls to Py_Initialize, so don't cache the value. */
1494 e = *_NSGetEnviron();
Victor Stinner8c62be82010-05-06 00:08:46 +00001495#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001496 e = environ;
1497#endif
1498 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001499 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001500 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001501 PyObject *k;
1502 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001503#ifdef MS_WINDOWS
1504 const wchar_t *p = wcschr(*e, L'=');
1505#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001506 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001507#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001508 if (p == NULL)
1509 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001510#ifdef MS_WINDOWS
1511 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1512#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001513 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001514#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001515 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001516 Py_DECREF(d);
1517 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001518 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001519#ifdef MS_WINDOWS
1520 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1521#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001522 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001523#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001524 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001525 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001526 Py_DECREF(d);
1527 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001528 }
Serhiy Storchakab510e102020-10-26 12:47:57 +02001529 if (PyDict_SetDefault(d, k, v) == NULL) {
1530 Py_DECREF(v);
1531 Py_DECREF(k);
1532 Py_DECREF(d);
1533 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001534 }
1535 Py_DECREF(k);
1536 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001537 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001538 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001539}
1540
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001541/* Set a POSIX-specific error from errno, and return NULL */
1542
Barry Warsawd58d7641998-07-23 16:14:40 +00001543static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001544posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001545{
Victor Stinner8c62be82010-05-06 00:08:46 +00001546 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001547}
Mark Hammondef8b6542001-05-13 08:04:26 +00001548
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001549#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001550static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001551win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001552{
Victor Stinner8c62be82010-05-06 00:08:46 +00001553 /* XXX We should pass the function name along in the future.
1554 (winreg.c also wants to pass the function name.)
1555 This would however require an additional param to the
1556 Windows error object, which is non-trivial.
1557 */
1558 errno = GetLastError();
1559 if (filename)
1560 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1561 else
1562 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001563}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001564
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001565static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001566win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001567{
1568 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001569 if (filename)
1570 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001571 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001572 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001573 filename);
1574 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001575 return PyErr_SetFromWindowsErr(err);
1576}
1577
1578static PyObject *
1579win32_error_object(const char* function, PyObject* filename)
1580{
1581 errno = GetLastError();
1582 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001583}
1584
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001585#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001586
Larry Hastings9cf065c2012-06-22 16:30:09 -07001587static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001588posix_path_object_error(PyObject *path)
1589{
1590 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1591}
1592
1593static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001594path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001595{
1596#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001597 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1598 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001599#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001600 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001601#endif
1602}
1603
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001604static PyObject *
1605path_object_error2(PyObject *path, PyObject *path2)
1606{
1607#ifdef MS_WINDOWS
1608 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1609 PyExc_OSError, 0, path, path2);
1610#else
1611 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1612#endif
1613}
1614
1615static PyObject *
1616path_error(path_t *path)
1617{
1618 return path_object_error(path->object);
1619}
Larry Hastings31826802013-10-19 00:09:25 -07001620
Larry Hastingsb0827312014-02-09 22:05:19 -08001621static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001622posix_path_error(path_t *path)
1623{
1624 return posix_path_object_error(path->object);
1625}
1626
1627static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001628path_error2(path_t *path, path_t *path2)
1629{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001630 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001631}
1632
1633
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001634/* POSIX generic methods */
1635
Larry Hastings2f936352014-08-05 14:04:04 +10001636static PyObject *
1637posix_fildes_fd(int fd, int (*func)(int))
1638{
1639 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001640 int async_err = 0;
1641
1642 do {
1643 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001644 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001645 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001646 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001647 Py_END_ALLOW_THREADS
1648 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1649 if (res != 0)
1650 return (!async_err) ? posix_error() : NULL;
1651 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001652}
Guido van Rossum21142a01999-01-08 21:05:37 +00001653
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001654
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001655#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001656/* This is a reimplementation of the C library's chdir function,
1657 but one that produces Win32 errors instead of DOS error codes.
1658 chdir is essentially a wrapper around SetCurrentDirectory; however,
1659 it also needs to set "magic" environment variables indicating
1660 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001661static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001662win32_wchdir(LPCWSTR path)
1663{
Victor Stinnered537822015-12-13 21:40:26 +01001664 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001665 int result;
1666 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001667
Victor Stinner8c62be82010-05-06 00:08:46 +00001668 if(!SetCurrentDirectoryW(path))
1669 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001670 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001671 if (!result)
1672 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001673 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001674 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001675 if (!new_path) {
1676 SetLastError(ERROR_OUTOFMEMORY);
1677 return FALSE;
1678 }
1679 result = GetCurrentDirectoryW(result, new_path);
1680 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001681 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001682 return FALSE;
1683 }
1684 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001685 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1686 wcsncmp(new_path, L"//", 2) == 0);
1687 if (!is_unc_like_path) {
1688 env[1] = new_path[0];
1689 result = SetEnvironmentVariableW(env, new_path);
1690 }
Victor Stinnered537822015-12-13 21:40:26 +01001691 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001692 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001693 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001694}
1695#endif
1696
Martin v. Löwis14694662006-02-03 12:54:16 +00001697#ifdef MS_WINDOWS
1698/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1699 - time stamps are restricted to second resolution
1700 - file modification times suffer from forth-and-back conversions between
1701 UTC and local time
1702 Therefore, we implement our own stat, based on the Win32 API directly.
1703*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001704#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001705#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001706#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001707
Victor Stinner6036e442015-03-08 01:58:04 +01001708static void
Steve Dowercc16be82016-09-08 10:35:16 -07001709find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1710 BY_HANDLE_FILE_INFORMATION *info,
1711 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001712{
1713 memset(info, 0, sizeof(*info));
1714 info->dwFileAttributes = pFileData->dwFileAttributes;
1715 info->ftCreationTime = pFileData->ftCreationTime;
1716 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1717 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1718 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1719 info->nFileSizeLow = pFileData->nFileSizeLow;
1720/* info->nNumberOfLinks = 1; */
1721 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1722 *reparse_tag = pFileData->dwReserved0;
1723 else
1724 *reparse_tag = 0;
1725}
1726
Guido van Rossumd8faa362007-04-27 19:54:29 +00001727static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001728attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001729{
Victor Stinner8c62be82010-05-06 00:08:46 +00001730 HANDLE hFindFile;
1731 WIN32_FIND_DATAW FileData;
1732 hFindFile = FindFirstFileW(pszFile, &FileData);
1733 if (hFindFile == INVALID_HANDLE_VALUE)
1734 return FALSE;
1735 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001736 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001737 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001738}
1739
Brian Curtind25aef52011-06-13 15:16:04 -05001740static int
Steve Dowercc16be82016-09-08 10:35:16 -07001741win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001742 BOOL traverse)
1743{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001744 HANDLE hFile;
1745 BY_HANDLE_FILE_INFORMATION fileInfo;
1746 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1747 DWORD fileType, error;
1748 BOOL isUnhandledTag = FALSE;
1749 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001750
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001751 DWORD access = FILE_READ_ATTRIBUTES;
1752 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1753 if (!traverse) {
1754 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1755 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001756
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001757 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001758 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001759 /* Either the path doesn't exist, or the caller lacks access. */
1760 error = GetLastError();
1761 switch (error) {
1762 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1763 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1764 /* Try reading the parent directory. */
1765 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1766 /* Cannot read the parent directory. */
1767 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001768 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001769 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001770 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1771 if (traverse ||
1772 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1773 /* The stat call has to traverse but cannot, so fail. */
1774 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001775 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001776 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001777 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001778 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001779
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001780 case ERROR_INVALID_PARAMETER:
1781 /* \\.\con requires read or write access. */
1782 hFile = CreateFileW(path, access | GENERIC_READ,
1783 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1784 OPEN_EXISTING, flags, NULL);
1785 if (hFile == INVALID_HANDLE_VALUE) {
1786 SetLastError(error);
1787 return -1;
1788 }
1789 break;
1790
1791 case ERROR_CANT_ACCESS_FILE:
1792 /* bpo37834: open unhandled reparse points if traverse fails. */
1793 if (traverse) {
1794 traverse = FALSE;
1795 isUnhandledTag = TRUE;
1796 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1797 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1798 }
1799 if (hFile == INVALID_HANDLE_VALUE) {
1800 SetLastError(error);
1801 return -1;
1802 }
1803 break;
1804
1805 default:
1806 return -1;
1807 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001808 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001809
1810 if (hFile != INVALID_HANDLE_VALUE) {
1811 /* Handle types other than files on disk. */
1812 fileType = GetFileType(hFile);
1813 if (fileType != FILE_TYPE_DISK) {
1814 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1815 retval = -1;
1816 goto cleanup;
1817 }
1818 DWORD fileAttributes = GetFileAttributesW(path);
1819 memset(result, 0, sizeof(*result));
1820 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1821 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1822 /* \\.\pipe\ or \\.\mailslot\ */
1823 result->st_mode = _S_IFDIR;
1824 } else if (fileType == FILE_TYPE_CHAR) {
1825 /* \\.\nul */
1826 result->st_mode = _S_IFCHR;
1827 } else if (fileType == FILE_TYPE_PIPE) {
1828 /* \\.\pipe\spam */
1829 result->st_mode = _S_IFIFO;
1830 }
1831 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1832 goto cleanup;
1833 }
1834
1835 /* Query the reparse tag, and traverse a non-link. */
1836 if (!traverse) {
1837 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1838 &tagInfo, sizeof(tagInfo))) {
1839 /* Allow devices that do not support FileAttributeTagInfo. */
1840 switch (GetLastError()) {
1841 case ERROR_INVALID_PARAMETER:
1842 case ERROR_INVALID_FUNCTION:
1843 case ERROR_NOT_SUPPORTED:
1844 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1845 tagInfo.ReparseTag = 0;
1846 break;
1847 default:
1848 retval = -1;
1849 goto cleanup;
1850 }
1851 } else if (tagInfo.FileAttributes &
1852 FILE_ATTRIBUTE_REPARSE_POINT) {
1853 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1854 if (isUnhandledTag) {
1855 /* Traversing previously failed for either this link
1856 or its target. */
1857 SetLastError(ERROR_CANT_ACCESS_FILE);
1858 retval = -1;
1859 goto cleanup;
1860 }
1861 /* Traverse a non-link, but not if traversing already failed
1862 for an unhandled tag. */
1863 } else if (!isUnhandledTag) {
1864 CloseHandle(hFile);
1865 return win32_xstat_impl(path, result, TRUE);
1866 }
1867 }
1868 }
1869
1870 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
1871 switch (GetLastError()) {
1872 case ERROR_INVALID_PARAMETER:
1873 case ERROR_INVALID_FUNCTION:
1874 case ERROR_NOT_SUPPORTED:
Steve Dower772ec0f2019-09-04 14:42:54 -07001875 /* Volumes and physical disks are block devices, e.g.
1876 \\.\C: and \\.\PhysicalDrive0. */
1877 memset(result, 0, sizeof(*result));
1878 result->st_mode = 0x6000; /* S_IFBLK */
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001879 goto cleanup;
1880 }
Steve Dower772ec0f2019-09-04 14:42:54 -07001881 retval = -1;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001882 goto cleanup;
1883 }
1884 }
1885
1886 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
1887
1888 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
1889 /* Fix the file execute permissions. This hack sets S_IEXEC if
1890 the filename has an extension that is commonly used by files
1891 that CreateProcessW can execute. A real implementation calls
1892 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
1893 AccessCheck to check for generic read, write, and execute
1894 access. */
1895 const wchar_t *fileExtension = wcsrchr(path, '.');
1896 if (fileExtension) {
1897 if (_wcsicmp(fileExtension, L".exe") == 0 ||
1898 _wcsicmp(fileExtension, L".bat") == 0 ||
1899 _wcsicmp(fileExtension, L".cmd") == 0 ||
1900 _wcsicmp(fileExtension, L".com") == 0) {
1901 result->st_mode |= 0111;
1902 }
1903 }
1904 }
1905
1906cleanup:
1907 if (hFile != INVALID_HANDLE_VALUE) {
Steve Dower772ec0f2019-09-04 14:42:54 -07001908 /* Preserve last error if we are failing */
1909 error = retval ? GetLastError() : 0;
1910 if (!CloseHandle(hFile)) {
1911 retval = -1;
1912 } else if (retval) {
1913 /* Restore last error */
1914 SetLastError(error);
1915 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001916 }
1917
1918 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001919}
1920
1921static int
Steve Dowercc16be82016-09-08 10:35:16 -07001922win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001923{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001924 /* Protocol violation: we explicitly clear errno, instead of
1925 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001926 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001927 errno = 0;
1928 return code;
1929}
Brian Curtind25aef52011-06-13 15:16:04 -05001930/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001931
1932 In Posix, stat automatically traverses symlinks and returns the stat
1933 structure for the target. In Windows, the equivalent GetFileAttributes by
1934 default does not traverse symlinks and instead returns attributes for
1935 the symlink.
1936
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001937 Instead, we will open the file (which *does* traverse symlinks by default)
1938 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00001939
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001940static int
Steve Dowercc16be82016-09-08 10:35:16 -07001941win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001942{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001943 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001944}
1945
Victor Stinner8c62be82010-05-06 00:08:46 +00001946static int
Steve Dowercc16be82016-09-08 10:35:16 -07001947win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001948{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001949 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001950}
1951
Martin v. Löwis14694662006-02-03 12:54:16 +00001952#endif /* MS_WINDOWS */
1953
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001954PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001955"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001956This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001957 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001958or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1959\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001960Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1961or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001962\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001963See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001964
1965static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001966 {"st_mode", "protection bits"},
1967 {"st_ino", "inode"},
1968 {"st_dev", "device"},
1969 {"st_nlink", "number of hard links"},
1970 {"st_uid", "user ID of owner"},
1971 {"st_gid", "group ID of owner"},
1972 {"st_size", "total size, in bytes"},
1973 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1974 {NULL, "integer time of last access"},
1975 {NULL, "integer time of last modification"},
1976 {NULL, "integer time of last change"},
1977 {"st_atime", "time of last access"},
1978 {"st_mtime", "time of last modification"},
1979 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001980 {"st_atime_ns", "time of last access in nanoseconds"},
1981 {"st_mtime_ns", "time of last modification in nanoseconds"},
1982 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001983#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001984 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001985#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001986#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001987 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001988#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001989#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001990 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001991#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001992#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001993 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001994#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001995#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001996 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001997#endif
1998#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001999 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002000#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002001#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2002 {"st_file_attributes", "Windows file attribute bits"},
2003#endif
jcea6c51d512018-01-28 14:00:08 +01002004#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2005 {"st_fstype", "Type of filesystem"},
2006#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002007#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2008 {"st_reparse_tag", "Windows reparse tag"},
2009#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002011};
2012
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002013#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002014#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002015#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002016#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002017#endif
2018
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002019#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002020#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2021#else
2022#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2023#endif
2024
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002025#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002026#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2027#else
2028#define ST_RDEV_IDX ST_BLOCKS_IDX
2029#endif
2030
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002031#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2032#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2033#else
2034#define ST_FLAGS_IDX ST_RDEV_IDX
2035#endif
2036
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002037#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002038#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002039#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002040#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002041#endif
2042
2043#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2044#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2045#else
2046#define ST_BIRTHTIME_IDX ST_GEN_IDX
2047#endif
2048
Zachary Ware63f277b2014-06-19 09:46:37 -05002049#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2050#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
2051#else
2052#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2053#endif
2054
jcea6c51d512018-01-28 14:00:08 +01002055#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2056#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2057#else
2058#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2059#endif
2060
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002061#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2062#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2063#else
2064#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2065#endif
2066
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002067static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002068 "stat_result", /* name */
2069 stat_result__doc__, /* doc */
2070 stat_result_fields,
2071 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002072};
2073
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002074PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002075"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2076This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002077 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002078or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002079\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002080See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002081
2082static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 {"f_bsize", },
2084 {"f_frsize", },
2085 {"f_blocks", },
2086 {"f_bfree", },
2087 {"f_bavail", },
2088 {"f_files", },
2089 {"f_ffree", },
2090 {"f_favail", },
2091 {"f_flag", },
2092 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002093 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002094 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002095};
2096
2097static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002098 "statvfs_result", /* name */
2099 statvfs_result__doc__, /* doc */
2100 statvfs_result_fields,
2101 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002102};
2103
Ross Lagerwall7807c352011-03-17 20:20:30 +02002104#if defined(HAVE_WAITID) && !defined(__APPLE__)
2105PyDoc_STRVAR(waitid_result__doc__,
2106"waitid_result: Result from waitid.\n\n\
2107This object may be accessed either as a tuple of\n\
2108 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2109or via the attributes si_pid, si_uid, and so on.\n\
2110\n\
2111See os.waitid for more information.");
2112
2113static PyStructSequence_Field waitid_result_fields[] = {
2114 {"si_pid", },
2115 {"si_uid", },
2116 {"si_signo", },
2117 {"si_status", },
2118 {"si_code", },
2119 {0}
2120};
2121
2122static PyStructSequence_Desc waitid_result_desc = {
2123 "waitid_result", /* name */
2124 waitid_result__doc__, /* doc */
2125 waitid_result_fields,
2126 5
2127};
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002128#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002129static newfunc structseq_new;
2130
2131static PyObject *
2132statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2133{
Victor Stinner8c62be82010-05-06 00:08:46 +00002134 PyStructSequence *result;
2135 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002136
Victor Stinner8c62be82010-05-06 00:08:46 +00002137 result = (PyStructSequence*)structseq_new(type, args, kwds);
2138 if (!result)
2139 return NULL;
2140 /* If we have been initialized from a tuple,
2141 st_?time might be set to None. Initialize it
2142 from the int slots. */
2143 for (i = 7; i <= 9; i++) {
2144 if (result->ob_item[i+3] == Py_None) {
2145 Py_DECREF(Py_None);
2146 Py_INCREF(result->ob_item[i]);
2147 result->ob_item[i+3] = result->ob_item[i];
2148 }
2149 }
2150 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002151}
2152
Eddie Elizondob3966632019-11-05 07:16:14 -08002153static int
2154_posix_clear(PyObject *module)
2155{
Victor Stinner97f33c32020-05-14 18:05:58 +02002156 _posixstate *state = get_posix_state(module);
2157 Py_CLEAR(state->billion);
2158 Py_CLEAR(state->DirEntryType);
2159 Py_CLEAR(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002160#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002161 Py_CLEAR(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002162#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002163 Py_CLEAR(state->StatResultType);
2164 Py_CLEAR(state->StatVFSResultType);
2165 Py_CLEAR(state->TerminalSizeType);
2166 Py_CLEAR(state->TimesResultType);
2167 Py_CLEAR(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002168#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002169 Py_CLEAR(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002170#endif
2171#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002172 Py_CLEAR(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002173#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002174 Py_CLEAR(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002175 return 0;
2176}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002177
Eddie Elizondob3966632019-11-05 07:16:14 -08002178static int
2179_posix_traverse(PyObject *module, visitproc visit, void *arg)
2180{
Victor Stinner97f33c32020-05-14 18:05:58 +02002181 _posixstate *state = get_posix_state(module);
2182 Py_VISIT(state->billion);
2183 Py_VISIT(state->DirEntryType);
2184 Py_VISIT(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002185#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002186 Py_VISIT(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002187#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002188 Py_VISIT(state->StatResultType);
2189 Py_VISIT(state->StatVFSResultType);
2190 Py_VISIT(state->TerminalSizeType);
2191 Py_VISIT(state->TimesResultType);
2192 Py_VISIT(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002193#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002194 Py_VISIT(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002195#endif
2196#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002197 Py_VISIT(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002198#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002199 Py_VISIT(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002200 return 0;
2201}
2202
2203static void
2204_posix_free(void *module)
2205{
2206 _posix_clear((PyObject *)module);
2207}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002208
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002209static void
Victor Stinner1c2fa782020-05-10 11:05:29 +02002210fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002211{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002212 PyObject *s = _PyLong_FromTime_t(sec);
2213 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2214 PyObject *s_in_ns = NULL;
2215 PyObject *ns_total = NULL;
2216 PyObject *float_s = NULL;
2217
2218 if (!(s && ns_fractional))
2219 goto exit;
2220
Victor Stinner1c2fa782020-05-10 11:05:29 +02002221 s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002222 if (!s_in_ns)
2223 goto exit;
2224
2225 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2226 if (!ns_total)
2227 goto exit;
2228
Victor Stinner01b5aab2017-10-24 02:02:00 -07002229 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2230 if (!float_s) {
2231 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002232 }
2233
2234 PyStructSequence_SET_ITEM(v, index, s);
2235 PyStructSequence_SET_ITEM(v, index+3, float_s);
2236 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2237 s = NULL;
2238 float_s = NULL;
2239 ns_total = NULL;
2240exit:
2241 Py_XDECREF(s);
2242 Py_XDECREF(ns_fractional);
2243 Py_XDECREF(s_in_ns);
2244 Py_XDECREF(ns_total);
2245 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002246}
2247
Tim Peters5aa91602002-01-30 05:46:57 +00002248/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002249 (used by posix_stat() and posix_fstat()) */
2250static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +02002251_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002252{
Victor Stinner8c62be82010-05-06 00:08:46 +00002253 unsigned long ansec, mnsec, cnsec;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002254 PyObject *StatResultType = get_posix_state(module)->StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08002255 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002256 if (v == NULL)
2257 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002258
Victor Stinner8c62be82010-05-06 00:08:46 +00002259 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002260 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002261 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002262#ifdef MS_WINDOWS
2263 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002264#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002265 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002266#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002267 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002268#if defined(MS_WINDOWS)
2269 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2270 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2271#else
2272 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2273 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2274#endif
xdegaye50e86032017-05-22 11:15:08 +02002275 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2276 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002277
Martin v. Löwis14694662006-02-03 12:54:16 +00002278#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002279 ansec = st->st_atim.tv_nsec;
2280 mnsec = st->st_mtim.tv_nsec;
2281 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002282#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002283 ansec = st->st_atimespec.tv_nsec;
2284 mnsec = st->st_mtimespec.tv_nsec;
2285 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002286#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002287 ansec = st->st_atime_nsec;
2288 mnsec = st->st_mtime_nsec;
2289 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002290#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002291 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002292#endif
Victor Stinner1c2fa782020-05-10 11:05:29 +02002293 fill_time(module, v, 7, st->st_atime, ansec);
2294 fill_time(module, v, 8, st->st_mtime, mnsec);
2295 fill_time(module, v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002296
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002297#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2299 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002300#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002301#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002302 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2303 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002304#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002305#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002306 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2307 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002308#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002309#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002310 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2311 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002312#endif
2313#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002314 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002315 PyObject *val;
2316 unsigned long bsec,bnsec;
2317 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002318#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002319 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002320#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002321 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002322#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002323 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002324 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2325 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002326 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002327#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002328#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002329 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2330 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002331#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002332#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2333 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2334 PyLong_FromUnsignedLong(st->st_file_attributes));
2335#endif
jcea6c51d512018-01-28 14:00:08 +01002336#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2337 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2338 PyUnicode_FromString(st->st_fstype));
2339#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002340#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2341 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2342 PyLong_FromUnsignedLong(st->st_reparse_tag));
2343#endif
Fred Drake699f3522000-06-29 21:12:41 +00002344
Victor Stinner8c62be82010-05-06 00:08:46 +00002345 if (PyErr_Occurred()) {
2346 Py_DECREF(v);
2347 return NULL;
2348 }
Fred Drake699f3522000-06-29 21:12:41 +00002349
Victor Stinner8c62be82010-05-06 00:08:46 +00002350 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002351}
2352
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002353/* POSIX methods */
2354
Guido van Rossum94f6f721999-01-06 18:42:14 +00002355
2356static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02002357posix_do_stat(PyObject *module, const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002358 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002359{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002360 STRUCT_STAT st;
2361 int result;
2362
2363#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2364 if (follow_symlinks_specified(function_name, follow_symlinks))
2365 return NULL;
2366#endif
2367
2368 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2369 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2370 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2371 return NULL;
2372
2373 Py_BEGIN_ALLOW_THREADS
2374 if (path->fd != -1)
2375 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002376#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002377 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002378 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002379 else
Steve Dowercc16be82016-09-08 10:35:16 -07002380 result = win32_lstat(path->wide, &st);
2381#else
2382 else
2383#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002384 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2385 result = LSTAT(path->narrow, &st);
2386 else
Steve Dowercc16be82016-09-08 10:35:16 -07002387#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002388#ifdef HAVE_FSTATAT
2389 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2390 result = fstatat(dir_fd, path->narrow, &st,
2391 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2392 else
Steve Dowercc16be82016-09-08 10:35:16 -07002393#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002394 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002395#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002396 Py_END_ALLOW_THREADS
2397
Victor Stinner292c8352012-10-30 02:17:38 +01002398 if (result != 0) {
2399 return path_error(path);
2400 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002401
Victor Stinner1c2fa782020-05-10 11:05:29 +02002402 return _pystat_fromstructstat(module, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002403}
2404
Larry Hastings2f936352014-08-05 14:04:04 +10002405/*[python input]
2406
2407for s in """
2408
2409FACCESSAT
2410FCHMODAT
2411FCHOWNAT
2412FSTATAT
2413LINKAT
2414MKDIRAT
2415MKFIFOAT
2416MKNODAT
2417OPENAT
2418READLINKAT
2419SYMLINKAT
2420UNLINKAT
2421
2422""".strip().split():
2423 s = s.strip()
2424 print("""
2425#ifdef HAVE_{s}
2426 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002427#else
Larry Hastings2f936352014-08-05 14:04:04 +10002428 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002429#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002430""".rstrip().format(s=s))
2431
2432for s in """
2433
2434FCHDIR
2435FCHMOD
2436FCHOWN
2437FDOPENDIR
2438FEXECVE
2439FPATHCONF
2440FSTATVFS
2441FTRUNCATE
2442
2443""".strip().split():
2444 s = s.strip()
2445 print("""
2446#ifdef HAVE_{s}
2447 #define PATH_HAVE_{s} 1
2448#else
2449 #define PATH_HAVE_{s} 0
2450#endif
2451
2452""".rstrip().format(s=s))
2453[python start generated code]*/
2454
2455#ifdef HAVE_FACCESSAT
2456 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2457#else
2458 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2459#endif
2460
2461#ifdef HAVE_FCHMODAT
2462 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2463#else
2464 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2465#endif
2466
2467#ifdef HAVE_FCHOWNAT
2468 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2469#else
2470 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2471#endif
2472
2473#ifdef HAVE_FSTATAT
2474 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2475#else
2476 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2477#endif
2478
2479#ifdef HAVE_LINKAT
2480 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2481#else
2482 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2483#endif
2484
2485#ifdef HAVE_MKDIRAT
2486 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2487#else
2488 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2489#endif
2490
2491#ifdef HAVE_MKFIFOAT
2492 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2493#else
2494 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2495#endif
2496
2497#ifdef HAVE_MKNODAT
2498 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2499#else
2500 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2501#endif
2502
2503#ifdef HAVE_OPENAT
2504 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2505#else
2506 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2507#endif
2508
2509#ifdef HAVE_READLINKAT
2510 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2511#else
2512 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2513#endif
2514
2515#ifdef HAVE_SYMLINKAT
2516 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2517#else
2518 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2519#endif
2520
2521#ifdef HAVE_UNLINKAT
2522 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2523#else
2524 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2525#endif
2526
2527#ifdef HAVE_FCHDIR
2528 #define PATH_HAVE_FCHDIR 1
2529#else
2530 #define PATH_HAVE_FCHDIR 0
2531#endif
2532
2533#ifdef HAVE_FCHMOD
2534 #define PATH_HAVE_FCHMOD 1
2535#else
2536 #define PATH_HAVE_FCHMOD 0
2537#endif
2538
2539#ifdef HAVE_FCHOWN
2540 #define PATH_HAVE_FCHOWN 1
2541#else
2542 #define PATH_HAVE_FCHOWN 0
2543#endif
2544
2545#ifdef HAVE_FDOPENDIR
2546 #define PATH_HAVE_FDOPENDIR 1
2547#else
2548 #define PATH_HAVE_FDOPENDIR 0
2549#endif
2550
2551#ifdef HAVE_FEXECVE
2552 #define PATH_HAVE_FEXECVE 1
2553#else
2554 #define PATH_HAVE_FEXECVE 0
2555#endif
2556
2557#ifdef HAVE_FPATHCONF
2558 #define PATH_HAVE_FPATHCONF 1
2559#else
2560 #define PATH_HAVE_FPATHCONF 0
2561#endif
2562
2563#ifdef HAVE_FSTATVFS
2564 #define PATH_HAVE_FSTATVFS 1
2565#else
2566 #define PATH_HAVE_FSTATVFS 0
2567#endif
2568
2569#ifdef HAVE_FTRUNCATE
2570 #define PATH_HAVE_FTRUNCATE 1
2571#else
2572 #define PATH_HAVE_FTRUNCATE 0
2573#endif
2574/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002575
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002576#ifdef MS_WINDOWS
2577 #undef PATH_HAVE_FTRUNCATE
2578 #define PATH_HAVE_FTRUNCATE 1
2579#endif
Larry Hastings31826802013-10-19 00:09:25 -07002580
Larry Hastings61272b72014-01-07 12:41:53 -08002581/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002582
2583class path_t_converter(CConverter):
2584
2585 type = "path_t"
2586 impl_by_reference = True
2587 parse_by_reference = True
2588
2589 converter = 'path_converter'
2590
2591 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002592 # right now path_t doesn't support default values.
2593 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002594 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002595 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002596
Larry Hastings2f936352014-08-05 14:04:04 +10002597 if self.c_default not in (None, 'Py_None'):
2598 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002599
2600 self.nullable = nullable
2601 self.allow_fd = allow_fd
2602
Larry Hastings7726ac92014-01-31 22:03:12 -08002603 def pre_render(self):
2604 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002605 if isinstance(value, str):
2606 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002607 return str(int(bool(value)))
2608
2609 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002610 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002611 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002612 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002613 strify(self.nullable),
2614 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002615 )
2616
2617 def cleanup(self):
2618 return "path_cleanup(&" + self.name + ");\n"
2619
2620
2621class dir_fd_converter(CConverter):
2622 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002623
Larry Hastings2f936352014-08-05 14:04:04 +10002624 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002625 if self.default in (unspecified, None):
2626 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002627 if isinstance(requires, str):
2628 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2629 else:
2630 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002631
Larry Hastings2f936352014-08-05 14:04:04 +10002632class uid_t_converter(CConverter):
2633 type = "uid_t"
2634 converter = '_Py_Uid_Converter'
2635
2636class gid_t_converter(CConverter):
2637 type = "gid_t"
2638 converter = '_Py_Gid_Converter'
2639
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002640class dev_t_converter(CConverter):
2641 type = 'dev_t'
2642 converter = '_Py_Dev_Converter'
2643
2644class dev_t_return_converter(unsigned_long_return_converter):
2645 type = 'dev_t'
2646 conversion_fn = '_PyLong_FromDev'
2647 unsigned_cast = '(dev_t)'
2648
Larry Hastings2f936352014-08-05 14:04:04 +10002649class FSConverter_converter(CConverter):
2650 type = 'PyObject *'
2651 converter = 'PyUnicode_FSConverter'
2652 def converter_init(self):
2653 if self.default is not unspecified:
2654 fail("FSConverter_converter does not support default values")
2655 self.c_default = 'NULL'
2656
2657 def cleanup(self):
2658 return "Py_XDECREF(" + self.name + ");\n"
2659
2660class pid_t_converter(CConverter):
2661 type = 'pid_t'
2662 format_unit = '" _Py_PARSE_PID "'
2663
2664class idtype_t_converter(int_converter):
2665 type = 'idtype_t'
2666
2667class id_t_converter(CConverter):
2668 type = 'id_t'
2669 format_unit = '" _Py_PARSE_PID "'
2670
Benjamin Petersonca470632016-09-06 13:47:26 -07002671class intptr_t_converter(CConverter):
2672 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002673 format_unit = '" _Py_PARSE_INTPTR "'
2674
2675class Py_off_t_converter(CConverter):
2676 type = 'Py_off_t'
2677 converter = 'Py_off_t_converter'
2678
2679class Py_off_t_return_converter(long_return_converter):
2680 type = 'Py_off_t'
2681 conversion_fn = 'PyLong_FromPy_off_t'
2682
2683class path_confname_converter(CConverter):
2684 type="int"
2685 converter="conv_path_confname"
2686
2687class confstr_confname_converter(path_confname_converter):
2688 converter='conv_confstr_confname'
2689
2690class sysconf_confname_converter(path_confname_converter):
2691 converter="conv_sysconf_confname"
2692
Larry Hastings61272b72014-01-07 12:41:53 -08002693[python start generated code]*/
Serhiy Storchaka9975cc52020-10-09 23:00:45 +03002694/*[python end generated code: output=da39a3ee5e6b4b0d input=3338733161aa7879]*/
Larry Hastings31826802013-10-19 00:09:25 -07002695
Larry Hastings61272b72014-01-07 12:41:53 -08002696/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002697
Larry Hastings2a727912014-01-16 11:32:01 -08002698os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002699
2700 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002701 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002702 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002703
2704 *
2705
Larry Hastings2f936352014-08-05 14:04:04 +10002706 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002707 If not None, it should be a file descriptor open to a directory,
2708 and path should be a relative string; path will then be relative to
2709 that directory.
2710
2711 follow_symlinks: bool = True
2712 If False, and the last element of the path is a symbolic link,
2713 stat will examine the symbolic link itself instead of the file
2714 the link points to.
2715
2716Perform a stat system call on the given path.
2717
2718dir_fd and follow_symlinks may not be implemented
2719 on your platform. If they are unavailable, using them will raise a
2720 NotImplementedError.
2721
2722It's an error to use dir_fd or follow_symlinks when specifying path as
2723 an open file descriptor.
2724
Larry Hastings61272b72014-01-07 12:41:53 -08002725[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002726
Larry Hastings31826802013-10-19 00:09:25 -07002727static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002728os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002729/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002730{
Victor Stinner1c2fa782020-05-10 11:05:29 +02002731 return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002732}
2733
Larry Hastings2f936352014-08-05 14:04:04 +10002734
2735/*[clinic input]
2736os.lstat
2737
2738 path : path_t
2739
2740 *
2741
2742 dir_fd : dir_fd(requires='fstatat') = None
2743
2744Perform a stat system call on the given path, without following symbolic links.
2745
2746Like stat(), but do not follow symbolic links.
2747Equivalent to stat(path, follow_symlinks=False).
2748[clinic start generated code]*/
2749
Larry Hastings2f936352014-08-05 14:04:04 +10002750static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002751os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2752/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002753{
2754 int follow_symlinks = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002755 return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10002756}
Larry Hastings31826802013-10-19 00:09:25 -07002757
Larry Hastings2f936352014-08-05 14:04:04 +10002758
Larry Hastings61272b72014-01-07 12:41:53 -08002759/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002760os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002761
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002762 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002763 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002764
2765 mode: int
2766 Operating-system mode bitfield. Can be F_OK to test existence,
2767 or the inclusive-OR of R_OK, W_OK, and X_OK.
2768
2769 *
2770
Larry Hastings2f936352014-08-05 14:04:04 +10002771 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002772 If not None, it should be a file descriptor open to a directory,
2773 and path should be relative; path will then be relative to that
2774 directory.
2775
2776 effective_ids: bool = False
2777 If True, access will use the effective uid/gid instead of
2778 the real uid/gid.
2779
2780 follow_symlinks: bool = True
2781 If False, and the last element of the path is a symbolic link,
2782 access will examine the symbolic link itself instead of the file
2783 the link points to.
2784
2785Use the real uid/gid to test for access to a path.
2786
2787{parameters}
2788dir_fd, effective_ids, and follow_symlinks may not be implemented
2789 on your platform. If they are unavailable, using them will raise a
2790 NotImplementedError.
2791
2792Note that most operations will use the effective uid/gid, therefore this
2793 routine can be used in a suid/sgid environment to test if the invoking user
2794 has the specified access to the path.
2795
Larry Hastings61272b72014-01-07 12:41:53 -08002796[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002797
Larry Hastings2f936352014-08-05 14:04:04 +10002798static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002799os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002800 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002801/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002802{
Larry Hastings2f936352014-08-05 14:04:04 +10002803 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002804
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002805#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002806 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002807#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002809#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002810
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811#ifndef HAVE_FACCESSAT
2812 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002813 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002814
2815 if (effective_ids) {
2816 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002817 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818 }
2819#endif
2820
2821#ifdef MS_WINDOWS
2822 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002823 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 Py_END_ALLOW_THREADS
2825
2826 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002827 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002828 * * we didn't get a -1, and
2829 * * write access wasn't requested,
2830 * * or the file isn't read-only,
2831 * * or it's a directory.
2832 * (Directories cannot be read-only on Windows.)
2833 */
Larry Hastings2f936352014-08-05 14:04:04 +10002834 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002835 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002836 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002837 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002838#else
2839
2840 Py_BEGIN_ALLOW_THREADS
2841#ifdef HAVE_FACCESSAT
2842 if ((dir_fd != DEFAULT_DIR_FD) ||
2843 effective_ids ||
2844 !follow_symlinks) {
2845 int flags = 0;
2846 if (!follow_symlinks)
2847 flags |= AT_SYMLINK_NOFOLLOW;
2848 if (effective_ids)
2849 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002850 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002851 }
2852 else
2853#endif
Larry Hastings31826802013-10-19 00:09:25 -07002854 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002856 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002857#endif
2858
Larry Hastings9cf065c2012-06-22 16:30:09 -07002859 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002860}
2861
Guido van Rossumd371ff11999-01-25 16:12:23 +00002862#ifndef F_OK
2863#define F_OK 0
2864#endif
2865#ifndef R_OK
2866#define R_OK 4
2867#endif
2868#ifndef W_OK
2869#define W_OK 2
2870#endif
2871#ifndef X_OK
2872#define X_OK 1
2873#endif
2874
Larry Hastings31826802013-10-19 00:09:25 -07002875
Guido van Rossumd371ff11999-01-25 16:12:23 +00002876#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002877/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002878os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002879
2880 fd: int
2881 Integer file descriptor handle.
2882
2883 /
2884
2885Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002886[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002887
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002889os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002890/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002891{
Guido van Rossum94f6f721999-01-06 18:42:14 +00002892
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002893 long size = sysconf(_SC_TTY_NAME_MAX);
2894 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002895 return posix_error();
2896 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002897 char *buffer = (char *)PyMem_RawMalloc(size);
2898 if (buffer == NULL) {
2899 return PyErr_NoMemory();
2900 }
2901 int ret = ttyname_r(fd, buffer, size);
2902 if (ret != 0) {
2903 PyMem_RawFree(buffer);
2904 errno = ret;
2905 return posix_error();
2906 }
2907 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
2908 PyMem_RawFree(buffer);
2909 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002910}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002911#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002912
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002913#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002914/*[clinic input]
2915os.ctermid
2916
2917Return the name of the controlling terminal for this process.
2918[clinic start generated code]*/
2919
Larry Hastings2f936352014-08-05 14:04:04 +10002920static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002921os_ctermid_impl(PyObject *module)
2922/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002923{
Victor Stinner8c62be82010-05-06 00:08:46 +00002924 char *ret;
2925 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002926
Greg Wardb48bc172000-03-01 21:51:56 +00002927#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002928 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002929#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002930 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002931#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002932 if (ret == NULL)
2933 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002934 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002935}
Larry Hastings2f936352014-08-05 14:04:04 +10002936#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002937
Larry Hastings2f936352014-08-05 14:04:04 +10002938
2939/*[clinic input]
2940os.chdir
2941
2942 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2943
2944Change the current working directory to the specified path.
2945
2946path may always be specified as a string.
2947On some platforms, path may also be specified as an open file descriptor.
2948 If this functionality is unavailable, using it raises an exception.
2949[clinic start generated code]*/
2950
Larry Hastings2f936352014-08-05 14:04:04 +10002951static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002952os_chdir_impl(PyObject *module, path_t *path)
2953/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002954{
2955 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002956
Saiyang Gou7514f4f2020-02-12 23:47:42 -08002957 if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
2958 return NULL;
2959 }
2960
Larry Hastings9cf065c2012-06-22 16:30:09 -07002961 Py_BEGIN_ALLOW_THREADS
2962#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002963 /* on unix, success = 0, on windows, success = !0 */
2964 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002965#else
2966#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002967 if (path->fd != -1)
2968 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002969 else
2970#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002971 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002972#endif
2973 Py_END_ALLOW_THREADS
2974
2975 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002976 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002977 }
2978
Larry Hastings2f936352014-08-05 14:04:04 +10002979 Py_RETURN_NONE;
2980}
2981
2982
2983#ifdef HAVE_FCHDIR
2984/*[clinic input]
2985os.fchdir
2986
2987 fd: fildes
2988
2989Change to the directory of the given file descriptor.
2990
2991fd must be opened on a directory, not a file.
2992Equivalent to os.chdir(fd).
2993
2994[clinic start generated code]*/
2995
Fred Drake4d1e64b2002-04-15 19:40:07 +00002996static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002997os_fchdir_impl(PyObject *module, int fd)
2998/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002999{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003000 if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
3001 return NULL;
3002 }
Larry Hastings2f936352014-08-05 14:04:04 +10003003 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00003004}
3005#endif /* HAVE_FCHDIR */
3006
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003007
Larry Hastings2f936352014-08-05 14:04:04 +10003008/*[clinic input]
3009os.chmod
3010
3011 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00003012 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10003013 On some platforms, path may also be specified as an open file descriptor.
3014 If this functionality is unavailable, using it raises an exception.
3015
3016 mode: int
3017 Operating-system mode bitfield.
3018
3019 *
3020
3021 dir_fd : dir_fd(requires='fchmodat') = None
3022 If not None, it should be a file descriptor open to a directory,
3023 and path should be relative; path will then be relative to that
3024 directory.
3025
3026 follow_symlinks: bool = True
3027 If False, and the last element of the path is a symbolic link,
3028 chmod will modify the symbolic link itself instead of the file
3029 the link points to.
3030
3031Change the access permissions of a file.
3032
3033It is an error to use dir_fd or follow_symlinks when specifying path as
3034 an open file descriptor.
3035dir_fd and follow_symlinks may not be implemented on your platform.
3036 If they are unavailable, using them will raise a NotImplementedError.
3037
3038[clinic start generated code]*/
3039
Larry Hastings2f936352014-08-05 14:04:04 +10003040static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003041os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003042 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003043/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003044{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003045 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003046
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003047#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003048 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003049#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003050
Larry Hastings9cf065c2012-06-22 16:30:09 -07003051#ifdef HAVE_FCHMODAT
3052 int fchmodat_nofollow_unsupported = 0;
3053#endif
3054
Larry Hastings9cf065c2012-06-22 16:30:09 -07003055#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3056 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003057 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003058#endif
3059
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003060 if (PySys_Audit("os.chmod", "Oii", path->object, mode,
3061 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3062 return NULL;
3063 }
3064
Larry Hastings9cf065c2012-06-22 16:30:09 -07003065#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003066 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003067 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003068 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003069 result = 0;
3070 else {
3071 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003072 attr &= ~FILE_ATTRIBUTE_READONLY;
3073 else
3074 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003075 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003076 }
3077 Py_END_ALLOW_THREADS
3078
3079 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003080 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003081 }
3082#else /* MS_WINDOWS */
3083 Py_BEGIN_ALLOW_THREADS
3084#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003085 if (path->fd != -1)
3086 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087 else
3088#endif
3089#ifdef HAVE_LCHMOD
3090 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003091 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003092 else
3093#endif
3094#ifdef HAVE_FCHMODAT
3095 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
3096 /*
3097 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3098 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003099 * and then says it isn't implemented yet.
3100 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003101 *
3102 * Once it is supported, os.chmod will automatically
3103 * support dir_fd and follow_symlinks=False. (Hopefully.)
3104 * Until then, we need to be careful what exception we raise.
3105 */
Larry Hastings2f936352014-08-05 14:04:04 +10003106 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003107 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3108 /*
3109 * But wait! We can't throw the exception without allowing threads,
3110 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3111 */
3112 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003113 result &&
3114 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3115 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003116 }
3117 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003118#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003119 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003120 Py_END_ALLOW_THREADS
3121
3122 if (result) {
3123#ifdef HAVE_FCHMODAT
3124 if (fchmodat_nofollow_unsupported) {
3125 if (dir_fd != DEFAULT_DIR_FD)
3126 dir_fd_and_follow_symlinks_invalid("chmod",
3127 dir_fd, follow_symlinks);
3128 else
3129 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003130 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003131 }
3132 else
3133#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003134 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003135 }
3136#endif
3137
Larry Hastings2f936352014-08-05 14:04:04 +10003138 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003139}
3140
Larry Hastings9cf065c2012-06-22 16:30:09 -07003141
Christian Heimes4e30a842007-11-30 22:12:06 +00003142#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003143/*[clinic input]
3144os.fchmod
3145
3146 fd: int
3147 mode: int
3148
3149Change the access permissions of the file given by file descriptor fd.
3150
3151Equivalent to os.chmod(fd, mode).
3152[clinic start generated code]*/
3153
Larry Hastings2f936352014-08-05 14:04:04 +10003154static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003155os_fchmod_impl(PyObject *module, int fd, int mode)
3156/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003157{
3158 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003159 int async_err = 0;
3160
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003161 if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
3162 return NULL;
3163 }
3164
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003165 do {
3166 Py_BEGIN_ALLOW_THREADS
3167 res = fchmod(fd, mode);
3168 Py_END_ALLOW_THREADS
3169 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3170 if (res != 0)
3171 return (!async_err) ? posix_error() : NULL;
3172
Victor Stinner8c62be82010-05-06 00:08:46 +00003173 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003174}
3175#endif /* HAVE_FCHMOD */
3176
Larry Hastings2f936352014-08-05 14:04:04 +10003177
Christian Heimes4e30a842007-11-30 22:12:06 +00003178#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003179/*[clinic input]
3180os.lchmod
3181
3182 path: path_t
3183 mode: int
3184
3185Change the access permissions of a file, without following symbolic links.
3186
3187If path is a symlink, this affects the link itself rather than the target.
3188Equivalent to chmod(path, mode, follow_symlinks=False)."
3189[clinic start generated code]*/
3190
Larry Hastings2f936352014-08-05 14:04:04 +10003191static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003192os_lchmod_impl(PyObject *module, path_t *path, int mode)
3193/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003194{
Victor Stinner8c62be82010-05-06 00:08:46 +00003195 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003196 if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3197 return NULL;
3198 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003199 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003200 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003201 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003202 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003203 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003204 return NULL;
3205 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003206 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003207}
3208#endif /* HAVE_LCHMOD */
3209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003210
Thomas Wouterscf297e42007-02-23 15:07:44 +00003211#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003212/*[clinic input]
3213os.chflags
3214
3215 path: path_t
3216 flags: unsigned_long(bitwise=True)
3217 follow_symlinks: bool=True
3218
3219Set file flags.
3220
3221If follow_symlinks is False, and the last element of the path is a symbolic
3222 link, chflags will change flags on the symbolic link itself instead of the
3223 file the link points to.
3224follow_symlinks may not be implemented on your platform. If it is
3225unavailable, using it will raise a NotImplementedError.
3226
3227[clinic start generated code]*/
3228
Larry Hastings2f936352014-08-05 14:04:04 +10003229static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003230os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003231 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003232/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003233{
3234 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003235
3236#ifndef HAVE_LCHFLAGS
3237 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003238 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003239#endif
3240
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003241 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3242 return NULL;
3243 }
3244
Victor Stinner8c62be82010-05-06 00:08:46 +00003245 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003246#ifdef HAVE_LCHFLAGS
3247 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003248 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003249 else
3250#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003251 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003252 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003253
Larry Hastings2f936352014-08-05 14:04:04 +10003254 if (result)
3255 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256
Larry Hastings2f936352014-08-05 14:04:04 +10003257 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003258}
3259#endif /* HAVE_CHFLAGS */
3260
Larry Hastings2f936352014-08-05 14:04:04 +10003261
Thomas Wouterscf297e42007-02-23 15:07:44 +00003262#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003263/*[clinic input]
3264os.lchflags
3265
3266 path: path_t
3267 flags: unsigned_long(bitwise=True)
3268
3269Set file flags.
3270
3271This function will not follow symbolic links.
3272Equivalent to chflags(path, flags, follow_symlinks=False).
3273[clinic start generated code]*/
3274
Larry Hastings2f936352014-08-05 14:04:04 +10003275static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003276os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3277/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003278{
Victor Stinner8c62be82010-05-06 00:08:46 +00003279 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003280 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3281 return NULL;
3282 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003283 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003284 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003285 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003286 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003287 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003288 }
Victor Stinner292c8352012-10-30 02:17:38 +01003289 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003290}
3291#endif /* HAVE_LCHFLAGS */
3292
Larry Hastings2f936352014-08-05 14:04:04 +10003293
Martin v. Löwis244edc82001-10-04 22:44:26 +00003294#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003295/*[clinic input]
3296os.chroot
3297 path: path_t
3298
3299Change root directory to path.
3300
3301[clinic start generated code]*/
3302
Larry Hastings2f936352014-08-05 14:04:04 +10003303static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003304os_chroot_impl(PyObject *module, path_t *path)
3305/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003306{
3307 int res;
3308 Py_BEGIN_ALLOW_THREADS
3309 res = chroot(path->narrow);
3310 Py_END_ALLOW_THREADS
3311 if (res < 0)
3312 return path_error(path);
3313 Py_RETURN_NONE;
3314}
3315#endif /* HAVE_CHROOT */
3316
Martin v. Löwis244edc82001-10-04 22:44:26 +00003317
Guido van Rossum21142a01999-01-08 21:05:37 +00003318#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003319/*[clinic input]
3320os.fsync
3321
3322 fd: fildes
3323
3324Force write of fd to disk.
3325[clinic start generated code]*/
3326
Larry Hastings2f936352014-08-05 14:04:04 +10003327static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003328os_fsync_impl(PyObject *module, int fd)
3329/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003330{
3331 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003332}
3333#endif /* HAVE_FSYNC */
3334
Larry Hastings2f936352014-08-05 14:04:04 +10003335
Ross Lagerwall7807c352011-03-17 20:20:30 +02003336#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003337/*[clinic input]
3338os.sync
3339
3340Force write of everything to disk.
3341[clinic start generated code]*/
3342
Larry Hastings2f936352014-08-05 14:04:04 +10003343static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003344os_sync_impl(PyObject *module)
3345/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003346{
3347 Py_BEGIN_ALLOW_THREADS
3348 sync();
3349 Py_END_ALLOW_THREADS
3350 Py_RETURN_NONE;
3351}
Larry Hastings2f936352014-08-05 14:04:04 +10003352#endif /* HAVE_SYNC */
3353
Ross Lagerwall7807c352011-03-17 20:20:30 +02003354
Guido van Rossum21142a01999-01-08 21:05:37 +00003355#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003356#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003357extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3358#endif
3359
Larry Hastings2f936352014-08-05 14:04:04 +10003360/*[clinic input]
3361os.fdatasync
3362
3363 fd: fildes
3364
3365Force write of fd to disk without forcing update of metadata.
3366[clinic start generated code]*/
3367
Larry Hastings2f936352014-08-05 14:04:04 +10003368static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003369os_fdatasync_impl(PyObject *module, int fd)
3370/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003371{
3372 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003373}
3374#endif /* HAVE_FDATASYNC */
3375
3376
Fredrik Lundh10723342000-07-10 16:38:09 +00003377#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003378/*[clinic input]
3379os.chown
3380
3381 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003382 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003383
3384 uid: uid_t
3385
3386 gid: gid_t
3387
3388 *
3389
3390 dir_fd : dir_fd(requires='fchownat') = None
3391 If not None, it should be a file descriptor open to a directory,
3392 and path should be relative; path will then be relative to that
3393 directory.
3394
3395 follow_symlinks: bool = True
3396 If False, and the last element of the path is a symbolic link,
3397 stat will examine the symbolic link itself instead of the file
3398 the link points to.
3399
3400Change the owner and group id of path to the numeric uid and gid.\
3401
3402path may always be specified as a string.
3403On some platforms, path may also be specified as an open file descriptor.
3404 If this functionality is unavailable, using it raises an exception.
3405If dir_fd is not None, it should be a file descriptor open to a directory,
3406 and path should be relative; path will then be relative to that directory.
3407If follow_symlinks is False, and the last element of the path is a symbolic
3408 link, chown will modify the symbolic link itself instead of the file the
3409 link points to.
3410It is an error to use dir_fd or follow_symlinks when specifying path as
3411 an open file descriptor.
3412dir_fd and follow_symlinks may not be implemented on your platform.
3413 If they are unavailable, using them will raise a NotImplementedError.
3414
3415[clinic start generated code]*/
3416
Larry Hastings2f936352014-08-05 14:04:04 +10003417static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003418os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003419 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003420/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003421{
3422 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423
3424#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3425 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003426 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003428 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3429 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3430 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431
3432#ifdef __APPLE__
3433 /*
3434 * This is for Mac OS X 10.3, which doesn't have lchown.
3435 * (But we still have an lchown symbol because of weak-linking.)
3436 * It doesn't have fchownat either. So there's no possibility
3437 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003438 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003439 if ((!follow_symlinks) && (lchown == NULL)) {
3440 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003441 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003442 }
3443#endif
3444
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003445 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
3446 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3447 return NULL;
3448 }
3449
Victor Stinner8c62be82010-05-06 00:08:46 +00003450 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003451#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003452 if (path->fd != -1)
3453 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003454 else
3455#endif
3456#ifdef HAVE_LCHOWN
3457 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003458 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003459 else
3460#endif
3461#ifdef HAVE_FCHOWNAT
3462 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003463 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003464 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3465 else
3466#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003467 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003468 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469
Larry Hastings2f936352014-08-05 14:04:04 +10003470 if (result)
3471 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003472
Larry Hastings2f936352014-08-05 14:04:04 +10003473 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003474}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003475#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003476
Larry Hastings2f936352014-08-05 14:04:04 +10003477
Christian Heimes4e30a842007-11-30 22:12:06 +00003478#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003479/*[clinic input]
3480os.fchown
3481
3482 fd: int
3483 uid: uid_t
3484 gid: gid_t
3485
3486Change the owner and group id of the file specified by file descriptor.
3487
3488Equivalent to os.chown(fd, uid, gid).
3489
3490[clinic start generated code]*/
3491
Larry Hastings2f936352014-08-05 14:04:04 +10003492static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003493os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3494/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003495{
Victor Stinner8c62be82010-05-06 00:08:46 +00003496 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003497 int async_err = 0;
3498
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003499 if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
3500 return NULL;
3501 }
3502
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003503 do {
3504 Py_BEGIN_ALLOW_THREADS
3505 res = fchown(fd, uid, gid);
3506 Py_END_ALLOW_THREADS
3507 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3508 if (res != 0)
3509 return (!async_err) ? posix_error() : NULL;
3510
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003512}
3513#endif /* HAVE_FCHOWN */
3514
Larry Hastings2f936352014-08-05 14:04:04 +10003515
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003516#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003517/*[clinic input]
3518os.lchown
3519
3520 path : path_t
3521 uid: uid_t
3522 gid: gid_t
3523
3524Change the owner and group id of path to the numeric uid and gid.
3525
3526This function will not follow symbolic links.
3527Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3528[clinic start generated code]*/
3529
Larry Hastings2f936352014-08-05 14:04:04 +10003530static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003531os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3532/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003533{
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003535 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
3536 return NULL;
3537 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003538 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003539 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003541 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003542 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003543 }
Larry Hastings2f936352014-08-05 14:04:04 +10003544 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003545}
3546#endif /* HAVE_LCHOWN */
3547
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003548
Barry Warsaw53699e91996-12-10 23:23:01 +00003549static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003550posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003551{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003552#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003553 wchar_t wbuf[MAXPATHLEN];
3554 wchar_t *wbuf2 = wbuf;
3555 DWORD len;
3556
3557 Py_BEGIN_ALLOW_THREADS
3558 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3559 /* If the buffer is large enough, len does not include the
3560 terminating \0. If the buffer is too small, len includes
3561 the space needed for the terminator. */
3562 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003563 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003564 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 }
Victor Stinner689830e2019-06-26 17:31:12 +02003566 else {
3567 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003568 }
Victor Stinner689830e2019-06-26 17:31:12 +02003569 if (wbuf2) {
3570 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 }
Victor Stinner689830e2019-06-26 17:31:12 +02003572 }
3573 Py_END_ALLOW_THREADS
3574
3575 if (!wbuf2) {
3576 PyErr_NoMemory();
3577 return NULL;
3578 }
3579 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003580 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003581 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003582 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003583 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003584
Victor Stinner689830e2019-06-26 17:31:12 +02003585 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3586 if (wbuf2 != wbuf) {
3587 PyMem_RawFree(wbuf2);
3588 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003589
Victor Stinner689830e2019-06-26 17:31:12 +02003590 if (use_bytes) {
3591 if (resobj == NULL) {
3592 return NULL;
3593 }
3594 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3595 }
3596
3597 return resobj;
3598#else
3599 const size_t chunk = 1024;
3600
3601 char *buf = NULL;
3602 char *cwd = NULL;
3603 size_t buflen = 0;
3604
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003606 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003607 char *newbuf;
3608 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3609 buflen += chunk;
3610 newbuf = PyMem_RawRealloc(buf, buflen);
3611 }
3612 else {
3613 newbuf = NULL;
3614 }
3615 if (newbuf == NULL) {
3616 PyMem_RawFree(buf);
3617 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003618 break;
3619 }
Victor Stinner689830e2019-06-26 17:31:12 +02003620 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003621
Victor Stinner4403d7d2015-04-25 00:16:10 +02003622 cwd = getcwd(buf, buflen);
3623 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003625
Victor Stinner689830e2019-06-26 17:31:12 +02003626 if (buf == NULL) {
3627 return PyErr_NoMemory();
3628 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003629 if (cwd == NULL) {
3630 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003631 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003632 }
3633
Victor Stinner689830e2019-06-26 17:31:12 +02003634 PyObject *obj;
3635 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003636 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003637 }
3638 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003639 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003640 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003641 PyMem_RawFree(buf);
3642
3643 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003644#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003645}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003646
Larry Hastings2f936352014-08-05 14:04:04 +10003647
3648/*[clinic input]
3649os.getcwd
3650
3651Return a unicode string representing the current working directory.
3652[clinic start generated code]*/
3653
Larry Hastings2f936352014-08-05 14:04:04 +10003654static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003655os_getcwd_impl(PyObject *module)
3656/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003657{
3658 return posix_getcwd(0);
3659}
3660
Larry Hastings2f936352014-08-05 14:04:04 +10003661
3662/*[clinic input]
3663os.getcwdb
3664
3665Return a bytes string representing the current working directory.
3666[clinic start generated code]*/
3667
Larry Hastings2f936352014-08-05 14:04:04 +10003668static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003669os_getcwdb_impl(PyObject *module)
3670/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003671{
3672 return posix_getcwd(1);
3673}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003674
Larry Hastings2f936352014-08-05 14:04:04 +10003675
Larry Hastings9cf065c2012-06-22 16:30:09 -07003676#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3677#define HAVE_LINK 1
3678#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003679
Guido van Rossumb6775db1994-08-01 11:34:53 +00003680#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003681/*[clinic input]
3682
3683os.link
3684
3685 src : path_t
3686 dst : path_t
3687 *
3688 src_dir_fd : dir_fd = None
3689 dst_dir_fd : dir_fd = None
3690 follow_symlinks: bool = True
3691
3692Create a hard link to a file.
3693
3694If either src_dir_fd or dst_dir_fd is not None, it should be a file
3695 descriptor open to a directory, and the respective path string (src or dst)
3696 should be relative; the path will then be relative to that directory.
3697If follow_symlinks is False, and the last element of src is a symbolic
3698 link, link will create a link to the symbolic link itself instead of the
3699 file the link points to.
3700src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3701 platform. If they are unavailable, using them will raise a
3702 NotImplementedError.
3703[clinic start generated code]*/
3704
Larry Hastings2f936352014-08-05 14:04:04 +10003705static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003706os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003707 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003708/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003709{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003711 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003712#else
3713 int result;
3714#endif
3715
Larry Hastings9cf065c2012-06-22 16:30:09 -07003716#ifndef HAVE_LINKAT
3717 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3718 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003719 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003720 }
3721#endif
3722
Steve Dowercc16be82016-09-08 10:35:16 -07003723#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003724 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003725 PyErr_SetString(PyExc_NotImplementedError,
3726 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003727 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 }
Steve Dowercc16be82016-09-08 10:35:16 -07003729#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003730
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003731 if (PySys_Audit("os.link", "OOii", src->object, dst->object,
3732 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
3733 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
3734 return NULL;
3735 }
3736
Brian Curtin1b9df392010-11-24 20:24:31 +00003737#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003738 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003739 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003740 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003741
Larry Hastings2f936352014-08-05 14:04:04 +10003742 if (!result)
3743 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003744#else
3745 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003746#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003747 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3748 (dst_dir_fd != DEFAULT_DIR_FD) ||
3749 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003750 result = linkat(src_dir_fd, src->narrow,
3751 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003752 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3753 else
Steve Dowercc16be82016-09-08 10:35:16 -07003754#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003755 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003756 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003757
Larry Hastings2f936352014-08-05 14:04:04 +10003758 if (result)
3759 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003760#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003761
Larry Hastings2f936352014-08-05 14:04:04 +10003762 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003763}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003764#endif
3765
Brian Curtin1b9df392010-11-24 20:24:31 +00003766
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003767#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003768static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003769_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003770{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003771 PyObject *v;
3772 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3773 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003774 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003775 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003776 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003777 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003778
Steve Dowercc16be82016-09-08 10:35:16 -07003779 WIN32_FIND_DATAW wFileData;
3780 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003781
Steve Dowercc16be82016-09-08 10:35:16 -07003782 if (!path->wide) { /* Default arg: "." */
3783 po_wchars = L".";
3784 len = 1;
3785 } else {
3786 po_wchars = path->wide;
3787 len = wcslen(path->wide);
3788 }
3789 /* The +5 is so we can append "\\*.*\0" */
3790 wnamebuf = PyMem_New(wchar_t, len + 5);
3791 if (!wnamebuf) {
3792 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003793 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003794 }
Steve Dowercc16be82016-09-08 10:35:16 -07003795 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003796 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003797 wchar_t wch = wnamebuf[len-1];
3798 if (wch != SEP && wch != ALTSEP && wch != L':')
3799 wnamebuf[len++] = SEP;
3800 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003801 }
Steve Dowercc16be82016-09-08 10:35:16 -07003802 if ((list = PyList_New(0)) == NULL) {
3803 goto exit;
3804 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003805 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003806 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003807 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003808 if (hFindFile == INVALID_HANDLE_VALUE) {
3809 int error = GetLastError();
3810 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003811 goto exit;
3812 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003813 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003814 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003815 }
3816 do {
3817 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003818 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3819 wcscmp(wFileData.cFileName, L"..") != 0) {
3820 v = PyUnicode_FromWideChar(wFileData.cFileName,
3821 wcslen(wFileData.cFileName));
3822 if (path->narrow && v) {
3823 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3824 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003825 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003826 Py_DECREF(list);
3827 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003828 break;
3829 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003830 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003831 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003832 Py_DECREF(list);
3833 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003834 break;
3835 }
3836 Py_DECREF(v);
3837 }
3838 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003839 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003840 Py_END_ALLOW_THREADS
3841 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3842 it got to the end of the directory. */
3843 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003844 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003845 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003846 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003847 }
3848 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003849
Larry Hastings9cf065c2012-06-22 16:30:09 -07003850exit:
3851 if (hFindFile != INVALID_HANDLE_VALUE) {
3852 if (FindClose(hFindFile) == FALSE) {
3853 if (list != NULL) {
3854 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003855 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003856 }
3857 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003858 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003859 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003860
Larry Hastings9cf065c2012-06-22 16:30:09 -07003861 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003862} /* end of _listdir_windows_no_opendir */
3863
3864#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3865
3866static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003867_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003868{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003869 PyObject *v;
3870 DIR *dirp = NULL;
3871 struct dirent *ep;
3872 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003873#ifdef HAVE_FDOPENDIR
3874 int fd = -1;
3875#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003876
Victor Stinner8c62be82010-05-06 00:08:46 +00003877 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003878#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003879 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003880 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003881 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003882 if (fd == -1)
3883 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003884
Larry Hastingsfdaea062012-06-25 04:42:23 -07003885 return_str = 1;
3886
Larry Hastings9cf065c2012-06-22 16:30:09 -07003887 Py_BEGIN_ALLOW_THREADS
3888 dirp = fdopendir(fd);
3889 Py_END_ALLOW_THREADS
3890 }
3891 else
3892#endif
3893 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003894 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003895 if (path->narrow) {
3896 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003897 /* only return bytes if they specified a bytes-like object */
3898 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003899 }
3900 else {
3901 name = ".";
3902 return_str = 1;
3903 }
3904
Larry Hastings9cf065c2012-06-22 16:30:09 -07003905 Py_BEGIN_ALLOW_THREADS
3906 dirp = opendir(name);
3907 Py_END_ALLOW_THREADS
3908 }
3909
3910 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003911 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003912#ifdef HAVE_FDOPENDIR
3913 if (fd != -1) {
3914 Py_BEGIN_ALLOW_THREADS
3915 close(fd);
3916 Py_END_ALLOW_THREADS
3917 }
3918#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003919 goto exit;
3920 }
3921 if ((list = PyList_New(0)) == NULL) {
3922 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003923 }
3924 for (;;) {
3925 errno = 0;
3926 Py_BEGIN_ALLOW_THREADS
3927 ep = readdir(dirp);
3928 Py_END_ALLOW_THREADS
3929 if (ep == NULL) {
3930 if (errno == 0) {
3931 break;
3932 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003933 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003934 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003935 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003936 }
3937 }
3938 if (ep->d_name[0] == '.' &&
3939 (NAMLEN(ep) == 1 ||
3940 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3941 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003942 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003943 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3944 else
3945 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003946 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003947 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003948 break;
3949 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003950 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003951 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003952 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003953 break;
3954 }
3955 Py_DECREF(v);
3956 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003957
Larry Hastings9cf065c2012-06-22 16:30:09 -07003958exit:
3959 if (dirp != NULL) {
3960 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003961#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003962 if (fd > -1)
3963 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003964#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003965 closedir(dirp);
3966 Py_END_ALLOW_THREADS
3967 }
3968
Larry Hastings9cf065c2012-06-22 16:30:09 -07003969 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003970} /* end of _posix_listdir */
3971#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003972
Larry Hastings2f936352014-08-05 14:04:04 +10003973
3974/*[clinic input]
3975os.listdir
3976
3977 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3978
3979Return a list containing the names of the files in the directory.
3980
BNMetricsb9427072018-11-02 15:20:19 +00003981path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003982 the filenames returned will also be bytes; in all other circumstances
3983 the filenames returned will be str.
3984If path is None, uses the path='.'.
3985On some platforms, path may also be specified as an open file descriptor;\
3986 the file descriptor must refer to a directory.
3987 If this functionality is unavailable, using it raises NotImplementedError.
3988
3989The list is in arbitrary order. It does not include the special
3990entries '.' and '..' even if they are present in the directory.
3991
3992
3993[clinic start generated code]*/
3994
Larry Hastings2f936352014-08-05 14:04:04 +10003995static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003996os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003997/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003998{
Steve Dower60419a72019-06-24 08:42:54 -07003999 if (PySys_Audit("os.listdir", "O",
4000 path->object ? path->object : Py_None) < 0) {
4001 return NULL;
4002 }
Larry Hastings2f936352014-08-05 14:04:04 +10004003#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4004 return _listdir_windows_no_opendir(path, NULL);
4005#else
4006 return _posix_listdir(path, NULL);
4007#endif
4008}
4009
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004010#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00004011/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004012/*[clinic input]
4013os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02004014
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004015 path: path_t
4016 /
4017
4018[clinic start generated code]*/
4019
4020static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004021os__getfullpathname_impl(PyObject *module, path_t *path)
4022/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004023{
Victor Stinner3939c322019-06-25 15:02:43 +02004024 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004025
Victor Stinner3939c322019-06-25 15:02:43 +02004026 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
4027 if (_Py_abspath(path->wide, &abspath) < 0) {
4028 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00004029 }
Victor Stinner3939c322019-06-25 15:02:43 +02004030 if (abspath == NULL) {
4031 return PyErr_NoMemory();
4032 }
4033
4034 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
4035 PyMem_RawFree(abspath);
4036 if (str == NULL) {
4037 return NULL;
4038 }
4039 if (path->narrow) {
4040 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
4041 }
4042 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10004043}
Brian Curtind40e6f72010-07-08 21:39:08 +00004044
Brian Curtind25aef52011-06-13 15:16:04 -05004045
Larry Hastings2f936352014-08-05 14:04:04 +10004046/*[clinic input]
4047os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004048
Steve Dower23ad6d02018-02-22 10:39:10 -08004049 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004050 /
4051
4052A helper function for samepath on windows.
4053[clinic start generated code]*/
4054
Larry Hastings2f936352014-08-05 14:04:04 +10004055static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004056os__getfinalpathname_impl(PyObject *module, path_t *path)
4057/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004058{
4059 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004060 wchar_t buf[MAXPATHLEN], *target_path = buf;
4061 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00004062 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004063 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004064
Steve Dower23ad6d02018-02-22 10:39:10 -08004065 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004066 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08004067 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004068 0, /* desired access */
4069 0, /* share mode */
4070 NULL, /* security attributes */
4071 OPEN_EXISTING,
4072 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4073 FILE_FLAG_BACKUP_SEMANTICS,
4074 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004075 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004076
Steve Dower23ad6d02018-02-22 10:39:10 -08004077 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004078 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004079 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004080
4081 /* We have a good handle to the target, use it to determine the
4082 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004083 while (1) {
4084 Py_BEGIN_ALLOW_THREADS
4085 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4086 buf_size, VOLUME_NAME_DOS);
4087 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004088
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004089 if (!result_length) {
4090 result = win32_error_object("GetFinalPathNameByHandleW",
4091 path->object);
4092 goto cleanup;
4093 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004094
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004095 if (result_length < buf_size) {
4096 break;
4097 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004098
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004099 wchar_t *tmp;
4100 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4101 result_length * sizeof(*tmp));
4102 if (!tmp) {
4103 result = PyErr_NoMemory();
4104 goto cleanup;
4105 }
4106
4107 buf_size = result_length;
4108 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004109 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004110
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004111 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004112 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004113 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004114 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004115
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004116cleanup:
4117 if (target_path != buf) {
4118 PyMem_Free(target_path);
4119 }
4120 CloseHandle(hFile);
4121 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004122}
Brian Curtin62857742010-09-06 17:07:27 +00004123
Tim Golden6b528062013-08-01 12:44:00 +01004124
Larry Hastings2f936352014-08-05 14:04:04 +10004125/*[clinic input]
4126os._getvolumepathname
4127
Steve Dower23ad6d02018-02-22 10:39:10 -08004128 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004129
4130A helper function for ismount on Win32.
4131[clinic start generated code]*/
4132
Larry Hastings2f936352014-08-05 14:04:04 +10004133static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004134os__getvolumepathname_impl(PyObject *module, path_t *path)
4135/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004136{
4137 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004138 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004139 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004140 BOOL ret;
4141
Tim Golden6b528062013-08-01 12:44:00 +01004142 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004143 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004144
Victor Stinner850a18e2017-10-24 16:53:32 -07004145 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004146 PyErr_SetString(PyExc_OverflowError, "path too long");
4147 return NULL;
4148 }
4149
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004150 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004151 if (mountpath == NULL)
4152 return PyErr_NoMemory();
4153
4154 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004155 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004156 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004157 Py_END_ALLOW_THREADS
4158
4159 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004160 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004161 goto exit;
4162 }
4163 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004164 if (path->narrow)
4165 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004166
4167exit:
4168 PyMem_Free(mountpath);
4169 return result;
4170}
Tim Golden6b528062013-08-01 12:44:00 +01004171
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004172#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004173
Larry Hastings2f936352014-08-05 14:04:04 +10004174
4175/*[clinic input]
4176os.mkdir
4177
4178 path : path_t
4179
4180 mode: int = 0o777
4181
4182 *
4183
4184 dir_fd : dir_fd(requires='mkdirat') = None
4185
4186# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4187
4188Create a directory.
4189
4190If dir_fd is not None, it should be a file descriptor open to a directory,
4191 and path should be relative; path will then be relative to that directory.
4192dir_fd may not be implemented on your platform.
4193 If it is unavailable, using it will raise a NotImplementedError.
4194
4195The mode argument is ignored on Windows.
4196[clinic start generated code]*/
4197
Larry Hastings2f936352014-08-05 14:04:04 +10004198static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004199os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4200/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004201{
4202 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004203
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004204 if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
4205 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4206 return NULL;
4207 }
4208
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004209#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004210 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004211 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004212 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004213
Larry Hastings2f936352014-08-05 14:04:04 +10004214 if (!result)
4215 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004216#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004217 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004218#if HAVE_MKDIRAT
4219 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004220 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004221 else
4222#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004223#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004224 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004225#else
Larry Hastings2f936352014-08-05 14:04:04 +10004226 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004227#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004228 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004229 if (result < 0)
4230 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004231#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004232 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004233}
4234
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004235
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004236/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4237#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004238#include <sys/resource.h>
4239#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004240
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004241
4242#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004243/*[clinic input]
4244os.nice
4245
4246 increment: int
4247 /
4248
4249Add increment to the priority of process and return the new priority.
4250[clinic start generated code]*/
4251
Larry Hastings2f936352014-08-05 14:04:04 +10004252static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004253os_nice_impl(PyObject *module, int increment)
4254/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004255{
4256 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004257
Victor Stinner8c62be82010-05-06 00:08:46 +00004258 /* There are two flavours of 'nice': one that returns the new
4259 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004260 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004261 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004262
Victor Stinner8c62be82010-05-06 00:08:46 +00004263 If we are of the nice family that returns the new priority, we
4264 need to clear errno before the call, and check if errno is filled
4265 before calling posix_error() on a returnvalue of -1, because the
4266 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004267
Victor Stinner8c62be82010-05-06 00:08:46 +00004268 errno = 0;
4269 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004270#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004271 if (value == 0)
4272 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004273#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004274 if (value == -1 && errno != 0)
4275 /* either nice() or getpriority() returned an error */
4276 return posix_error();
4277 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004278}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004279#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004280
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004281
4282#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004283/*[clinic input]
4284os.getpriority
4285
4286 which: int
4287 who: int
4288
4289Return program scheduling priority.
4290[clinic start generated code]*/
4291
Larry Hastings2f936352014-08-05 14:04:04 +10004292static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004293os_getpriority_impl(PyObject *module, int which, int who)
4294/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004295{
4296 int retval;
4297
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004298 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004299 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004300 if (errno != 0)
4301 return posix_error();
4302 return PyLong_FromLong((long)retval);
4303}
4304#endif /* HAVE_GETPRIORITY */
4305
4306
4307#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004308/*[clinic input]
4309os.setpriority
4310
4311 which: int
4312 who: int
4313 priority: int
4314
4315Set program scheduling priority.
4316[clinic start generated code]*/
4317
Larry Hastings2f936352014-08-05 14:04:04 +10004318static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004319os_setpriority_impl(PyObject *module, int which, int who, int priority)
4320/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004321{
4322 int retval;
4323
4324 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004325 if (retval == -1)
4326 return posix_error();
4327 Py_RETURN_NONE;
4328}
4329#endif /* HAVE_SETPRIORITY */
4330
4331
Barry Warsaw53699e91996-12-10 23:23:01 +00004332static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004333internal_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 +00004334{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004335 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004336 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004337
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004338#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004339 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004340 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004341#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004342 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004343#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004344
Larry Hastings9cf065c2012-06-22 16:30:09 -07004345 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4346 (dst_dir_fd != DEFAULT_DIR_FD);
4347#ifndef HAVE_RENAMEAT
4348 if (dir_fd_specified) {
4349 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004350 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004351 }
4352#endif
4353
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004354 if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
4355 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
4356 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
4357 return NULL;
4358 }
4359
Larry Hastings9cf065c2012-06-22 16:30:09 -07004360#ifdef MS_WINDOWS
4361 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004362 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004363 Py_END_ALLOW_THREADS
4364
Larry Hastings2f936352014-08-05 14:04:04 +10004365 if (!result)
4366 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004367
4368#else
Steve Dowercc16be82016-09-08 10:35:16 -07004369 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4370 PyErr_Format(PyExc_ValueError,
4371 "%s: src and dst must be the same type", function_name);
4372 return NULL;
4373 }
4374
Larry Hastings9cf065c2012-06-22 16:30:09 -07004375 Py_BEGIN_ALLOW_THREADS
4376#ifdef HAVE_RENAMEAT
4377 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004378 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004379 else
4380#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004381 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004382 Py_END_ALLOW_THREADS
4383
Larry Hastings2f936352014-08-05 14:04:04 +10004384 if (result)
4385 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004387 Py_RETURN_NONE;
4388}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004389
Larry Hastings2f936352014-08-05 14:04:04 +10004390
4391/*[clinic input]
4392os.rename
4393
4394 src : path_t
4395 dst : path_t
4396 *
4397 src_dir_fd : dir_fd = None
4398 dst_dir_fd : dir_fd = None
4399
4400Rename a file or directory.
4401
4402If either src_dir_fd or dst_dir_fd is not None, it should be a file
4403 descriptor open to a directory, and the respective path string (src or dst)
4404 should be relative; the path will then be relative to that directory.
4405src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4406 If they are unavailable, using them will raise a NotImplementedError.
4407[clinic start generated code]*/
4408
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004409static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004410os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004411 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004412/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004413{
Larry Hastings2f936352014-08-05 14:04:04 +10004414 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004415}
4416
Larry Hastings2f936352014-08-05 14:04:04 +10004417
4418/*[clinic input]
4419os.replace = os.rename
4420
4421Rename a file or directory, overwriting the destination.
4422
4423If either src_dir_fd or dst_dir_fd is not None, it should be a file
4424 descriptor open to a directory, and the respective path string (src or dst)
4425 should be relative; the path will then be relative to that directory.
4426src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004427 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004428[clinic start generated code]*/
4429
Larry Hastings2f936352014-08-05 14:04:04 +10004430static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004431os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4432 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004433/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004434{
4435 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4436}
4437
4438
4439/*[clinic input]
4440os.rmdir
4441
4442 path: path_t
4443 *
4444 dir_fd: dir_fd(requires='unlinkat') = None
4445
4446Remove a directory.
4447
4448If dir_fd is not None, it should be a file descriptor open to a directory,
4449 and path should be relative; path will then be relative to that directory.
4450dir_fd may not be implemented on your platform.
4451 If it is unavailable, using it will raise a NotImplementedError.
4452[clinic start generated code]*/
4453
Larry Hastings2f936352014-08-05 14:04:04 +10004454static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004455os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4456/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004457{
4458 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004459
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004460 if (PySys_Audit("os.rmdir", "Oi", path->object,
4461 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4462 return NULL;
4463 }
4464
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004465 Py_BEGIN_ALLOW_THREADS
4466#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004467 /* Windows, success=1, UNIX, success=0 */
4468 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004469#else
4470#ifdef HAVE_UNLINKAT
4471 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004472 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004473 else
4474#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004475 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004476#endif
4477 Py_END_ALLOW_THREADS
4478
Larry Hastings2f936352014-08-05 14:04:04 +10004479 if (result)
4480 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004481
Larry Hastings2f936352014-08-05 14:04:04 +10004482 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004483}
4484
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004485
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004486#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004487#ifdef MS_WINDOWS
4488/*[clinic input]
4489os.system -> long
4490
4491 command: Py_UNICODE
4492
4493Execute the command in a subshell.
4494[clinic start generated code]*/
4495
Larry Hastings2f936352014-08-05 14:04:04 +10004496static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004497os_system_impl(PyObject *module, const Py_UNICODE *command)
4498/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004499{
4500 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004501
Steve Dowerfbe3c762019-10-18 00:52:15 -07004502 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004503 return -1;
4504 }
4505
Victor Stinner8c62be82010-05-06 00:08:46 +00004506 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004507 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004508 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004509 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004510 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004511 return result;
4512}
4513#else /* MS_WINDOWS */
4514/*[clinic input]
4515os.system -> long
4516
4517 command: FSConverter
4518
4519Execute the command in a subshell.
4520[clinic start generated code]*/
4521
Larry Hastings2f936352014-08-05 14:04:04 +10004522static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004523os_system_impl(PyObject *module, PyObject *command)
4524/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004525{
4526 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004527 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004528
Steve Dowerfbe3c762019-10-18 00:52:15 -07004529 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004530 return -1;
4531 }
4532
Larry Hastings2f936352014-08-05 14:04:04 +10004533 Py_BEGIN_ALLOW_THREADS
4534 result = system(bytes);
4535 Py_END_ALLOW_THREADS
4536 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004537}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004538#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004539#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004540
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004541
Larry Hastings2f936352014-08-05 14:04:04 +10004542/*[clinic input]
4543os.umask
4544
4545 mask: int
4546 /
4547
4548Set the current numeric umask and return the previous umask.
4549[clinic start generated code]*/
4550
Larry Hastings2f936352014-08-05 14:04:04 +10004551static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004552os_umask_impl(PyObject *module, int mask)
4553/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004554{
4555 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004556 if (i < 0)
4557 return posix_error();
4558 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004559}
4560
Brian Curtind40e6f72010-07-08 21:39:08 +00004561#ifdef MS_WINDOWS
4562
4563/* override the default DeleteFileW behavior so that directory
4564symlinks can be removed with this function, the same as with
4565Unix symlinks */
4566BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4567{
4568 WIN32_FILE_ATTRIBUTE_DATA info;
4569 WIN32_FIND_DATAW find_data;
4570 HANDLE find_data_handle;
4571 int is_directory = 0;
4572 int is_link = 0;
4573
4574 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4575 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004576
Brian Curtind40e6f72010-07-08 21:39:08 +00004577 /* Get WIN32_FIND_DATA structure for the path to determine if
4578 it is a symlink */
4579 if(is_directory &&
4580 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4581 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4582
4583 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004584 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4585 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4586 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4587 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004588 FindClose(find_data_handle);
4589 }
4590 }
4591 }
4592
4593 if (is_directory && is_link)
4594 return RemoveDirectoryW(lpFileName);
4595
4596 return DeleteFileW(lpFileName);
4597}
4598#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004600
Larry Hastings2f936352014-08-05 14:04:04 +10004601/*[clinic input]
4602os.unlink
4603
4604 path: path_t
4605 *
4606 dir_fd: dir_fd(requires='unlinkat')=None
4607
4608Remove a file (same as remove()).
4609
4610If dir_fd is not None, it should be a file descriptor open to a directory,
4611 and path should be relative; path will then be relative to that directory.
4612dir_fd may not be implemented on your platform.
4613 If it is unavailable, using it will raise a NotImplementedError.
4614
4615[clinic start generated code]*/
4616
Larry Hastings2f936352014-08-05 14:04:04 +10004617static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004618os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4619/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004620{
4621 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004622
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004623 if (PySys_Audit("os.remove", "Oi", path->object,
4624 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4625 return NULL;
4626 }
4627
Larry Hastings9cf065c2012-06-22 16:30:09 -07004628 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004629 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004631 /* Windows, success=1, UNIX, success=0 */
4632 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004633#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004634#ifdef HAVE_UNLINKAT
4635 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004636 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004637 else
4638#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004639 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004640#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004641 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004642 Py_END_ALLOW_THREADS
4643
Larry Hastings2f936352014-08-05 14:04:04 +10004644 if (result)
4645 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004646
Larry Hastings2f936352014-08-05 14:04:04 +10004647 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004648}
4649
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004650
Larry Hastings2f936352014-08-05 14:04:04 +10004651/*[clinic input]
4652os.remove = os.unlink
4653
4654Remove a file (same as unlink()).
4655
4656If dir_fd is not None, it should be a file descriptor open to a directory,
4657 and path should be relative; path will then be relative to that directory.
4658dir_fd may not be implemented on your platform.
4659 If it is unavailable, using it will raise a NotImplementedError.
4660[clinic start generated code]*/
4661
Larry Hastings2f936352014-08-05 14:04:04 +10004662static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004663os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4664/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004665{
4666 return os_unlink_impl(module, path, dir_fd);
4667}
4668
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004669
Larry Hastings605a62d2012-06-24 04:33:36 -07004670static PyStructSequence_Field uname_result_fields[] = {
4671 {"sysname", "operating system name"},
4672 {"nodename", "name of machine on network (implementation-defined)"},
4673 {"release", "operating system release"},
4674 {"version", "operating system version"},
4675 {"machine", "hardware identifier"},
4676 {NULL}
4677};
4678
4679PyDoc_STRVAR(uname_result__doc__,
4680"uname_result: Result from os.uname().\n\n\
4681This object may be accessed either as a tuple of\n\
4682 (sysname, nodename, release, version, machine),\n\
4683or via the attributes sysname, nodename, release, version, and machine.\n\
4684\n\
4685See os.uname for more information.");
4686
4687static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08004688 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07004689 uname_result__doc__, /* doc */
4690 uname_result_fields,
4691 5
4692};
4693
Larry Hastings605a62d2012-06-24 04:33:36 -07004694#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004695/*[clinic input]
4696os.uname
4697
4698Return an object identifying the current operating system.
4699
4700The object behaves like a named tuple with the following fields:
4701 (sysname, nodename, release, version, machine)
4702
4703[clinic start generated code]*/
4704
Larry Hastings2f936352014-08-05 14:04:04 +10004705static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004706os_uname_impl(PyObject *module)
4707/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004708{
Victor Stinner8c62be82010-05-06 00:08:46 +00004709 struct utsname u;
4710 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004711 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004712
Victor Stinner8c62be82010-05-06 00:08:46 +00004713 Py_BEGIN_ALLOW_THREADS
4714 res = uname(&u);
4715 Py_END_ALLOW_THREADS
4716 if (res < 0)
4717 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004718
Hai Shif707d942020-03-16 21:15:01 +08004719 PyObject *UnameResultType = get_posix_state(module)->UnameResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08004720 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004721 if (value == NULL)
4722 return NULL;
4723
4724#define SET(i, field) \
4725 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004726 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004727 if (!o) { \
4728 Py_DECREF(value); \
4729 return NULL; \
4730 } \
4731 PyStructSequence_SET_ITEM(value, i, o); \
4732 } \
4733
4734 SET(0, u.sysname);
4735 SET(1, u.nodename);
4736 SET(2, u.release);
4737 SET(3, u.version);
4738 SET(4, u.machine);
4739
4740#undef SET
4741
4742 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004743}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004744#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004745
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004746
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747
4748typedef struct {
4749 int now;
4750 time_t atime_s;
4751 long atime_ns;
4752 time_t mtime_s;
4753 long mtime_ns;
4754} utime_t;
4755
4756/*
Victor Stinner484df002014-10-09 13:52:31 +02004757 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 * they also intentionally leak the declaration of a pointer named "time"
4759 */
4760#define UTIME_TO_TIMESPEC \
4761 struct timespec ts[2]; \
4762 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004763 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004764 time = NULL; \
4765 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004766 ts[0].tv_sec = ut->atime_s; \
4767 ts[0].tv_nsec = ut->atime_ns; \
4768 ts[1].tv_sec = ut->mtime_s; \
4769 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770 time = ts; \
4771 } \
4772
4773#define UTIME_TO_TIMEVAL \
4774 struct timeval tv[2]; \
4775 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004776 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004777 time = NULL; \
4778 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004779 tv[0].tv_sec = ut->atime_s; \
4780 tv[0].tv_usec = ut->atime_ns / 1000; \
4781 tv[1].tv_sec = ut->mtime_s; \
4782 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004783 time = tv; \
4784 } \
4785
4786#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004787 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004788 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004789 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004790 time = NULL; \
4791 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004792 u.actime = ut->atime_s; \
4793 u.modtime = ut->mtime_s; \
4794 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004795 }
4796
4797#define UTIME_TO_TIME_T \
4798 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004799 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004800 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004801 time = NULL; \
4802 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004803 timet[0] = ut->atime_s; \
4804 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004805 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004806 } \
4807
4808
Victor Stinner528a9ab2015-09-03 21:30:26 +02004809#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004810
4811static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004812utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004813{
4814#ifdef HAVE_UTIMENSAT
4815 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4816 UTIME_TO_TIMESPEC;
4817 return utimensat(dir_fd, path, time, flags);
4818#elif defined(HAVE_FUTIMESAT)
4819 UTIME_TO_TIMEVAL;
4820 /*
4821 * follow_symlinks will never be false here;
4822 * we only allow !follow_symlinks and dir_fd together
4823 * if we have utimensat()
4824 */
4825 assert(follow_symlinks);
4826 return futimesat(dir_fd, path, time);
4827#endif
4828}
4829
Larry Hastings2f936352014-08-05 14:04:04 +10004830 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4831#else
4832 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004833#endif
4834
Victor Stinner528a9ab2015-09-03 21:30:26 +02004835#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004836
4837static int
Victor Stinner484df002014-10-09 13:52:31 +02004838utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004839{
4840#ifdef HAVE_FUTIMENS
4841 UTIME_TO_TIMESPEC;
4842 return futimens(fd, time);
4843#else
4844 UTIME_TO_TIMEVAL;
4845 return futimes(fd, time);
4846#endif
4847}
4848
Larry Hastings2f936352014-08-05 14:04:04 +10004849 #define PATH_UTIME_HAVE_FD 1
4850#else
4851 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004852#endif
4853
Victor Stinner5ebae872015-09-22 01:29:33 +02004854#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4855# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4856#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004857
Victor Stinner4552ced2015-09-21 22:37:15 +02004858#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004859
4860static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004861utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004862{
4863#ifdef HAVE_UTIMENSAT
4864 UTIME_TO_TIMESPEC;
4865 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4866#else
4867 UTIME_TO_TIMEVAL;
4868 return lutimes(path, time);
4869#endif
4870}
4871
4872#endif
4873
4874#ifndef MS_WINDOWS
4875
4876static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004877utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004878{
4879#ifdef HAVE_UTIMENSAT
4880 UTIME_TO_TIMESPEC;
4881 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4882#elif defined(HAVE_UTIMES)
4883 UTIME_TO_TIMEVAL;
4884 return utimes(path, time);
4885#elif defined(HAVE_UTIME_H)
4886 UTIME_TO_UTIMBUF;
4887 return utime(path, time);
4888#else
4889 UTIME_TO_TIME_T;
4890 return utime(path, time);
4891#endif
4892}
4893
4894#endif
4895
Larry Hastings76ad59b2012-05-03 00:30:07 -07004896static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02004897split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004898{
4899 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004900 PyObject *divmod;
Victor Stinner1c2fa782020-05-10 11:05:29 +02004901 divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07004902 if (!divmod)
4903 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004904 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4905 PyErr_Format(PyExc_TypeError,
4906 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08004907 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004908 goto exit;
4909 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004910 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4911 if ((*s == -1) && PyErr_Occurred())
4912 goto exit;
4913 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004914 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004915 goto exit;
4916
4917 result = 1;
4918exit:
4919 Py_XDECREF(divmod);
4920 return result;
4921}
4922
Larry Hastings2f936352014-08-05 14:04:04 +10004923
4924/*[clinic input]
4925os.utime
4926
4927 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004928 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10004929 *
4930 ns: object = NULL
4931 dir_fd: dir_fd(requires='futimensat') = None
4932 follow_symlinks: bool=True
4933
Martin Panter0ff89092015-09-09 01:56:53 +00004934# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004935
4936Set the access and modified time of path.
4937
4938path may always be specified as a string.
4939On some platforms, path may also be specified as an open file descriptor.
4940 If this functionality is unavailable, using it raises an exception.
4941
4942If times is not None, it must be a tuple (atime, mtime);
4943 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004944If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004945 atime_ns and mtime_ns should be expressed as integer nanoseconds
4946 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004947If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004948Specifying tuples for both times and ns is an error.
4949
4950If dir_fd is not None, it should be a file descriptor open to a directory,
4951 and path should be relative; path will then be relative to that directory.
4952If follow_symlinks is False, and the last element of the path is a symbolic
4953 link, utime will modify the symbolic link itself instead of the file the
4954 link points to.
4955It is an error to use dir_fd or follow_symlinks when specifying path
4956 as an open file descriptor.
4957dir_fd and follow_symlinks may not be available on your platform.
4958 If they are unavailable, using them will raise a NotImplementedError.
4959
4960[clinic start generated code]*/
4961
Larry Hastings2f936352014-08-05 14:04:04 +10004962static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004963os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4964 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004965/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004966{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004967#ifdef MS_WINDOWS
4968 HANDLE hFile;
4969 FILETIME atime, mtime;
4970#else
4971 int result;
4972#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004973
Larry Hastings2f936352014-08-05 14:04:04 +10004974 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004975
Christian Heimesb3c87242013-08-01 00:08:16 +02004976 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004977
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004978 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004979 PyErr_SetString(PyExc_ValueError,
4980 "utime: you may specify either 'times'"
4981 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004982 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004983 }
4984
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004985 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004986 time_t a_sec, m_sec;
4987 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004988 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004989 PyErr_SetString(PyExc_TypeError,
4990 "utime: 'times' must be either"
4991 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004992 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004993 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004994 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004995 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004996 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004997 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004998 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004999 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005000 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005001 utime.atime_s = a_sec;
5002 utime.atime_ns = a_nsec;
5003 utime.mtime_s = m_sec;
5004 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005005 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005006 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07005007 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005008 PyErr_SetString(PyExc_TypeError,
5009 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005010 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005011 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005012 utime.now = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005013 if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005014 &utime.atime_s, &utime.atime_ns) ||
Victor Stinner1c2fa782020-05-10 11:05:29 +02005015 !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005016 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005017 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005018 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005019 }
5020 else {
5021 /* times and ns are both None/unspecified. use "now". */
5022 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005023 }
5024
Victor Stinner4552ced2015-09-21 22:37:15 +02005025#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005026 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005027 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005028#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005029
Larry Hastings2f936352014-08-05 14:04:04 +10005030 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
5031 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
5032 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005033 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005034
Larry Hastings9cf065c2012-06-22 16:30:09 -07005035#if !defined(HAVE_UTIMENSAT)
5036 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02005037 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005038 "utime: cannot use dir_fd and follow_symlinks "
5039 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005040 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005041 }
5042#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005043
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005044 if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
5045 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
5046 return NULL;
5047 }
5048
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005049#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005050 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005051 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5052 NULL, OPEN_EXISTING,
5053 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005054 Py_END_ALLOW_THREADS
5055 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10005056 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005057 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005058 }
5059
Larry Hastings9cf065c2012-06-22 16:30:09 -07005060 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005061 GetSystemTimeAsFileTime(&mtime);
5062 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08005065 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5066 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005067 }
5068 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5069 /* Avoid putting the file name into the error here,
5070 as that may confuse the user into believing that
5071 something is wrong with the file, when it also
5072 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005073 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005074 CloseHandle(hFile);
5075 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005076 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005077 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005078#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005079 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005080
Victor Stinner4552ced2015-09-21 22:37:15 +02005081#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005082 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10005083 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005084 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005085#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005086
Victor Stinner528a9ab2015-09-03 21:30:26 +02005087#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005088 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10005089 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005090 else
5091#endif
5092
Victor Stinner528a9ab2015-09-03 21:30:26 +02005093#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005094 if (path->fd != -1)
5095 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005096 else
5097#endif
5098
Larry Hastings2f936352014-08-05 14:04:04 +10005099 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005100
5101 Py_END_ALLOW_THREADS
5102
5103 if (result < 0) {
5104 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005105 posix_error();
5106 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005108
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005109#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005110
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005111 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005112}
5113
Guido van Rossum3b066191991-06-04 19:40:25 +00005114/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005115
Larry Hastings2f936352014-08-05 14:04:04 +10005116
5117/*[clinic input]
5118os._exit
5119
5120 status: int
5121
5122Exit to the system with specified status, without normal exit processing.
5123[clinic start generated code]*/
5124
Larry Hastings2f936352014-08-05 14:04:04 +10005125static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005126os__exit_impl(PyObject *module, int status)
5127/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005128{
5129 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005131}
5132
Steve Dowercc16be82016-09-08 10:35:16 -07005133#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5134#define EXECV_CHAR wchar_t
5135#else
5136#define EXECV_CHAR char
5137#endif
5138
pxinwrf2d7ac72019-05-21 18:46:37 +08005139#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005140static void
Steve Dowercc16be82016-09-08 10:35:16 -07005141free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005142{
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 Py_ssize_t i;
5144 for (i = 0; i < count; i++)
5145 PyMem_Free(array[i]);
5146 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005147}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005148
Berker Peksag81816462016-09-15 20:19:47 +03005149static int
5150fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005151{
Victor Stinner8c62be82010-05-06 00:08:46 +00005152 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005153 PyObject *ub;
5154 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005155#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005156 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005157 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005158 *out = PyUnicode_AsWideCharString(ub, &size);
5159 if (*out)
5160 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005161#else
Berker Peksag81816462016-09-15 20:19:47 +03005162 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005163 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005164 size = PyBytes_GET_SIZE(ub);
5165 *out = PyMem_Malloc(size + 1);
5166 if (*out) {
5167 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5168 result = 1;
5169 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005170 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005171#endif
Berker Peksag81816462016-09-15 20:19:47 +03005172 Py_DECREF(ub);
5173 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005174}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005175#endif
5176
pxinwrf2d7ac72019-05-21 18:46:37 +08005177#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005178static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005179parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5180{
Victor Stinner8c62be82010-05-06 00:08:46 +00005181 Py_ssize_t i, pos, envc;
5182 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005183 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005184 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005185
Victor Stinner8c62be82010-05-06 00:08:46 +00005186 i = PyMapping_Size(env);
5187 if (i < 0)
5188 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005189 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 if (envlist == NULL) {
5191 PyErr_NoMemory();
5192 return NULL;
5193 }
5194 envc = 0;
5195 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005196 if (!keys)
5197 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005198 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005199 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005200 goto error;
5201 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5202 PyErr_Format(PyExc_TypeError,
5203 "env.keys() or env.values() is not a list");
5204 goto error;
5205 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005206
Victor Stinner8c62be82010-05-06 00:08:46 +00005207 for (pos = 0; pos < i; pos++) {
5208 key = PyList_GetItem(keys, pos);
5209 val = PyList_GetItem(vals, pos);
5210 if (!key || !val)
5211 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005212
Berker Peksag81816462016-09-15 20:19:47 +03005213#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5214 if (!PyUnicode_FSDecoder(key, &key2))
5215 goto error;
5216 if (!PyUnicode_FSDecoder(val, &val2)) {
5217 Py_DECREF(key2);
5218 goto error;
5219 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005220 /* Search from index 1 because on Windows starting '=' is allowed for
5221 defining hidden environment variables. */
5222 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5223 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5224 {
5225 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005226 Py_DECREF(key2);
5227 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005228 goto error;
5229 }
Berker Peksag81816462016-09-15 20:19:47 +03005230 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5231#else
5232 if (!PyUnicode_FSConverter(key, &key2))
5233 goto error;
5234 if (!PyUnicode_FSConverter(val, &val2)) {
5235 Py_DECREF(key2);
5236 goto error;
5237 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005238 if (PyBytes_GET_SIZE(key2) == 0 ||
5239 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5240 {
5241 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005242 Py_DECREF(key2);
5243 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005244 goto error;
5245 }
Berker Peksag81816462016-09-15 20:19:47 +03005246 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5247 PyBytes_AS_STRING(val2));
5248#endif
5249 Py_DECREF(key2);
5250 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005251 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005252 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005253
5254 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5255 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005256 goto error;
5257 }
Berker Peksag81816462016-09-15 20:19:47 +03005258
Steve Dowercc16be82016-09-08 10:35:16 -07005259 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005260 }
5261 Py_DECREF(vals);
5262 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005263
Victor Stinner8c62be82010-05-06 00:08:46 +00005264 envlist[envc] = 0;
5265 *envc_ptr = envc;
5266 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005267
5268error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005269 Py_XDECREF(keys);
5270 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005271 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005272 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005273}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005274
Steve Dowercc16be82016-09-08 10:35:16 -07005275static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005276parse_arglist(PyObject* argv, Py_ssize_t *argc)
5277{
5278 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005279 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005280 if (argvlist == NULL) {
5281 PyErr_NoMemory();
5282 return NULL;
5283 }
5284 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005285 PyObject* item = PySequence_ITEM(argv, i);
5286 if (item == NULL)
5287 goto fail;
5288 if (!fsconvert_strdup(item, &argvlist[i])) {
5289 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005290 goto fail;
5291 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005292 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005293 }
5294 argvlist[*argc] = NULL;
5295 return argvlist;
5296fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005297 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005298 free_string_array(argvlist, *argc);
5299 return NULL;
5300}
Steve Dowercc16be82016-09-08 10:35:16 -07005301
Ross Lagerwall7807c352011-03-17 20:20:30 +02005302#endif
5303
Larry Hastings2f936352014-08-05 14:04:04 +10005304
Ross Lagerwall7807c352011-03-17 20:20:30 +02005305#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005306/*[clinic input]
5307os.execv
5308
Steve Dowercc16be82016-09-08 10:35:16 -07005309 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005310 Path of executable file.
5311 argv: object
5312 Tuple or list of strings.
5313 /
5314
5315Execute an executable path with arguments, replacing current process.
5316[clinic start generated code]*/
5317
Larry Hastings2f936352014-08-05 14:04:04 +10005318static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005319os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5320/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005321{
Steve Dowercc16be82016-09-08 10:35:16 -07005322 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005323 Py_ssize_t argc;
5324
5325 /* execv has two arguments: (path, argv), where
5326 argv is a list or tuple of strings. */
5327
Ross Lagerwall7807c352011-03-17 20:20:30 +02005328 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5329 PyErr_SetString(PyExc_TypeError,
5330 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005331 return NULL;
5332 }
5333 argc = PySequence_Size(argv);
5334 if (argc < 1) {
5335 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005336 return NULL;
5337 }
5338
5339 argvlist = parse_arglist(argv, &argc);
5340 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005341 return NULL;
5342 }
Steve Dowerbce26262016-11-19 19:17:26 -08005343 if (!argvlist[0][0]) {
5344 PyErr_SetString(PyExc_ValueError,
5345 "execv() arg 2 first element cannot be empty");
5346 free_string_array(argvlist, argc);
5347 return NULL;
5348 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005349
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005350 if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005351 free_string_array(argvlist, argc);
5352 return NULL;
5353 }
5354
Steve Dowerbce26262016-11-19 19:17:26 -08005355 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005356#ifdef HAVE_WEXECV
5357 _wexecv(path->wide, argvlist);
5358#else
5359 execv(path->narrow, argvlist);
5360#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005361 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005362
5363 /* If we get here it's definitely an error */
5364
5365 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005366 return posix_error();
5367}
5368
Larry Hastings2f936352014-08-05 14:04:04 +10005369
5370/*[clinic input]
5371os.execve
5372
5373 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5374 Path of executable file.
5375 argv: object
5376 Tuple or list of strings.
5377 env: object
5378 Dictionary of strings mapping to strings.
5379
5380Execute an executable path with arguments, replacing current process.
5381[clinic start generated code]*/
5382
Larry Hastings2f936352014-08-05 14:04:04 +10005383static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005384os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5385/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005386{
Steve Dowercc16be82016-09-08 10:35:16 -07005387 EXECV_CHAR **argvlist = NULL;
5388 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005389 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005390
Victor Stinner8c62be82010-05-06 00:08:46 +00005391 /* execve has three arguments: (path, argv, env), where
5392 argv is a list or tuple of strings and env is a dictionary
5393 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005394
Ross Lagerwall7807c352011-03-17 20:20:30 +02005395 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005396 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005397 "execve: argv must be a tuple or list");
Saiyang Gou95f60012020-02-04 16:15:00 -08005398 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005399 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005400 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005401 if (argc < 1) {
5402 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5403 return NULL;
5404 }
5405
Victor Stinner8c62be82010-05-06 00:08:46 +00005406 if (!PyMapping_Check(env)) {
5407 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005408 "execve: environment must be a mapping object");
Saiyang Gou95f60012020-02-04 16:15:00 -08005409 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005411
Ross Lagerwall7807c352011-03-17 20:20:30 +02005412 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005413 if (argvlist == NULL) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005414 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005415 }
Steve Dowerbce26262016-11-19 19:17:26 -08005416 if (!argvlist[0][0]) {
5417 PyErr_SetString(PyExc_ValueError,
5418 "execve: argv first element cannot be empty");
Saiyang Gou95f60012020-02-04 16:15:00 -08005419 goto fail_0;
Steve Dowerbce26262016-11-19 19:17:26 -08005420 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005421
Victor Stinner8c62be82010-05-06 00:08:46 +00005422 envlist = parse_envlist(env, &envc);
5423 if (envlist == NULL)
Saiyang Gou95f60012020-02-04 16:15:00 -08005424 goto fail_0;
5425
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005426 if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005427 goto fail_1;
5428 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005429
Steve Dowerbce26262016-11-19 19:17:26 -08005430 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005431#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005432 if (path->fd > -1)
5433 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005434 else
5435#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005436#ifdef HAVE_WEXECV
5437 _wexecve(path->wide, argvlist, envlist);
5438#else
Larry Hastings2f936352014-08-05 14:04:04 +10005439 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005440#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005441 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005442
5443 /* If we get here it's definitely an error */
5444
Alexey Izbyshev83460312018-10-20 03:28:22 +03005445 posix_path_error(path);
Saiyang Gou95f60012020-02-04 16:15:00 -08005446 fail_1:
Steve Dowercc16be82016-09-08 10:35:16 -07005447 free_string_array(envlist, envc);
Saiyang Gou95f60012020-02-04 16:15:00 -08005448 fail_0:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005449 if (argvlist)
5450 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005451 return NULL;
5452}
Steve Dowercc16be82016-09-08 10:35:16 -07005453
Larry Hastings9cf065c2012-06-22 16:30:09 -07005454#endif /* HAVE_EXECV */
5455
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005456#ifdef HAVE_POSIX_SPAWN
5457
5458enum posix_spawn_file_actions_identifier {
5459 POSIX_SPAWN_OPEN,
5460 POSIX_SPAWN_CLOSE,
5461 POSIX_SPAWN_DUP2
5462};
5463
William Orr81574b82018-10-01 22:19:56 -07005464#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005465static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005466convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005467#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005468
5469static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005470parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005471 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005472 PyObject *setsigdef, PyObject *scheduler,
5473 posix_spawnattr_t *attrp)
5474{
5475 long all_flags = 0;
5476
5477 errno = posix_spawnattr_init(attrp);
5478 if (errno) {
5479 posix_error();
5480 return -1;
5481 }
5482
5483 if (setpgroup) {
5484 pid_t pgid = PyLong_AsPid(setpgroup);
5485 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5486 goto fail;
5487 }
5488 errno = posix_spawnattr_setpgroup(attrp, pgid);
5489 if (errno) {
5490 posix_error();
5491 goto fail;
5492 }
5493 all_flags |= POSIX_SPAWN_SETPGROUP;
5494 }
5495
5496 if (resetids) {
5497 all_flags |= POSIX_SPAWN_RESETIDS;
5498 }
5499
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005500 if (setsid) {
5501#ifdef POSIX_SPAWN_SETSID
5502 all_flags |= POSIX_SPAWN_SETSID;
5503#elif defined(POSIX_SPAWN_SETSID_NP)
5504 all_flags |= POSIX_SPAWN_SETSID_NP;
5505#else
5506 argument_unavailable_error(func_name, "setsid");
5507 return -1;
5508#endif
5509 }
5510
Pablo Galindo254a4662018-09-07 16:44:24 +01005511 if (setsigmask) {
5512 sigset_t set;
5513 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5514 goto fail;
5515 }
5516 errno = posix_spawnattr_setsigmask(attrp, &set);
5517 if (errno) {
5518 posix_error();
5519 goto fail;
5520 }
5521 all_flags |= POSIX_SPAWN_SETSIGMASK;
5522 }
5523
5524 if (setsigdef) {
5525 sigset_t set;
5526 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5527 goto fail;
5528 }
5529 errno = posix_spawnattr_setsigdefault(attrp, &set);
5530 if (errno) {
5531 posix_error();
5532 goto fail;
5533 }
5534 all_flags |= POSIX_SPAWN_SETSIGDEF;
5535 }
5536
5537 if (scheduler) {
5538#ifdef POSIX_SPAWN_SETSCHEDULER
5539 PyObject *py_schedpolicy;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005540 PyObject *schedparam_obj;
Pablo Galindo254a4662018-09-07 16:44:24 +01005541 struct sched_param schedparam;
5542
Victor Stinner1c2fa782020-05-10 11:05:29 +02005543 if (!PyArg_ParseTuple(scheduler, "OO"
Pablo Galindo254a4662018-09-07 16:44:24 +01005544 ";A scheduler tuple must have two elements",
Victor Stinner1c2fa782020-05-10 11:05:29 +02005545 &py_schedpolicy, &schedparam_obj)) {
5546 goto fail;
5547 }
5548 if (!convert_sched_param(module, schedparam_obj, &schedparam)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005549 goto fail;
5550 }
5551 if (py_schedpolicy != Py_None) {
5552 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5553
5554 if (schedpolicy == -1 && PyErr_Occurred()) {
5555 goto fail;
5556 }
5557 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5558 if (errno) {
5559 posix_error();
5560 goto fail;
5561 }
5562 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5563 }
5564 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5565 if (errno) {
5566 posix_error();
5567 goto fail;
5568 }
5569 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5570#else
5571 PyErr_SetString(PyExc_NotImplementedError,
5572 "The scheduler option is not supported in this system.");
5573 goto fail;
5574#endif
5575 }
5576
5577 errno = posix_spawnattr_setflags(attrp, all_flags);
5578 if (errno) {
5579 posix_error();
5580 goto fail;
5581 }
5582
5583 return 0;
5584
5585fail:
5586 (void)posix_spawnattr_destroy(attrp);
5587 return -1;
5588}
5589
5590static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005591parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005592 posix_spawn_file_actions_t *file_actionsp,
5593 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005594{
5595 PyObject *seq;
5596 PyObject *file_action = NULL;
5597 PyObject *tag_obj;
5598
5599 seq = PySequence_Fast(file_actions,
5600 "file_actions must be a sequence or None");
5601 if (seq == NULL) {
5602 return -1;
5603 }
5604
5605 errno = posix_spawn_file_actions_init(file_actionsp);
5606 if (errno) {
5607 posix_error();
5608 Py_DECREF(seq);
5609 return -1;
5610 }
5611
Zackery Spytzd52a83a2019-06-26 14:54:20 -06005612 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03005613 file_action = PySequence_Fast_GET_ITEM(seq, i);
5614 Py_INCREF(file_action);
5615 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5616 PyErr_SetString(PyExc_TypeError,
5617 "Each file_actions element must be a non-empty tuple");
5618 goto fail;
5619 }
5620 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5621 if (tag == -1 && PyErr_Occurred()) {
5622 goto fail;
5623 }
5624
5625 /* Populate the file_actions object */
5626 switch (tag) {
5627 case POSIX_SPAWN_OPEN: {
5628 int fd, oflag;
5629 PyObject *path;
5630 unsigned long mode;
5631 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5632 ";A open file_action tuple must have 5 elements",
5633 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5634 &oflag, &mode))
5635 {
5636 goto fail;
5637 }
Pablo Galindocb970732018-06-19 09:19:50 +01005638 if (PyList_Append(temp_buffer, path)) {
5639 Py_DECREF(path);
5640 goto fail;
5641 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005642 errno = posix_spawn_file_actions_addopen(file_actionsp,
5643 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005644 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005645 if (errno) {
5646 posix_error();
5647 goto fail;
5648 }
5649 break;
5650 }
5651 case POSIX_SPAWN_CLOSE: {
5652 int fd;
5653 if (!PyArg_ParseTuple(file_action, "Oi"
5654 ";A close file_action tuple must have 2 elements",
5655 &tag_obj, &fd))
5656 {
5657 goto fail;
5658 }
5659 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5660 if (errno) {
5661 posix_error();
5662 goto fail;
5663 }
5664 break;
5665 }
5666 case POSIX_SPAWN_DUP2: {
5667 int fd1, fd2;
5668 if (!PyArg_ParseTuple(file_action, "Oii"
5669 ";A dup2 file_action tuple must have 3 elements",
5670 &tag_obj, &fd1, &fd2))
5671 {
5672 goto fail;
5673 }
5674 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5675 fd1, fd2);
5676 if (errno) {
5677 posix_error();
5678 goto fail;
5679 }
5680 break;
5681 }
5682 default: {
5683 PyErr_SetString(PyExc_TypeError,
5684 "Unknown file_actions identifier");
5685 goto fail;
5686 }
5687 }
5688 Py_DECREF(file_action);
5689 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005690
Serhiy Storchakaef347532018-05-01 16:45:04 +03005691 Py_DECREF(seq);
5692 return 0;
5693
5694fail:
5695 Py_DECREF(seq);
5696 Py_DECREF(file_action);
5697 (void)posix_spawn_file_actions_destroy(file_actionsp);
5698 return -1;
5699}
5700
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005701
5702static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005703py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5704 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005705 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005706 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005707{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005708 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005709 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005710 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005711 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005712 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005713 posix_spawnattr_t attr;
5714 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005715 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005716 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005717 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005718 pid_t pid;
5719 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005720
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005721 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005722 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005723 like posix.environ. */
5724
Serhiy Storchakaef347532018-05-01 16:45:04 +03005725 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005726 PyErr_Format(PyExc_TypeError,
5727 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005728 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005729 }
5730 argc = PySequence_Size(argv);
5731 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005732 PyErr_Format(PyExc_ValueError,
5733 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005734 return NULL;
5735 }
5736
5737 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005738 PyErr_Format(PyExc_TypeError,
5739 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005740 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005741 }
5742
5743 argvlist = parse_arglist(argv, &argc);
5744 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005745 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005746 }
5747 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005748 PyErr_Format(PyExc_ValueError,
5749 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005750 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005751 }
5752
5753 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005754 if (envlist == NULL) {
5755 goto exit;
5756 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005757
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005758 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005759 /* There is a bug in old versions of glibc that makes some of the
5760 * helper functions for manipulating file actions not copy the provided
5761 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5762 * copy the value of path for some old versions of glibc (<2.20).
5763 * The use of temp_buffer here is a workaround that keeps the
5764 * python objects that own the buffers alive until posix_spawn gets called.
5765 * Check https://bugs.python.org/issue33630 and
5766 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5767 temp_buffer = PyList_New(0);
5768 if (!temp_buffer) {
5769 goto exit;
5770 }
5771 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005772 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005773 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005774 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005775 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005776
Victor Stinner1c2fa782020-05-10 11:05:29 +02005777 if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005778 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005779 goto exit;
5780 }
5781 attrp = &attr;
5782
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005783 if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005784 goto exit;
5785 }
5786
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005787 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005788#ifdef HAVE_POSIX_SPAWNP
5789 if (use_posix_spawnp) {
5790 err_code = posix_spawnp(&pid, path->narrow,
5791 file_actionsp, attrp, argvlist, envlist);
5792 }
5793 else
5794#endif /* HAVE_POSIX_SPAWNP */
5795 {
5796 err_code = posix_spawn(&pid, path->narrow,
5797 file_actionsp, attrp, argvlist, envlist);
5798 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005799 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005800
Serhiy Storchakaef347532018-05-01 16:45:04 +03005801 if (err_code) {
5802 errno = err_code;
5803 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005804 goto exit;
5805 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005806#ifdef _Py_MEMORY_SANITIZER
5807 __msan_unpoison(&pid, sizeof(pid));
5808#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005809 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005810
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005811exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005812 if (file_actionsp) {
5813 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005814 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005815 if (attrp) {
5816 (void)posix_spawnattr_destroy(attrp);
5817 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005818 if (envlist) {
5819 free_string_array(envlist, envc);
5820 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005821 if (argvlist) {
5822 free_string_array(argvlist, argc);
5823 }
Pablo Galindocb970732018-06-19 09:19:50 +01005824 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005825 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005826}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005827
5828
5829/*[clinic input]
5830
5831os.posix_spawn
5832 path: path_t
5833 Path of executable file.
5834 argv: object
5835 Tuple or list of strings.
5836 env: object
5837 Dictionary of strings mapping to strings.
5838 /
5839 *
5840 file_actions: object(c_default='NULL') = ()
5841 A sequence of file action tuples.
5842 setpgroup: object = NULL
5843 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5844 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005845 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5846 setsid: bool(accept={int}) = False
5847 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005848 setsigmask: object(c_default='NULL') = ()
5849 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5850 setsigdef: object(c_default='NULL') = ()
5851 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5852 scheduler: object = NULL
5853 A tuple with the scheduler policy (optional) and parameters.
5854
5855Execute the program specified by path in a new process.
5856[clinic start generated code]*/
5857
5858static PyObject *
5859os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5860 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005861 PyObject *setpgroup, int resetids, int setsid,
5862 PyObject *setsigmask, PyObject *setsigdef,
5863 PyObject *scheduler)
5864/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005865{
5866 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005867 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005868 scheduler);
5869}
5870 #endif /* HAVE_POSIX_SPAWN */
5871
5872
5873
5874#ifdef HAVE_POSIX_SPAWNP
5875/*[clinic input]
5876
5877os.posix_spawnp
5878 path: path_t
5879 Path of executable file.
5880 argv: object
5881 Tuple or list of strings.
5882 env: object
5883 Dictionary of strings mapping to strings.
5884 /
5885 *
5886 file_actions: object(c_default='NULL') = ()
5887 A sequence of file action tuples.
5888 setpgroup: object = NULL
5889 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5890 resetids: bool(accept={int}) = False
5891 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005892 setsid: bool(accept={int}) = False
5893 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005894 setsigmask: object(c_default='NULL') = ()
5895 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5896 setsigdef: object(c_default='NULL') = ()
5897 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5898 scheduler: object = NULL
5899 A tuple with the scheduler policy (optional) and parameters.
5900
5901Execute the program specified by path in a new process.
5902[clinic start generated code]*/
5903
5904static PyObject *
5905os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5906 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005907 PyObject *setpgroup, int resetids, int setsid,
5908 PyObject *setsigmask, PyObject *setsigdef,
5909 PyObject *scheduler)
5910/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005911{
5912 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005913 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005914 scheduler);
5915}
5916#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005917
pxinwrf2d7ac72019-05-21 18:46:37 +08005918#ifdef HAVE_RTPSPAWN
5919static intptr_t
5920_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5921 const char *envp[])
5922{
5923 RTP_ID rtpid;
5924 int status;
5925 pid_t res;
5926 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005927
pxinwrf2d7ac72019-05-21 18:46:37 +08005928 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5929 uStackSize=0 cannot be used, the default stack size is too small for
5930 Python. */
5931 if (envp) {
5932 rtpid = rtpSpawn(rtpFileName, argv, envp,
5933 100, 0x1000000, 0, VX_FP_TASK);
5934 }
5935 else {
5936 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5937 100, 0x1000000, 0, VX_FP_TASK);
5938 }
5939 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5940 do {
5941 res = waitpid((pid_t)rtpid, &status, 0);
5942 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5943
5944 if (res < 0)
5945 return RTP_ID_ERROR;
5946 return ((intptr_t)status);
5947 }
5948 return ((intptr_t)rtpid);
5949}
5950#endif
5951
5952#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10005953/*[clinic input]
5954os.spawnv
5955
5956 mode: int
5957 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005958 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005959 Path of executable file.
5960 argv: object
5961 Tuple or list of strings.
5962 /
5963
5964Execute the program specified by path in a new process.
5965[clinic start generated code]*/
5966
Larry Hastings2f936352014-08-05 14:04:04 +10005967static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005968os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5969/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005970{
Steve Dowercc16be82016-09-08 10:35:16 -07005971 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005972 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005973 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005974 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005975 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005976
Victor Stinner8c62be82010-05-06 00:08:46 +00005977 /* spawnv has three arguments: (mode, path, argv), where
5978 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005979
Victor Stinner8c62be82010-05-06 00:08:46 +00005980 if (PyList_Check(argv)) {
5981 argc = PyList_Size(argv);
5982 getitem = PyList_GetItem;
5983 }
5984 else if (PyTuple_Check(argv)) {
5985 argc = PyTuple_Size(argv);
5986 getitem = PyTuple_GetItem;
5987 }
5988 else {
5989 PyErr_SetString(PyExc_TypeError,
5990 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005991 return NULL;
5992 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005993 if (argc == 0) {
5994 PyErr_SetString(PyExc_ValueError,
5995 "spawnv() arg 2 cannot be empty");
5996 return NULL;
5997 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005998
Steve Dowercc16be82016-09-08 10:35:16 -07005999 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006000 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006001 return PyErr_NoMemory();
6002 }
6003 for (i = 0; i < argc; i++) {
6004 if (!fsconvert_strdup((*getitem)(argv, i),
6005 &argvlist[i])) {
6006 free_string_array(argvlist, i);
6007 PyErr_SetString(
6008 PyExc_TypeError,
6009 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00006010 return NULL;
6011 }
Steve Dower93ff8722016-11-19 19:03:54 -08006012 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02006013 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08006014 PyErr_SetString(
6015 PyExc_ValueError,
6016 "spawnv() arg 2 first element cannot be empty");
6017 return NULL;
6018 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006019 }
6020 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006021
pxinwrf2d7ac72019-05-21 18:46:37 +08006022#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006023 if (mode == _OLD_P_OVERLAY)
6024 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006025#endif
Tim Peters5aa91602002-01-30 05:46:57 +00006026
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006027 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
Saiyang Gou95f60012020-02-04 16:15:00 -08006028 Py_None) < 0) {
6029 free_string_array(argvlist, argc);
6030 return NULL;
6031 }
6032
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006034 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006035#ifdef HAVE_WSPAWNV
6036 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006037#elif defined(HAVE_RTPSPAWN)
6038 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07006039#else
6040 spawnval = _spawnv(mode, path->narrow, argvlist);
6041#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006042 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006043 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00006044
Victor Stinner8c62be82010-05-06 00:08:46 +00006045 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00006046
Victor Stinner8c62be82010-05-06 00:08:46 +00006047 if (spawnval == -1)
6048 return posix_error();
6049 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006050 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006051}
6052
Larry Hastings2f936352014-08-05 14:04:04 +10006053/*[clinic input]
6054os.spawnve
6055
6056 mode: int
6057 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006058 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006059 Path of executable file.
6060 argv: object
6061 Tuple or list of strings.
6062 env: object
6063 Dictionary of strings mapping to strings.
6064 /
6065
6066Execute the program specified by path in a new process.
6067[clinic start generated code]*/
6068
Larry Hastings2f936352014-08-05 14:04:04 +10006069static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006070os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006071 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07006072/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006073{
Steve Dowercc16be82016-09-08 10:35:16 -07006074 EXECV_CHAR **argvlist;
6075 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006076 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006077 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006078 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006079 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006080 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006081
Victor Stinner8c62be82010-05-06 00:08:46 +00006082 /* spawnve has four arguments: (mode, path, argv, env), where
6083 argv is a list or tuple of strings and env is a dictionary
6084 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006085
Victor Stinner8c62be82010-05-06 00:08:46 +00006086 if (PyList_Check(argv)) {
6087 argc = PyList_Size(argv);
6088 getitem = PyList_GetItem;
6089 }
6090 else if (PyTuple_Check(argv)) {
6091 argc = PyTuple_Size(argv);
6092 getitem = PyTuple_GetItem;
6093 }
6094 else {
6095 PyErr_SetString(PyExc_TypeError,
6096 "spawnve() arg 2 must be a tuple or list");
6097 goto fail_0;
6098 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006099 if (argc == 0) {
6100 PyErr_SetString(PyExc_ValueError,
6101 "spawnve() arg 2 cannot be empty");
6102 goto fail_0;
6103 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006104 if (!PyMapping_Check(env)) {
6105 PyErr_SetString(PyExc_TypeError,
6106 "spawnve() arg 3 must be a mapping object");
6107 goto fail_0;
6108 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006109
Steve Dowercc16be82016-09-08 10:35:16 -07006110 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006111 if (argvlist == NULL) {
6112 PyErr_NoMemory();
6113 goto fail_0;
6114 }
6115 for (i = 0; i < argc; i++) {
6116 if (!fsconvert_strdup((*getitem)(argv, i),
6117 &argvlist[i]))
6118 {
6119 lastarg = i;
6120 goto fail_1;
6121 }
Steve Dowerbce26262016-11-19 19:17:26 -08006122 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006123 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006124 PyErr_SetString(
6125 PyExc_ValueError,
6126 "spawnv() arg 2 first element cannot be empty");
6127 goto fail_1;
6128 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006129 }
6130 lastarg = argc;
6131 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006132
Victor Stinner8c62be82010-05-06 00:08:46 +00006133 envlist = parse_envlist(env, &envc);
6134 if (envlist == NULL)
6135 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006136
pxinwrf2d7ac72019-05-21 18:46:37 +08006137#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006138 if (mode == _OLD_P_OVERLAY)
6139 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006140#endif
Tim Peters25059d32001-12-07 20:35:43 +00006141
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006142 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006143 goto fail_2;
6144 }
6145
Victor Stinner8c62be82010-05-06 00:08:46 +00006146 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006147 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006148#ifdef HAVE_WSPAWNV
6149 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006150#elif defined(HAVE_RTPSPAWN)
6151 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6152 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006153#else
6154 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6155#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006156 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006157 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006158
Victor Stinner8c62be82010-05-06 00:08:46 +00006159 if (spawnval == -1)
6160 (void) posix_error();
6161 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006162 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006163
Saiyang Gou95f60012020-02-04 16:15:00 -08006164 fail_2:
Victor Stinner8c62be82010-05-06 00:08:46 +00006165 while (--envc >= 0)
6166 PyMem_DEL(envlist[envc]);
6167 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006168 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006169 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006170 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006171 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006172}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006173
Guido van Rossuma1065681999-01-25 23:20:23 +00006174#endif /* HAVE_SPAWNV */
6175
6176
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006177#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006178
6179/* Helper function to validate arguments.
6180 Returns 0 on success. non-zero on failure with a TypeError raised.
6181 If obj is non-NULL it must be callable. */
6182static int
6183check_null_or_callable(PyObject *obj, const char* obj_name)
6184{
6185 if (obj && !PyCallable_Check(obj)) {
6186 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006187 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006188 return -1;
6189 }
6190 return 0;
6191}
6192
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006193/*[clinic input]
6194os.register_at_fork
6195
Gregory P. Smith163468a2017-05-29 10:03:41 -07006196 *
6197 before: object=NULL
6198 A callable to be called in the parent before the fork() syscall.
6199 after_in_child: object=NULL
6200 A callable to be called in the child after fork().
6201 after_in_parent: object=NULL
6202 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006203
Gregory P. Smith163468a2017-05-29 10:03:41 -07006204Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006205
Gregory P. Smith163468a2017-05-29 10:03:41 -07006206'before' callbacks are called in reverse order.
6207'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006208
6209[clinic start generated code]*/
6210
6211static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006212os_register_at_fork_impl(PyObject *module, PyObject *before,
6213 PyObject *after_in_child, PyObject *after_in_parent)
6214/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006215{
6216 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006217
Gregory P. Smith163468a2017-05-29 10:03:41 -07006218 if (!before && !after_in_child && !after_in_parent) {
6219 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6220 return NULL;
6221 }
6222 if (check_null_or_callable(before, "before") ||
6223 check_null_or_callable(after_in_child, "after_in_child") ||
6224 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006225 return NULL;
6226 }
Victor Stinner81a7be32020-04-14 15:14:01 +02006227 interp = _PyInterpreterState_GET();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006228
Gregory P. Smith163468a2017-05-29 10:03:41 -07006229 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006230 return NULL;
6231 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006232 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006233 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006234 }
6235 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6236 return NULL;
6237 }
6238 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006239}
6240#endif /* HAVE_FORK */
6241
6242
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006243#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006244/*[clinic input]
6245os.fork1
6246
6247Fork a child process with a single multiplexed (i.e., not bound) thread.
6248
6249Return 0 to child process and PID of child to parent process.
6250[clinic start generated code]*/
6251
Larry Hastings2f936352014-08-05 14:04:04 +10006252static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006253os_fork1_impl(PyObject *module)
6254/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006255{
Victor Stinner8c62be82010-05-06 00:08:46 +00006256 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006257
Victor Stinner81a7be32020-04-14 15:14:01 +02006258 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006259 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6260 return NULL;
6261 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006262 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006263 pid = fork1();
6264 if (pid == 0) {
6265 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006266 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006267 } else {
6268 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006269 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006270 }
6271 if (pid == -1)
6272 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006274}
Larry Hastings2f936352014-08-05 14:04:04 +10006275#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006276
6277
Guido van Rossumad0ee831995-03-01 10:34:45 +00006278#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006279/*[clinic input]
6280os.fork
6281
6282Fork a child process.
6283
6284Return 0 to child process and PID of child to parent process.
6285[clinic start generated code]*/
6286
Larry Hastings2f936352014-08-05 14:04:04 +10006287static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006288os_fork_impl(PyObject *module)
6289/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006290{
Victor Stinner8c62be82010-05-06 00:08:46 +00006291 pid_t pid;
Victor Stinner252346a2020-05-01 11:33:44 +02006292 PyInterpreterState *interp = _PyInterpreterState_GET();
6293 if (interp->config._isolated_interpreter) {
6294 PyErr_SetString(PyExc_RuntimeError,
6295 "fork not supported for isolated subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -07006296 return NULL;
6297 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006298 if (PySys_Audit("os.fork", NULL) < 0) {
6299 return NULL;
6300 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006301 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 pid = fork();
6303 if (pid == 0) {
6304 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006305 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006306 } else {
6307 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006308 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006309 }
6310 if (pid == -1)
6311 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006312 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006313}
Larry Hastings2f936352014-08-05 14:04:04 +10006314#endif /* HAVE_FORK */
6315
Guido van Rossum85e3b011991-06-03 12:42:10 +00006316
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006317#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006318#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006319/*[clinic input]
6320os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006321
Larry Hastings2f936352014-08-05 14:04:04 +10006322 policy: int
6323
6324Get the maximum scheduling priority for policy.
6325[clinic start generated code]*/
6326
Larry Hastings2f936352014-08-05 14:04:04 +10006327static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006328os_sched_get_priority_max_impl(PyObject *module, int policy)
6329/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006330{
6331 int max;
6332
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006333 max = sched_get_priority_max(policy);
6334 if (max < 0)
6335 return posix_error();
6336 return PyLong_FromLong(max);
6337}
6338
Larry Hastings2f936352014-08-05 14:04:04 +10006339
6340/*[clinic input]
6341os.sched_get_priority_min
6342
6343 policy: int
6344
6345Get the minimum scheduling priority for policy.
6346[clinic start generated code]*/
6347
Larry Hastings2f936352014-08-05 14:04:04 +10006348static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006349os_sched_get_priority_min_impl(PyObject *module, int policy)
6350/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006351{
6352 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006353 if (min < 0)
6354 return posix_error();
6355 return PyLong_FromLong(min);
6356}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006357#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6358
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006359
Larry Hastings2f936352014-08-05 14:04:04 +10006360#ifdef HAVE_SCHED_SETSCHEDULER
6361/*[clinic input]
6362os.sched_getscheduler
6363 pid: pid_t
6364 /
6365
Min ho Kimc4cacc82019-07-31 08:16:13 +10006366Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006367
6368Passing 0 for pid returns the scheduling policy for the calling process.
6369[clinic start generated code]*/
6370
Larry Hastings2f936352014-08-05 14:04:04 +10006371static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006372os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006373/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006374{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006375 int policy;
6376
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006377 policy = sched_getscheduler(pid);
6378 if (policy < 0)
6379 return posix_error();
6380 return PyLong_FromLong(policy);
6381}
Larry Hastings2f936352014-08-05 14:04:04 +10006382#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006383
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006384
William Orr81574b82018-10-01 22:19:56 -07006385#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006386/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006387class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006388
6389@classmethod
6390os.sched_param.__new__
6391
6392 sched_priority: object
6393 A scheduling parameter.
6394
Eddie Elizondob3966632019-11-05 07:16:14 -08006395Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006396[clinic start generated code]*/
6397
Larry Hastings2f936352014-08-05 14:04:04 +10006398static PyObject *
6399os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006400/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006401{
6402 PyObject *res;
6403
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006404 res = PyStructSequence_New(type);
6405 if (!res)
6406 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006407 Py_INCREF(sched_priority);
6408 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006409 return res;
6410}
6411
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006412PyDoc_VAR(os_sched_param__doc__);
6413
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006414static PyStructSequence_Field sched_param_fields[] = {
6415 {"sched_priority", "the scheduling priority"},
6416 {0}
6417};
6418
6419static PyStructSequence_Desc sched_param_desc = {
6420 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006421 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006422 sched_param_fields,
6423 1
6424};
6425
6426static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006427convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006428{
6429 long priority;
6430
Victor Stinner1c2fa782020-05-10 11:05:29 +02006431 if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006432 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6433 return 0;
6434 }
6435 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6436 if (priority == -1 && PyErr_Occurred())
6437 return 0;
6438 if (priority > INT_MAX || priority < INT_MIN) {
6439 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6440 return 0;
6441 }
6442 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6443 return 1;
6444}
William Orr81574b82018-10-01 22:19:56 -07006445#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006446
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006447
6448#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006449/*[clinic input]
6450os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006451
Larry Hastings2f936352014-08-05 14:04:04 +10006452 pid: pid_t
6453 policy: int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006454 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006455 /
6456
6457Set the scheduling policy for the process identified by pid.
6458
6459If pid is 0, the calling process is changed.
6460param is an instance of sched_param.
6461[clinic start generated code]*/
6462
Larry Hastings2f936352014-08-05 14:04:04 +10006463static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006464os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Victor Stinner1c2fa782020-05-10 11:05:29 +02006465 PyObject *param_obj)
6466/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006467{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006468 struct sched_param param;
6469 if (!convert_sched_param(module, param_obj, &param)) {
6470 return NULL;
6471 }
6472
Jesus Cea9c822272011-09-10 01:40:52 +02006473 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006474 ** sched_setscheduler() returns 0 in Linux, but the previous
6475 ** scheduling policy under Solaris/Illumos, and others.
6476 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006477 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02006478 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006479 return posix_error();
6480 Py_RETURN_NONE;
6481}
Larry Hastings2f936352014-08-05 14:04:04 +10006482#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006483
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006484
6485#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006486/*[clinic input]
6487os.sched_getparam
6488 pid: pid_t
6489 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006490
Larry Hastings2f936352014-08-05 14:04:04 +10006491Returns scheduling parameters for the process identified by pid.
6492
6493If pid is 0, returns parameters for the calling process.
6494Return value is an instance of sched_param.
6495[clinic start generated code]*/
6496
Larry Hastings2f936352014-08-05 14:04:04 +10006497static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006498os_sched_getparam_impl(PyObject *module, pid_t pid)
6499/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006500{
6501 struct sched_param param;
6502 PyObject *result;
6503 PyObject *priority;
6504
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006505 if (sched_getparam(pid, &param))
6506 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02006507 PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -08006508 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006509 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006510 return NULL;
6511 priority = PyLong_FromLong(param.sched_priority);
6512 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006513 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006514 return NULL;
6515 }
Larry Hastings2f936352014-08-05 14:04:04 +10006516 PyStructSequence_SET_ITEM(result, 0, priority);
6517 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006518}
6519
Larry Hastings2f936352014-08-05 14:04:04 +10006520
6521/*[clinic input]
6522os.sched_setparam
6523 pid: pid_t
Victor Stinner1c2fa782020-05-10 11:05:29 +02006524 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006525 /
6526
6527Set scheduling parameters for the process identified by pid.
6528
6529If pid is 0, sets parameters for the calling process.
6530param should be an instance of sched_param.
6531[clinic start generated code]*/
6532
Larry Hastings2f936352014-08-05 14:04:04 +10006533static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02006534os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
6535/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006536{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006537 struct sched_param param;
6538 if (!convert_sched_param(module, param_obj, &param)) {
6539 return NULL;
6540 }
6541
6542 if (sched_setparam(pid, &param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006543 return posix_error();
6544 Py_RETURN_NONE;
6545}
Larry Hastings2f936352014-08-05 14:04:04 +10006546#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006547
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006548
6549#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006550/*[clinic input]
6551os.sched_rr_get_interval -> double
6552 pid: pid_t
6553 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006554
Larry Hastings2f936352014-08-05 14:04:04 +10006555Return the round-robin quantum for the process identified by pid, in seconds.
6556
6557Value returned is a float.
6558[clinic start generated code]*/
6559
Larry Hastings2f936352014-08-05 14:04:04 +10006560static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006561os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6562/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006563{
6564 struct timespec interval;
6565 if (sched_rr_get_interval(pid, &interval)) {
6566 posix_error();
6567 return -1.0;
6568 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006569#ifdef _Py_MEMORY_SANITIZER
6570 __msan_unpoison(&interval, sizeof(interval));
6571#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006572 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6573}
6574#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006575
Larry Hastings2f936352014-08-05 14:04:04 +10006576
6577/*[clinic input]
6578os.sched_yield
6579
6580Voluntarily relinquish the CPU.
6581[clinic start generated code]*/
6582
Larry Hastings2f936352014-08-05 14:04:04 +10006583static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006584os_sched_yield_impl(PyObject *module)
6585/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006586{
6587 if (sched_yield())
6588 return posix_error();
6589 Py_RETURN_NONE;
6590}
6591
Benjamin Peterson2740af82011-08-02 17:41:34 -05006592#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006593/* The minimum number of CPUs allocated in a cpu_set_t */
6594static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006595
Larry Hastings2f936352014-08-05 14:04:04 +10006596/*[clinic input]
6597os.sched_setaffinity
6598 pid: pid_t
6599 mask : object
6600 /
6601
6602Set the CPU affinity of the process identified by pid to mask.
6603
6604mask should be an iterable of integers identifying CPUs.
6605[clinic start generated code]*/
6606
Larry Hastings2f936352014-08-05 14:04:04 +10006607static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006608os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6609/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006610{
Antoine Pitrou84869872012-08-04 16:16:35 +02006611 int ncpus;
6612 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006613 cpu_set_t *cpu_set = NULL;
6614 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006615
Larry Hastings2f936352014-08-05 14:04:04 +10006616 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006617 if (iterator == NULL)
6618 return NULL;
6619
6620 ncpus = NCPUS_START;
6621 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006622 cpu_set = CPU_ALLOC(ncpus);
6623 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006624 PyErr_NoMemory();
6625 goto error;
6626 }
Larry Hastings2f936352014-08-05 14:04:04 +10006627 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006628
6629 while ((item = PyIter_Next(iterator))) {
6630 long cpu;
6631 if (!PyLong_Check(item)) {
6632 PyErr_Format(PyExc_TypeError,
6633 "expected an iterator of ints, "
6634 "but iterator yielded %R",
6635 Py_TYPE(item));
6636 Py_DECREF(item);
6637 goto error;
6638 }
6639 cpu = PyLong_AsLong(item);
6640 Py_DECREF(item);
6641 if (cpu < 0) {
6642 if (!PyErr_Occurred())
6643 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6644 goto error;
6645 }
6646 if (cpu > INT_MAX - 1) {
6647 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6648 goto error;
6649 }
6650 if (cpu >= ncpus) {
6651 /* Grow CPU mask to fit the CPU number */
6652 int newncpus = ncpus;
6653 cpu_set_t *newmask;
6654 size_t newsetsize;
6655 while (newncpus <= cpu) {
6656 if (newncpus > INT_MAX / 2)
6657 newncpus = cpu + 1;
6658 else
6659 newncpus = newncpus * 2;
6660 }
6661 newmask = CPU_ALLOC(newncpus);
6662 if (newmask == NULL) {
6663 PyErr_NoMemory();
6664 goto error;
6665 }
6666 newsetsize = CPU_ALLOC_SIZE(newncpus);
6667 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006668 memcpy(newmask, cpu_set, setsize);
6669 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006670 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006671 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006672 ncpus = newncpus;
6673 }
Larry Hastings2f936352014-08-05 14:04:04 +10006674 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006675 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07006676 if (PyErr_Occurred()) {
6677 goto error;
6678 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006679 Py_CLEAR(iterator);
6680
Larry Hastings2f936352014-08-05 14:04:04 +10006681 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006682 posix_error();
6683 goto error;
6684 }
Larry Hastings2f936352014-08-05 14:04:04 +10006685 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006686 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006687
6688error:
Larry Hastings2f936352014-08-05 14:04:04 +10006689 if (cpu_set)
6690 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006691 Py_XDECREF(iterator);
6692 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006693}
6694
Larry Hastings2f936352014-08-05 14:04:04 +10006695
6696/*[clinic input]
6697os.sched_getaffinity
6698 pid: pid_t
6699 /
6700
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006701Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006702
6703The affinity is returned as a set of CPU identifiers.
6704[clinic start generated code]*/
6705
Larry Hastings2f936352014-08-05 14:04:04 +10006706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006707os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006708/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006709{
Antoine Pitrou84869872012-08-04 16:16:35 +02006710 int cpu, ncpus, count;
6711 size_t setsize;
6712 cpu_set_t *mask = NULL;
6713 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006714
Antoine Pitrou84869872012-08-04 16:16:35 +02006715 ncpus = NCPUS_START;
6716 while (1) {
6717 setsize = CPU_ALLOC_SIZE(ncpus);
6718 mask = CPU_ALLOC(ncpus);
6719 if (mask == NULL)
6720 return PyErr_NoMemory();
6721 if (sched_getaffinity(pid, setsize, mask) == 0)
6722 break;
6723 CPU_FREE(mask);
6724 if (errno != EINVAL)
6725 return posix_error();
6726 if (ncpus > INT_MAX / 2) {
6727 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6728 "a large enough CPU set");
6729 return NULL;
6730 }
6731 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006732 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006733
6734 res = PySet_New(NULL);
6735 if (res == NULL)
6736 goto error;
6737 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6738 if (CPU_ISSET_S(cpu, setsize, mask)) {
6739 PyObject *cpu_num = PyLong_FromLong(cpu);
6740 --count;
6741 if (cpu_num == NULL)
6742 goto error;
6743 if (PySet_Add(res, cpu_num)) {
6744 Py_DECREF(cpu_num);
6745 goto error;
6746 }
6747 Py_DECREF(cpu_num);
6748 }
6749 }
6750 CPU_FREE(mask);
6751 return res;
6752
6753error:
6754 if (mask)
6755 CPU_FREE(mask);
6756 Py_XDECREF(res);
6757 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006758}
6759
Benjamin Peterson2740af82011-08-02 17:41:34 -05006760#endif /* HAVE_SCHED_SETAFFINITY */
6761
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006762#endif /* HAVE_SCHED_H */
6763
Larry Hastings2f936352014-08-05 14:04:04 +10006764
Neal Norwitzb59798b2003-03-21 01:43:31 +00006765/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006766#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Victor Stinner57766632020-10-29 15:16:23 +01006767# define DEV_PTY_FILE "/dev/ptc"
6768# define HAVE_DEV_PTMX
Neal Norwitzb59798b2003-03-21 01:43:31 +00006769#else
Victor Stinner57766632020-10-29 15:16:23 +01006770# define DEV_PTY_FILE "/dev/ptmx"
Neal Norwitzb59798b2003-03-21 01:43:31 +00006771#endif
6772
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006773#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006774#ifdef HAVE_PTY_H
6775#include <pty.h>
6776#else
6777#ifdef HAVE_LIBUTIL_H
6778#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006779#else
6780#ifdef HAVE_UTIL_H
6781#include <util.h>
6782#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006783#endif /* HAVE_LIBUTIL_H */
6784#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006785#ifdef HAVE_STROPTS_H
6786#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006787#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006788#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006789
Larry Hastings2f936352014-08-05 14:04:04 +10006790
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006791#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006792/*[clinic input]
6793os.openpty
6794
6795Open a pseudo-terminal.
6796
6797Return a tuple of (master_fd, slave_fd) containing open file descriptors
6798for both the master and slave ends.
6799[clinic start generated code]*/
6800
Larry Hastings2f936352014-08-05 14:04:04 +10006801static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006802os_openpty_impl(PyObject *module)
6803/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006804{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006805 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006806#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006807 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006808#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006809#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006810 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006811#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006813#endif
6814#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006815
Thomas Wouters70c21a12000-07-14 14:28:33 +00006816#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006818 goto posix_error;
6819
6820 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6821 goto error;
6822 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6823 goto error;
6824
Neal Norwitzb59798b2003-03-21 01:43:31 +00006825#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6827 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006828 goto posix_error;
6829 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6830 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006831
Victor Stinnerdaf45552013-08-28 00:53:59 +02006832 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006834 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006835
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006836#else
Victor Stinner000de532013-11-25 23:19:58 +01006837 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006839 goto posix_error;
6840
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006842
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 /* change permission of slave */
6844 if (grantpt(master_fd) < 0) {
6845 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006846 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006848
Victor Stinner8c62be82010-05-06 00:08:46 +00006849 /* unlock slave */
6850 if (unlockpt(master_fd) < 0) {
6851 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006852 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006854
Victor Stinner8c62be82010-05-06 00:08:46 +00006855 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006856
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 slave_name = ptsname(master_fd); /* get name of slave */
6858 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006859 goto posix_error;
6860
6861 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006862 if (slave_fd == -1)
6863 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006864
6865 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6866 goto posix_error;
6867
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006868#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6870 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006871#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006873#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006874#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006875#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006876
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006878
Victor Stinnerdaf45552013-08-28 00:53:59 +02006879posix_error:
6880 posix_error();
6881error:
6882 if (master_fd != -1)
6883 close(master_fd);
6884 if (slave_fd != -1)
6885 close(slave_fd);
6886 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006887}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006888#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006889
Larry Hastings2f936352014-08-05 14:04:04 +10006890
Fred Drake8cef4cf2000-06-28 16:40:38 +00006891#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006892/*[clinic input]
6893os.forkpty
6894
6895Fork a new process with a new pseudo-terminal as controlling tty.
6896
6897Returns a tuple of (pid, master_fd).
6898Like fork(), return pid of 0 to the child process,
6899and pid of child to the parent process.
6900To both, return fd of newly opened pseudo-terminal.
6901[clinic start generated code]*/
6902
Larry Hastings2f936352014-08-05 14:04:04 +10006903static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006904os_forkpty_impl(PyObject *module)
6905/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006906{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006907 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006909
Victor Stinner81a7be32020-04-14 15:14:01 +02006910 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006911 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6912 return NULL;
6913 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006914 if (PySys_Audit("os.forkpty", NULL) < 0) {
6915 return NULL;
6916 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006917 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006918 pid = forkpty(&master_fd, NULL, NULL, NULL);
6919 if (pid == 0) {
6920 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006921 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 } else {
6923 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006924 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 }
6926 if (pid == -1)
6927 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006929}
Larry Hastings2f936352014-08-05 14:04:04 +10006930#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006931
Ross Lagerwall7807c352011-03-17 20:20:30 +02006932
Guido van Rossumad0ee831995-03-01 10:34:45 +00006933#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006934/*[clinic input]
6935os.getegid
6936
6937Return the current process's effective group id.
6938[clinic start generated code]*/
6939
Larry Hastings2f936352014-08-05 14:04:04 +10006940static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006941os_getegid_impl(PyObject *module)
6942/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006943{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006944 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006945}
Larry Hastings2f936352014-08-05 14:04:04 +10006946#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006947
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006948
Guido van Rossumad0ee831995-03-01 10:34:45 +00006949#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006950/*[clinic input]
6951os.geteuid
6952
6953Return the current process's effective user id.
6954[clinic start generated code]*/
6955
Larry Hastings2f936352014-08-05 14:04:04 +10006956static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006957os_geteuid_impl(PyObject *module)
6958/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006959{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006960 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006961}
Larry Hastings2f936352014-08-05 14:04:04 +10006962#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006963
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006964
Guido van Rossumad0ee831995-03-01 10:34:45 +00006965#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006966/*[clinic input]
6967os.getgid
6968
6969Return the current process's group id.
6970[clinic start generated code]*/
6971
Larry Hastings2f936352014-08-05 14:04:04 +10006972static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006973os_getgid_impl(PyObject *module)
6974/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006975{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006976 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006977}
Larry Hastings2f936352014-08-05 14:04:04 +10006978#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006979
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006980
Berker Peksag39404992016-09-15 20:45:16 +03006981#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006982/*[clinic input]
6983os.getpid
6984
6985Return the current process id.
6986[clinic start generated code]*/
6987
Larry Hastings2f936352014-08-05 14:04:04 +10006988static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006989os_getpid_impl(PyObject *module)
6990/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006991{
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006993}
Berker Peksag39404992016-09-15 20:45:16 +03006994#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006995
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006996#ifdef NGROUPS_MAX
6997#define MAX_GROUPS NGROUPS_MAX
6998#else
6999 /* defined to be 16 on Solaris7, so this should be a small number */
7000#define MAX_GROUPS 64
7001#endif
7002
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007003#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10007004
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007005#ifdef __APPLE__
7006/*[clinic input]
7007os.getgrouplist
7008
7009 user: str
7010 username to lookup
7011 group as basegid: int
7012 base group id of the user
7013 /
7014
7015Returns a list of groups to which a user belongs.
7016[clinic start generated code]*/
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007017
7018static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007019os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
7020/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
7021#else
7022/*[clinic input]
7023os.getgrouplist
7024
7025 user: str
7026 username to lookup
7027 group as basegid: gid_t
7028 base group id of the user
7029 /
7030
7031Returns a list of groups to which a user belongs.
7032[clinic start generated code]*/
7033
7034static PyObject *
7035os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
7036/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
7037#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007038{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007039 int i, ngroups;
7040 PyObject *list;
7041#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007042 int *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007043#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007044 gid_t *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007045#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007046
7047 /*
7048 * NGROUPS_MAX is defined by POSIX.1 as the maximum
7049 * number of supplimental groups a users can belong to.
7050 * We have to increment it by one because
7051 * getgrouplist() returns both the supplemental groups
7052 * and the primary group, i.e. all of the groups the
7053 * user belongs to.
7054 */
7055 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007056
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007057 while (1) {
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007058#ifdef __APPLE__
Victor Stinner8ec73702020-03-23 20:00:57 +01007059 groups = PyMem_New(int, ngroups);
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007060#else
7061 groups = PyMem_New(gid_t, ngroups);
7062#endif
Victor Stinner8ec73702020-03-23 20:00:57 +01007063 if (groups == NULL) {
7064 return PyErr_NoMemory();
7065 }
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007066
7067 int old_ngroups = ngroups;
7068 if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
7069 /* Success */
7070 break;
7071 }
7072
7073 /* getgrouplist() fails if the group list is too small */
7074 PyMem_Free(groups);
7075
7076 if (ngroups > old_ngroups) {
7077 /* If the group list is too small, the glibc implementation of
7078 getgrouplist() sets ngroups to the total number of groups and
7079 returns -1. */
7080 }
7081 else {
7082 /* Double the group list size */
7083 if (ngroups > INT_MAX / 2) {
7084 return PyErr_NoMemory();
7085 }
7086 ngroups *= 2;
7087 }
7088
7089 /* Retry getgrouplist() with a larger group list */
Victor Stinner8ec73702020-03-23 20:00:57 +01007090 }
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007091
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007092#ifdef _Py_MEMORY_SANITIZER
7093 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7094 __msan_unpoison(&ngroups, sizeof(ngroups));
7095 __msan_unpoison(groups, ngroups*sizeof(*groups));
7096#endif
7097
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007098 list = PyList_New(ngroups);
7099 if (list == NULL) {
7100 PyMem_Del(groups);
7101 return NULL;
7102 }
7103
7104 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007105#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007106 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007107#else
7108 PyObject *o = _PyLong_FromGid(groups[i]);
7109#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007110 if (o == NULL) {
7111 Py_DECREF(list);
7112 PyMem_Del(groups);
7113 return NULL;
7114 }
7115 PyList_SET_ITEM(list, i, o);
7116 }
7117
7118 PyMem_Del(groups);
7119
7120 return list;
7121}
Larry Hastings2f936352014-08-05 14:04:04 +10007122#endif /* HAVE_GETGROUPLIST */
7123
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007124
Fred Drakec9680921999-12-13 16:37:25 +00007125#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007126/*[clinic input]
7127os.getgroups
7128
7129Return list of supplemental group IDs for the process.
7130[clinic start generated code]*/
7131
Larry Hastings2f936352014-08-05 14:04:04 +10007132static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007133os_getgroups_impl(PyObject *module)
7134/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007135{
7136 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007137 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007138
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007139 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007140 * This is a helper variable to store the intermediate result when
7141 * that happens.
7142 *
7143 * To keep the code readable the OSX behaviour is unconditional,
7144 * according to the POSIX spec this should be safe on all unix-y
7145 * systems.
7146 */
7147 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007148 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007149
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007150#ifdef __APPLE__
7151 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7152 * there are more groups than can fit in grouplist. Therefore, on OS X
7153 * always first call getgroups with length 0 to get the actual number
7154 * of groups.
7155 */
7156 n = getgroups(0, NULL);
7157 if (n < 0) {
7158 return posix_error();
7159 } else if (n <= MAX_GROUPS) {
7160 /* groups will fit in existing array */
7161 alt_grouplist = grouplist;
7162 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007163 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007164 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007165 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007166 }
7167 }
7168
7169 n = getgroups(n, alt_grouplist);
7170 if (n == -1) {
7171 if (alt_grouplist != grouplist) {
7172 PyMem_Free(alt_grouplist);
7173 }
7174 return posix_error();
7175 }
7176#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007177 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007178 if (n < 0) {
7179 if (errno == EINVAL) {
7180 n = getgroups(0, NULL);
7181 if (n == -1) {
7182 return posix_error();
7183 }
7184 if (n == 0) {
7185 /* Avoid malloc(0) */
7186 alt_grouplist = grouplist;
7187 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007188 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007189 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007190 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007191 }
7192 n = getgroups(n, alt_grouplist);
7193 if (n == -1) {
7194 PyMem_Free(alt_grouplist);
7195 return posix_error();
7196 }
7197 }
7198 } else {
7199 return posix_error();
7200 }
7201 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007202#endif
7203
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007204 result = PyList_New(n);
7205 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007206 int i;
7207 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007208 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007209 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007210 Py_DECREF(result);
7211 result = NULL;
7212 break;
Fred Drakec9680921999-12-13 16:37:25 +00007213 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007214 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007215 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007216 }
7217
7218 if (alt_grouplist != grouplist) {
7219 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007220 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007221
Fred Drakec9680921999-12-13 16:37:25 +00007222 return result;
7223}
Larry Hastings2f936352014-08-05 14:04:04 +10007224#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007225
Antoine Pitroub7572f02009-12-02 20:46:48 +00007226#ifdef HAVE_INITGROUPS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007227#ifdef __APPLE__
7228/*[clinic input]
7229os.initgroups
Antoine Pitroub7572f02009-12-02 20:46:48 +00007230
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007231 username as oname: FSConverter
7232 gid: int
7233 /
7234
7235Initialize the group access list.
7236
7237Call the system initgroups() to initialize the group access list with all of
7238the groups of which the specified username is a member, plus the specified
7239group id.
7240[clinic start generated code]*/
7241
Antoine Pitroub7572f02009-12-02 20:46:48 +00007242static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007243os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7244/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7245#else
7246/*[clinic input]
7247os.initgroups
7248
7249 username as oname: FSConverter
7250 gid: gid_t
7251 /
7252
7253Initialize the group access list.
7254
7255Call the system initgroups() to initialize the group access list with all of
7256the groups of which the specified username is a member, plus the specified
7257group id.
7258[clinic start generated code]*/
7259
7260static PyObject *
7261os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7262/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7263#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007264{
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007265 const char *username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007266
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007267 if (initgroups(username, gid) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007268 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007269
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007270 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007271}
Larry Hastings2f936352014-08-05 14:04:04 +10007272#endif /* HAVE_INITGROUPS */
7273
Antoine Pitroub7572f02009-12-02 20:46:48 +00007274
Martin v. Löwis606edc12002-06-13 21:09:11 +00007275#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007276/*[clinic input]
7277os.getpgid
7278
7279 pid: pid_t
7280
7281Call the system call getpgid(), and return the result.
7282[clinic start generated code]*/
7283
Larry Hastings2f936352014-08-05 14:04:04 +10007284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007285os_getpgid_impl(PyObject *module, pid_t pid)
7286/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007287{
7288 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007289 if (pgid < 0)
7290 return posix_error();
7291 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007292}
7293#endif /* HAVE_GETPGID */
7294
7295
Guido van Rossumb6775db1994-08-01 11:34:53 +00007296#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007297/*[clinic input]
7298os.getpgrp
7299
7300Return the current process group id.
7301[clinic start generated code]*/
7302
Larry Hastings2f936352014-08-05 14:04:04 +10007303static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007304os_getpgrp_impl(PyObject *module)
7305/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007306{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007307#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007308 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007309#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007310 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007311#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007312}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007313#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007314
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007315
Guido van Rossumb6775db1994-08-01 11:34:53 +00007316#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007317/*[clinic input]
7318os.setpgrp
7319
7320Make the current process the leader of its process group.
7321[clinic start generated code]*/
7322
Larry Hastings2f936352014-08-05 14:04:04 +10007323static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007324os_setpgrp_impl(PyObject *module)
7325/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007326{
Guido van Rossum64933891994-10-20 21:56:42 +00007327#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007328 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007329#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007330 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007331#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007332 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007333 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007334}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007335#endif /* HAVE_SETPGRP */
7336
Guido van Rossumad0ee831995-03-01 10:34:45 +00007337#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007338
7339#ifdef MS_WINDOWS
7340#include <tlhelp32.h>
7341
7342static PyObject*
7343win32_getppid()
7344{
7345 HANDLE snapshot;
7346 pid_t mypid;
7347 PyObject* result = NULL;
7348 BOOL have_record;
7349 PROCESSENTRY32 pe;
7350
7351 mypid = getpid(); /* This function never fails */
7352
7353 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7354 if (snapshot == INVALID_HANDLE_VALUE)
7355 return PyErr_SetFromWindowsErr(GetLastError());
7356
7357 pe.dwSize = sizeof(pe);
7358 have_record = Process32First(snapshot, &pe);
7359 while (have_record) {
7360 if (mypid == (pid_t)pe.th32ProcessID) {
7361 /* We could cache the ulong value in a static variable. */
7362 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7363 break;
7364 }
7365
7366 have_record = Process32Next(snapshot, &pe);
7367 }
7368
7369 /* If our loop exits and our pid was not found (result will be NULL)
7370 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7371 * error anyway, so let's raise it. */
7372 if (!result)
7373 result = PyErr_SetFromWindowsErr(GetLastError());
7374
7375 CloseHandle(snapshot);
7376
7377 return result;
7378}
7379#endif /*MS_WINDOWS*/
7380
Larry Hastings2f936352014-08-05 14:04:04 +10007381
7382/*[clinic input]
7383os.getppid
7384
7385Return the parent's process id.
7386
7387If the parent process has already exited, Windows machines will still
7388return its id; others systems will return the id of the 'init' process (1).
7389[clinic start generated code]*/
7390
Larry Hastings2f936352014-08-05 14:04:04 +10007391static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007392os_getppid_impl(PyObject *module)
7393/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007394{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007395#ifdef MS_WINDOWS
7396 return win32_getppid();
7397#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007398 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007399#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007400}
7401#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007402
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007403
Fred Drake12c6e2d1999-12-14 21:25:03 +00007404#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007405/*[clinic input]
7406os.getlogin
7407
7408Return the actual login name.
7409[clinic start generated code]*/
7410
Larry Hastings2f936352014-08-05 14:04:04 +10007411static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007412os_getlogin_impl(PyObject *module)
7413/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007414{
Victor Stinner8c62be82010-05-06 00:08:46 +00007415 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007416#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007417 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007418 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007419
7420 if (GetUserNameW(user_name, &num_chars)) {
7421 /* num_chars is the number of unicode chars plus null terminator */
7422 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007423 }
7424 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007425 result = PyErr_SetFromWindowsErr(GetLastError());
7426#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007427 char *name;
7428 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007429
Victor Stinner8c62be82010-05-06 00:08:46 +00007430 errno = 0;
7431 name = getlogin();
7432 if (name == NULL) {
7433 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007434 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007435 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007436 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007437 }
7438 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007439 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007440 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007441#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007442 return result;
7443}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007444#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007445
Larry Hastings2f936352014-08-05 14:04:04 +10007446
Guido van Rossumad0ee831995-03-01 10:34:45 +00007447#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007448/*[clinic input]
7449os.getuid
7450
7451Return the current process's user id.
7452[clinic start generated code]*/
7453
Larry Hastings2f936352014-08-05 14:04:04 +10007454static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007455os_getuid_impl(PyObject *module)
7456/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007457{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007458 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007459}
Larry Hastings2f936352014-08-05 14:04:04 +10007460#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007461
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007462
Brian Curtineb24d742010-04-12 17:16:38 +00007463#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007464#define HAVE_KILL
7465#endif /* MS_WINDOWS */
7466
7467#ifdef HAVE_KILL
7468/*[clinic input]
7469os.kill
7470
7471 pid: pid_t
7472 signal: Py_ssize_t
7473 /
7474
7475Kill a process with a signal.
7476[clinic start generated code]*/
7477
Larry Hastings2f936352014-08-05 14:04:04 +10007478static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007479os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7480/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007481{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007482 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7483 return NULL;
7484 }
7485#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007486 if (kill(pid, (int)signal) == -1)
7487 return posix_error();
7488 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007489#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007490 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007491 DWORD sig = (DWORD)signal;
7492 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007493 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007494
Victor Stinner8c62be82010-05-06 00:08:46 +00007495 /* Console processes which share a common console can be sent CTRL+C or
7496 CTRL+BREAK events, provided they handle said events. */
7497 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007498 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007499 err = GetLastError();
7500 PyErr_SetFromWindowsErr(err);
7501 }
7502 else
7503 Py_RETURN_NONE;
7504 }
Brian Curtineb24d742010-04-12 17:16:38 +00007505
Victor Stinner8c62be82010-05-06 00:08:46 +00007506 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7507 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007508 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007509 if (handle == NULL) {
7510 err = GetLastError();
7511 return PyErr_SetFromWindowsErr(err);
7512 }
Brian Curtineb24d742010-04-12 17:16:38 +00007513
Victor Stinner8c62be82010-05-06 00:08:46 +00007514 if (TerminateProcess(handle, sig) == 0) {
7515 err = GetLastError();
7516 result = PyErr_SetFromWindowsErr(err);
7517 } else {
7518 Py_INCREF(Py_None);
7519 result = Py_None;
7520 }
Brian Curtineb24d742010-04-12 17:16:38 +00007521
Victor Stinner8c62be82010-05-06 00:08:46 +00007522 CloseHandle(handle);
7523 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007524#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007525}
Larry Hastings2f936352014-08-05 14:04:04 +10007526#endif /* HAVE_KILL */
7527
7528
7529#ifdef HAVE_KILLPG
7530/*[clinic input]
7531os.killpg
7532
7533 pgid: pid_t
7534 signal: int
7535 /
7536
7537Kill a process group with a signal.
7538[clinic start generated code]*/
7539
Larry Hastings2f936352014-08-05 14:04:04 +10007540static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007541os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7542/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007543{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007544 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7545 return NULL;
7546 }
Larry Hastings2f936352014-08-05 14:04:04 +10007547 /* XXX some man pages make the `pgid` parameter an int, others
7548 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7549 take the same type. Moreover, pid_t is always at least as wide as
7550 int (else compilation of this module fails), which is safe. */
7551 if (killpg(pgid, signal) == -1)
7552 return posix_error();
7553 Py_RETURN_NONE;
7554}
7555#endif /* HAVE_KILLPG */
7556
Brian Curtineb24d742010-04-12 17:16:38 +00007557
Guido van Rossumc0125471996-06-28 18:55:32 +00007558#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007559#ifdef HAVE_SYS_LOCK_H
7560#include <sys/lock.h>
7561#endif
7562
Larry Hastings2f936352014-08-05 14:04:04 +10007563/*[clinic input]
7564os.plock
7565 op: int
7566 /
7567
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007568Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007569[clinic start generated code]*/
7570
Larry Hastings2f936352014-08-05 14:04:04 +10007571static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007572os_plock_impl(PyObject *module, int op)
7573/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007574{
Victor Stinner8c62be82010-05-06 00:08:46 +00007575 if (plock(op) == -1)
7576 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007577 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007578}
Larry Hastings2f936352014-08-05 14:04:04 +10007579#endif /* HAVE_PLOCK */
7580
Guido van Rossumc0125471996-06-28 18:55:32 +00007581
Guido van Rossumb6775db1994-08-01 11:34:53 +00007582#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007583/*[clinic input]
7584os.setuid
7585
7586 uid: uid_t
7587 /
7588
7589Set the current process's user id.
7590[clinic start generated code]*/
7591
Larry Hastings2f936352014-08-05 14:04:04 +10007592static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007593os_setuid_impl(PyObject *module, uid_t uid)
7594/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007595{
Victor Stinner8c62be82010-05-06 00:08:46 +00007596 if (setuid(uid) < 0)
7597 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007598 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007599}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007600#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007601
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007602
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007603#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007604/*[clinic input]
7605os.seteuid
7606
7607 euid: uid_t
7608 /
7609
7610Set the current process's effective user id.
7611[clinic start generated code]*/
7612
Larry Hastings2f936352014-08-05 14:04:04 +10007613static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007614os_seteuid_impl(PyObject *module, uid_t euid)
7615/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007616{
7617 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007619 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007620}
7621#endif /* HAVE_SETEUID */
7622
Larry Hastings2f936352014-08-05 14:04:04 +10007623
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007624#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007625/*[clinic input]
7626os.setegid
7627
7628 egid: gid_t
7629 /
7630
7631Set the current process's effective group id.
7632[clinic start generated code]*/
7633
Larry Hastings2f936352014-08-05 14:04:04 +10007634static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007635os_setegid_impl(PyObject *module, gid_t egid)
7636/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007637{
7638 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007640 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007641}
7642#endif /* HAVE_SETEGID */
7643
Larry Hastings2f936352014-08-05 14:04:04 +10007644
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007645#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007646/*[clinic input]
7647os.setreuid
7648
7649 ruid: uid_t
7650 euid: uid_t
7651 /
7652
7653Set the current process's real and effective user ids.
7654[clinic start generated code]*/
7655
Larry Hastings2f936352014-08-05 14:04:04 +10007656static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007657os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7658/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007659{
Victor Stinner8c62be82010-05-06 00:08:46 +00007660 if (setreuid(ruid, euid) < 0) {
7661 return posix_error();
7662 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007663 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007664 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007665}
7666#endif /* HAVE_SETREUID */
7667
Larry Hastings2f936352014-08-05 14:04:04 +10007668
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007669#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007670/*[clinic input]
7671os.setregid
7672
7673 rgid: gid_t
7674 egid: gid_t
7675 /
7676
7677Set the current process's real and effective group ids.
7678[clinic start generated code]*/
7679
Larry Hastings2f936352014-08-05 14:04:04 +10007680static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007681os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7682/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007683{
7684 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007685 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007686 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007687}
7688#endif /* HAVE_SETREGID */
7689
Larry Hastings2f936352014-08-05 14:04:04 +10007690
Guido van Rossumb6775db1994-08-01 11:34:53 +00007691#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007692/*[clinic input]
7693os.setgid
7694 gid: gid_t
7695 /
7696
7697Set the current process's group id.
7698[clinic start generated code]*/
7699
Larry Hastings2f936352014-08-05 14:04:04 +10007700static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007701os_setgid_impl(PyObject *module, gid_t gid)
7702/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007703{
Victor Stinner8c62be82010-05-06 00:08:46 +00007704 if (setgid(gid) < 0)
7705 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007706 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007707}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007708#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007709
Larry Hastings2f936352014-08-05 14:04:04 +10007710
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007711#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007712/*[clinic input]
7713os.setgroups
7714
7715 groups: object
7716 /
7717
7718Set the groups of the current process to list.
7719[clinic start generated code]*/
7720
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007721static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007722os_setgroups(PyObject *module, PyObject *groups)
7723/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007724{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007725 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007727
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 if (!PySequence_Check(groups)) {
7729 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7730 return NULL;
7731 }
7732 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007733 if (len < 0) {
7734 return NULL;
7735 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007736 if (len > MAX_GROUPS) {
7737 PyErr_SetString(PyExc_ValueError, "too many groups");
7738 return NULL;
7739 }
7740 for(i = 0; i < len; i++) {
7741 PyObject *elem;
7742 elem = PySequence_GetItem(groups, i);
7743 if (!elem)
7744 return NULL;
7745 if (!PyLong_Check(elem)) {
7746 PyErr_SetString(PyExc_TypeError,
7747 "groups must be integers");
7748 Py_DECREF(elem);
7749 return NULL;
7750 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007751 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 Py_DECREF(elem);
7753 return NULL;
7754 }
7755 }
7756 Py_DECREF(elem);
7757 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007758
Victor Stinner8c62be82010-05-06 00:08:46 +00007759 if (setgroups(len, grouplist) < 0)
7760 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007761 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007762}
7763#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007764
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007765#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7766static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02007767wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007768{
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08007770 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007771
Victor Stinner8c62be82010-05-06 00:08:46 +00007772 if (pid == -1)
7773 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007774
Zackery Spytz682107c2019-09-09 09:48:32 -06007775 // If wait succeeded but no child was ready to report status, ru will not
7776 // have been populated.
7777 if (pid == 0) {
7778 memset(ru, 0, sizeof(*ru));
7779 }
7780
Eddie Elizondob3966632019-11-05 07:16:14 -08007781 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7782 if (m == NULL)
7783 return NULL;
Victor Stinner1c2fa782020-05-10 11:05:29 +02007784 struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08007785 Py_DECREF(m);
7786 if (struct_rusage == NULL)
7787 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007788
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7790 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08007791 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007792 if (!result)
7793 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007794
7795#ifndef doubletime
7796#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7797#endif
7798
Victor Stinner8c62be82010-05-06 00:08:46 +00007799 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007800 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007802 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007803#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7805 SET_INT(result, 2, ru->ru_maxrss);
7806 SET_INT(result, 3, ru->ru_ixrss);
7807 SET_INT(result, 4, ru->ru_idrss);
7808 SET_INT(result, 5, ru->ru_isrss);
7809 SET_INT(result, 6, ru->ru_minflt);
7810 SET_INT(result, 7, ru->ru_majflt);
7811 SET_INT(result, 8, ru->ru_nswap);
7812 SET_INT(result, 9, ru->ru_inblock);
7813 SET_INT(result, 10, ru->ru_oublock);
7814 SET_INT(result, 11, ru->ru_msgsnd);
7815 SET_INT(result, 12, ru->ru_msgrcv);
7816 SET_INT(result, 13, ru->ru_nsignals);
7817 SET_INT(result, 14, ru->ru_nvcsw);
7818 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007819#undef SET_INT
7820
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 if (PyErr_Occurred()) {
7822 Py_DECREF(result);
7823 return NULL;
7824 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007825
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007827}
7828#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7829
Larry Hastings2f936352014-08-05 14:04:04 +10007830
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007831#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007832/*[clinic input]
7833os.wait3
7834
7835 options: int
7836Wait for completion of a child process.
7837
7838Returns a tuple of information about the child process:
7839 (pid, status, rusage)
7840[clinic start generated code]*/
7841
Larry Hastings2f936352014-08-05 14:04:04 +10007842static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007843os_wait3_impl(PyObject *module, int options)
7844/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007845{
Victor Stinner8c62be82010-05-06 00:08:46 +00007846 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007848 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007849 WAIT_TYPE status;
7850 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007851
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007852 do {
7853 Py_BEGIN_ALLOW_THREADS
7854 pid = wait3(&status, options, &ru);
7855 Py_END_ALLOW_THREADS
7856 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7857 if (pid < 0)
7858 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007859
Victor Stinner1c2fa782020-05-10 11:05:29 +02007860 return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007861}
7862#endif /* HAVE_WAIT3 */
7863
Larry Hastings2f936352014-08-05 14:04:04 +10007864
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007865#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007866/*[clinic input]
7867
7868os.wait4
7869
7870 pid: pid_t
7871 options: int
7872
7873Wait for completion of a specific child process.
7874
7875Returns a tuple of information about the child process:
7876 (pid, status, rusage)
7877[clinic start generated code]*/
7878
Larry Hastings2f936352014-08-05 14:04:04 +10007879static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007880os_wait4_impl(PyObject *module, pid_t pid, int options)
7881/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007882{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007883 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007884 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007885 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007886 WAIT_TYPE status;
7887 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007888
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007889 do {
7890 Py_BEGIN_ALLOW_THREADS
7891 res = wait4(pid, &status, options, &ru);
7892 Py_END_ALLOW_THREADS
7893 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7894 if (res < 0)
7895 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007896
Victor Stinner1c2fa782020-05-10 11:05:29 +02007897 return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007898}
7899#endif /* HAVE_WAIT4 */
7900
Larry Hastings2f936352014-08-05 14:04:04 +10007901
Ross Lagerwall7807c352011-03-17 20:20:30 +02007902#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007903/*[clinic input]
7904os.waitid
7905
7906 idtype: idtype_t
7907 Must be one of be P_PID, P_PGID or P_ALL.
7908 id: id_t
7909 The id to wait on.
7910 options: int
7911 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7912 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7913 /
7914
7915Returns the result of waiting for a process or processes.
7916
7917Returns either waitid_result or None if WNOHANG is specified and there are
7918no children in a waitable state.
7919[clinic start generated code]*/
7920
Larry Hastings2f936352014-08-05 14:04:04 +10007921static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007922os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7923/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007924{
7925 PyObject *result;
7926 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007927 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007928 siginfo_t si;
7929 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007930
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007931 do {
7932 Py_BEGIN_ALLOW_THREADS
7933 res = waitid(idtype, id, &si, options);
7934 Py_END_ALLOW_THREADS
7935 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7936 if (res < 0)
7937 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007938
7939 if (si.si_pid == 0)
7940 Py_RETURN_NONE;
7941
Hai Shif707d942020-03-16 21:15:01 +08007942 PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08007943 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007944 if (!result)
7945 return NULL;
7946
7947 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007948 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007949 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7950 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7951 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7952 if (PyErr_Occurred()) {
7953 Py_DECREF(result);
7954 return NULL;
7955 }
7956
7957 return result;
7958}
Larry Hastings2f936352014-08-05 14:04:04 +10007959#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007960
Larry Hastings2f936352014-08-05 14:04:04 +10007961
7962#if defined(HAVE_WAITPID)
7963/*[clinic input]
7964os.waitpid
7965 pid: pid_t
7966 options: int
7967 /
7968
7969Wait for completion of a given child process.
7970
7971Returns a tuple of information regarding the child process:
7972 (pid, status)
7973
7974The options argument is ignored on Windows.
7975[clinic start generated code]*/
7976
Larry Hastings2f936352014-08-05 14:04:04 +10007977static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007978os_waitpid_impl(PyObject *module, pid_t pid, int options)
7979/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007980{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007981 pid_t res;
7982 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 WAIT_TYPE status;
7984 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007985
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007986 do {
7987 Py_BEGIN_ALLOW_THREADS
7988 res = waitpid(pid, &status, options);
7989 Py_END_ALLOW_THREADS
7990 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7991 if (res < 0)
7992 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007993
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007994 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007995}
Tim Petersab034fa2002-02-01 11:27:43 +00007996#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007997/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007998/*[clinic input]
7999os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07008000 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10008001 options: int
8002 /
8003
8004Wait for completion of a given process.
8005
8006Returns a tuple of information regarding the process:
8007 (pid, status << 8)
8008
8009The options argument is ignored on Windows.
8010[clinic start generated code]*/
8011
Larry Hastings2f936352014-08-05 14:04:04 +10008012static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07008013os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07008014/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008015{
8016 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07008017 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008018 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008019
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008020 do {
8021 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08008022 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008023 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08008024 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008025 Py_END_ALLOW_THREADS
8026 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008027 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008028 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008029
Victor Stinner9bee32b2020-04-22 16:30:35 +02008030 unsigned long long ustatus = (unsigned int)status;
8031
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 /* shift the status left a byte so this is more like the POSIX waitpid */
Victor Stinner9bee32b2020-04-22 16:30:35 +02008033 return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00008034}
Larry Hastings2f936352014-08-05 14:04:04 +10008035#endif
8036
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008037
Guido van Rossumad0ee831995-03-01 10:34:45 +00008038#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10008039/*[clinic input]
8040os.wait
8041
8042Wait for completion of a child process.
8043
8044Returns a tuple of information about the child process:
8045 (pid, status)
8046[clinic start generated code]*/
8047
Larry Hastings2f936352014-08-05 14:04:04 +10008048static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008049os_wait_impl(PyObject *module)
8050/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00008051{
Victor Stinner8c62be82010-05-06 00:08:46 +00008052 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008053 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008054 WAIT_TYPE status;
8055 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00008056
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008057 do {
8058 Py_BEGIN_ALLOW_THREADS
8059 pid = wait(&status);
8060 Py_END_ALLOW_THREADS
8061 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8062 if (pid < 0)
8063 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008064
Victor Stinner8c62be82010-05-06 00:08:46 +00008065 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00008066}
Larry Hastings2f936352014-08-05 14:04:04 +10008067#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008068
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08008069#if defined(__linux__) && defined(__NR_pidfd_open)
8070/*[clinic input]
8071os.pidfd_open
8072 pid: pid_t
8073 flags: unsigned_int = 0
8074
8075Return a file descriptor referring to the process *pid*.
8076
8077The descriptor can be used to perform process management without races and
8078signals.
8079[clinic start generated code]*/
8080
8081static PyObject *
8082os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8083/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8084{
8085 int fd = syscall(__NR_pidfd_open, pid, flags);
8086 if (fd < 0) {
8087 return posix_error();
8088 }
8089 return PyLong_FromLong(fd);
8090}
8091#endif
8092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008093
Larry Hastings9cf065c2012-06-22 16:30:09 -07008094#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008095/*[clinic input]
8096os.readlink
8097
8098 path: path_t
8099 *
8100 dir_fd: dir_fd(requires='readlinkat') = None
8101
8102Return a string representing the path to which the symbolic link points.
8103
8104If dir_fd is not None, it should be a file descriptor open to a directory,
8105and path should be relative; path will then be relative to that directory.
8106
8107dir_fd may not be implemented on your platform. If it is unavailable,
8108using it will raise a NotImplementedError.
8109[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008110
Barry Warsaw53699e91996-12-10 23:23:01 +00008111static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008112os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8113/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008114{
Berker Peksage0b5b202018-08-15 13:03:41 +03008115#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008116 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008117 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008118
8119 Py_BEGIN_ALLOW_THREADS
8120#ifdef HAVE_READLINKAT
8121 if (dir_fd != DEFAULT_DIR_FD)
8122 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8123 else
8124#endif
8125 length = readlink(path->narrow, buffer, MAXPATHLEN);
8126 Py_END_ALLOW_THREADS
8127
8128 if (length < 0) {
8129 return path_error(path);
8130 }
8131 buffer[length] = '\0';
8132
8133 if (PyUnicode_Check(path->object))
8134 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8135 else
8136 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008137#elif defined(MS_WINDOWS)
8138 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008139 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008140 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008141 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8142 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008143 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008144
Larry Hastings2f936352014-08-05 14:04:04 +10008145 /* First get a handle to the reparse point */
8146 Py_BEGIN_ALLOW_THREADS
8147 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008148 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008149 0,
8150 0,
8151 0,
8152 OPEN_EXISTING,
8153 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8154 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008155 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8156 /* New call DeviceIoControl to read the reparse point */
8157 io_result = DeviceIoControl(
8158 reparse_point_handle,
8159 FSCTL_GET_REPARSE_POINT,
8160 0, 0, /* in buffer */
8161 target_buffer, sizeof(target_buffer),
8162 &n_bytes_returned,
8163 0 /* we're not using OVERLAPPED_IO */
8164 );
8165 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008166 }
Larry Hastings2f936352014-08-05 14:04:04 +10008167 Py_END_ALLOW_THREADS
8168
Berker Peksage0b5b202018-08-15 13:03:41 +03008169 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008170 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008171 }
Larry Hastings2f936352014-08-05 14:04:04 +10008172
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008173 wchar_t *name = NULL;
8174 Py_ssize_t nameLen = 0;
8175 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008176 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008177 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8178 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8179 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008180 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008181 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8182 {
8183 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8184 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8185 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8186 }
8187 else
8188 {
8189 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8190 }
8191 if (name) {
8192 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8193 /* Our buffer is mutable, so this is okay */
8194 name[1] = L'\\';
8195 }
8196 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008197 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008198 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8199 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008200 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008201 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008202#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008203}
Berker Peksage0b5b202018-08-15 13:03:41 +03008204#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008205
Larry Hastings9cf065c2012-06-22 16:30:09 -07008206#if defined(MS_WINDOWS)
8207
Steve Dower6921e732018-03-05 14:26:08 -08008208/* Remove the last portion of the path - return 0 on success */
8209static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008210_dirnameW(WCHAR *path)
8211{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008212 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008213 size_t length = wcsnlen_s(path, MAX_PATH);
8214 if (length == MAX_PATH) {
8215 return -1;
8216 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008217
8218 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008219 for(ptr = path + length; ptr != path; ptr--) {
8220 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008221 break;
Steve Dower6921e732018-03-05 14:26:08 -08008222 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008223 }
8224 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008225 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008226}
8227
Minmin Gong7f21c9a2020-05-18 09:17:19 -07008228#endif
8229
8230#ifdef HAVE_SYMLINK
8231
8232#if defined(MS_WINDOWS)
8233
Victor Stinner31b3b922013-06-05 01:49:17 +02008234/* Is this path absolute? */
8235static int
8236_is_absW(const WCHAR *path)
8237{
Steve Dower6921e732018-03-05 14:26:08 -08008238 return path[0] == L'\\' || path[0] == L'/' ||
8239 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008240}
8241
Steve Dower6921e732018-03-05 14:26:08 -08008242/* join root and rest with a backslash - return 0 on success */
8243static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008244_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8245{
Victor Stinner31b3b922013-06-05 01:49:17 +02008246 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008247 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008248 }
8249
Steve Dower6921e732018-03-05 14:26:08 -08008250 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8251 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008252 }
Steve Dower6921e732018-03-05 14:26:08 -08008253
8254 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8255 return -1;
8256 }
8257
8258 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008259}
8260
Victor Stinner31b3b922013-06-05 01:49:17 +02008261/* Return True if the path at src relative to dest is a directory */
8262static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008263_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008264{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008265 WIN32_FILE_ATTRIBUTE_DATA src_info;
8266 WCHAR dest_parent[MAX_PATH];
8267 WCHAR src_resolved[MAX_PATH] = L"";
8268
8269 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008270 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8271 _dirnameW(dest_parent)) {
8272 return 0;
8273 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008274 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008275 if (_joinW(src_resolved, dest_parent, src)) {
8276 return 0;
8277 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008278 return (
8279 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8280 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8281 );
8282}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008283#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008284
Larry Hastings2f936352014-08-05 14:04:04 +10008285
8286/*[clinic input]
8287os.symlink
8288 src: path_t
8289 dst: path_t
8290 target_is_directory: bool = False
8291 *
8292 dir_fd: dir_fd(requires='symlinkat')=None
8293
8294# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8295
8296Create a symbolic link pointing to src named dst.
8297
8298target_is_directory is required on Windows if the target is to be
8299 interpreted as a directory. (On Windows, symlink requires
8300 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8301 target_is_directory is ignored on non-Windows platforms.
8302
8303If dir_fd is not None, it should be a file descriptor open to a directory,
8304 and path should be relative; path will then be relative to that directory.
8305dir_fd may not be implemented on your platform.
8306 If it is unavailable, using it will raise a NotImplementedError.
8307
8308[clinic start generated code]*/
8309
Larry Hastings2f936352014-08-05 14:04:04 +10008310static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008311os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008312 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008313/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008314{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008315#ifdef MS_WINDOWS
8316 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008317 DWORD flags = 0;
8318
8319 /* Assumed true, set to false if detected to not be available. */
8320 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008321#else
8322 int result;
8323#endif
8324
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008325 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8326 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8327 return NULL;
8328 }
8329
Larry Hastings9cf065c2012-06-22 16:30:09 -07008330#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008331
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008332 if (windows_has_symlink_unprivileged_flag) {
8333 /* Allow non-admin symlinks if system allows it. */
8334 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8335 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008336
Larry Hastings9cf065c2012-06-22 16:30:09 -07008337 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008338 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008339 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8340 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8341 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8342 }
8343
8344 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008345 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008346 Py_END_ALLOW_THREADS
8347
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008348 if (windows_has_symlink_unprivileged_flag && !result &&
8349 ERROR_INVALID_PARAMETER == GetLastError()) {
8350
8351 Py_BEGIN_ALLOW_THREADS
8352 _Py_BEGIN_SUPPRESS_IPH
8353 /* This error might be caused by
8354 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8355 Try again, and update windows_has_symlink_unprivileged_flag if we
8356 are successful this time.
8357
8358 NOTE: There is a risk of a race condition here if there are other
8359 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8360 another process (or thread) changes that condition in between our
8361 calls to CreateSymbolicLink.
8362 */
8363 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8364 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8365 _Py_END_SUPPRESS_IPH
8366 Py_END_ALLOW_THREADS
8367
8368 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8369 windows_has_symlink_unprivileged_flag = FALSE;
8370 }
8371 }
8372
Larry Hastings2f936352014-08-05 14:04:04 +10008373 if (!result)
8374 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008375
8376#else
8377
Steve Dower6921e732018-03-05 14:26:08 -08008378 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8379 PyErr_SetString(PyExc_ValueError,
8380 "symlink: src and dst must be the same type");
8381 return NULL;
8382 }
8383
Larry Hastings9cf065c2012-06-22 16:30:09 -07008384 Py_BEGIN_ALLOW_THREADS
8385#if HAVE_SYMLINKAT
8386 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10008387 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008388 else
8389#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008390 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008391 Py_END_ALLOW_THREADS
8392
Larry Hastings2f936352014-08-05 14:04:04 +10008393 if (result)
8394 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008395#endif
8396
Larry Hastings2f936352014-08-05 14:04:04 +10008397 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008398}
8399#endif /* HAVE_SYMLINK */
8400
Larry Hastings9cf065c2012-06-22 16:30:09 -07008401
Brian Curtind40e6f72010-07-08 21:39:08 +00008402
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008403
Larry Hastings605a62d2012-06-24 04:33:36 -07008404static PyStructSequence_Field times_result_fields[] = {
8405 {"user", "user time"},
8406 {"system", "system time"},
8407 {"children_user", "user time of children"},
8408 {"children_system", "system time of children"},
8409 {"elapsed", "elapsed time since an arbitrary point in the past"},
8410 {NULL}
8411};
8412
8413PyDoc_STRVAR(times_result__doc__,
8414"times_result: Result from os.times().\n\n\
8415This object may be accessed either as a tuple of\n\
8416 (user, system, children_user, children_system, elapsed),\n\
8417or via the attributes user, system, children_user, children_system,\n\
8418and elapsed.\n\
8419\n\
8420See os.times for more information.");
8421
8422static PyStructSequence_Desc times_result_desc = {
8423 "times_result", /* name */
8424 times_result__doc__, /* doc */
8425 times_result_fields,
8426 5
8427};
8428
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008429#ifdef MS_WINDOWS
8430#define HAVE_TIMES /* mandatory, for the method table */
8431#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008432
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008433#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008434
8435static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008436build_times_result(PyObject *module, double user, double system,
Larry Hastings605a62d2012-06-24 04:33:36 -07008437 double children_user, double children_system,
8438 double elapsed)
8439{
Victor Stinner1c2fa782020-05-10 11:05:29 +02008440 PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008441 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008442 if (value == NULL)
8443 return NULL;
8444
8445#define SET(i, field) \
8446 { \
8447 PyObject *o = PyFloat_FromDouble(field); \
8448 if (!o) { \
8449 Py_DECREF(value); \
8450 return NULL; \
8451 } \
8452 PyStructSequence_SET_ITEM(value, i, o); \
8453 } \
8454
8455 SET(0, user);
8456 SET(1, system);
8457 SET(2, children_user);
8458 SET(3, children_system);
8459 SET(4, elapsed);
8460
8461#undef SET
8462
8463 return value;
8464}
8465
Larry Hastings605a62d2012-06-24 04:33:36 -07008466
Larry Hastings2f936352014-08-05 14:04:04 +10008467#ifndef MS_WINDOWS
8468#define NEED_TICKS_PER_SECOND
8469static long ticks_per_second = -1;
8470#endif /* MS_WINDOWS */
8471
8472/*[clinic input]
8473os.times
8474
8475Return a collection containing process timing information.
8476
8477The object returned behaves like a named tuple with these fields:
8478 (utime, stime, cutime, cstime, elapsed_time)
8479All fields are floating point numbers.
8480[clinic start generated code]*/
8481
Larry Hastings2f936352014-08-05 14:04:04 +10008482static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008483os_times_impl(PyObject *module)
8484/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008485#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008486{
Victor Stinner8c62be82010-05-06 00:08:46 +00008487 FILETIME create, exit, kernel, user;
8488 HANDLE hProc;
8489 hProc = GetCurrentProcess();
8490 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8491 /* The fields of a FILETIME structure are the hi and lo part
8492 of a 64-bit value expressed in 100 nanosecond units.
8493 1e7 is one second in such units; 1e-7 the inverse.
8494 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8495 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02008496 return build_times_result(module,
Victor Stinner8c62be82010-05-06 00:08:46 +00008497 (double)(user.dwHighDateTime*429.4967296 +
8498 user.dwLowDateTime*1e-7),
8499 (double)(kernel.dwHighDateTime*429.4967296 +
8500 kernel.dwLowDateTime*1e-7),
8501 (double)0,
8502 (double)0,
8503 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008504}
Larry Hastings2f936352014-08-05 14:04:04 +10008505#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008506{
Larry Hastings2f936352014-08-05 14:04:04 +10008507
8508
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008509 struct tms t;
8510 clock_t c;
8511 errno = 0;
8512 c = times(&t);
8513 if (c == (clock_t) -1)
8514 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02008515 return build_times_result(module,
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008516 (double)t.tms_utime / ticks_per_second,
8517 (double)t.tms_stime / ticks_per_second,
8518 (double)t.tms_cutime / ticks_per_second,
8519 (double)t.tms_cstime / ticks_per_second,
8520 (double)c / ticks_per_second);
8521}
Larry Hastings2f936352014-08-05 14:04:04 +10008522#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008523#endif /* HAVE_TIMES */
8524
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008525
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008526#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008527/*[clinic input]
8528os.getsid
8529
8530 pid: pid_t
8531 /
8532
8533Call the system call getsid(pid) and return the result.
8534[clinic start generated code]*/
8535
Larry Hastings2f936352014-08-05 14:04:04 +10008536static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008537os_getsid_impl(PyObject *module, pid_t pid)
8538/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008539{
Victor Stinner8c62be82010-05-06 00:08:46 +00008540 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008541 sid = getsid(pid);
8542 if (sid < 0)
8543 return posix_error();
8544 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008545}
8546#endif /* HAVE_GETSID */
8547
8548
Guido van Rossumb6775db1994-08-01 11:34:53 +00008549#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008550/*[clinic input]
8551os.setsid
8552
8553Call the system call setsid().
8554[clinic start generated code]*/
8555
Larry Hastings2f936352014-08-05 14:04:04 +10008556static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008557os_setsid_impl(PyObject *module)
8558/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008559{
Victor Stinner8c62be82010-05-06 00:08:46 +00008560 if (setsid() < 0)
8561 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008562 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008563}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008564#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008565
Larry Hastings2f936352014-08-05 14:04:04 +10008566
Guido van Rossumb6775db1994-08-01 11:34:53 +00008567#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008568/*[clinic input]
8569os.setpgid
8570
8571 pid: pid_t
8572 pgrp: pid_t
8573 /
8574
8575Call the system call setpgid(pid, pgrp).
8576[clinic start generated code]*/
8577
Larry Hastings2f936352014-08-05 14:04:04 +10008578static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008579os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8580/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008581{
Victor Stinner8c62be82010-05-06 00:08:46 +00008582 if (setpgid(pid, pgrp) < 0)
8583 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008584 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008585}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008586#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008587
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008588
Guido van Rossumb6775db1994-08-01 11:34:53 +00008589#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008590/*[clinic input]
8591os.tcgetpgrp
8592
8593 fd: int
8594 /
8595
8596Return the process group associated with the terminal specified by fd.
8597[clinic start generated code]*/
8598
Larry Hastings2f936352014-08-05 14:04:04 +10008599static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008600os_tcgetpgrp_impl(PyObject *module, int fd)
8601/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008602{
8603 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008604 if (pgid < 0)
8605 return posix_error();
8606 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008607}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008608#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008610
Guido van Rossumb6775db1994-08-01 11:34:53 +00008611#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008612/*[clinic input]
8613os.tcsetpgrp
8614
8615 fd: int
8616 pgid: pid_t
8617 /
8618
8619Set the process group associated with the terminal specified by fd.
8620[clinic start generated code]*/
8621
Larry Hastings2f936352014-08-05 14:04:04 +10008622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008623os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8624/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008625{
Victor Stinner8c62be82010-05-06 00:08:46 +00008626 if (tcsetpgrp(fd, pgid) < 0)
8627 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008628 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008629}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008630#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008631
Guido van Rossum687dd131993-05-17 08:34:16 +00008632/* Functions acting on file descriptors */
8633
Victor Stinnerdaf45552013-08-28 00:53:59 +02008634#ifdef O_CLOEXEC
8635extern int _Py_open_cloexec_works;
8636#endif
8637
Larry Hastings2f936352014-08-05 14:04:04 +10008638
8639/*[clinic input]
8640os.open -> int
8641 path: path_t
8642 flags: int
8643 mode: int = 0o777
8644 *
8645 dir_fd: dir_fd(requires='openat') = None
8646
8647# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8648
8649Open a file for low level IO. Returns a file descriptor (integer).
8650
8651If dir_fd is not None, it should be a file descriptor open to a directory,
8652 and path should be relative; path will then be relative to that directory.
8653dir_fd may not be implemented on your platform.
8654 If it is unavailable, using it will raise a NotImplementedError.
8655[clinic start generated code]*/
8656
Larry Hastings2f936352014-08-05 14:04:04 +10008657static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008658os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8659/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008660{
8661 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008662 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008663
Victor Stinnerdaf45552013-08-28 00:53:59 +02008664#ifdef O_CLOEXEC
8665 int *atomic_flag_works = &_Py_open_cloexec_works;
8666#elif !defined(MS_WINDOWS)
8667 int *atomic_flag_works = NULL;
8668#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008669
Victor Stinnerdaf45552013-08-28 00:53:59 +02008670#ifdef MS_WINDOWS
8671 flags |= O_NOINHERIT;
8672#elif defined(O_CLOEXEC)
8673 flags |= O_CLOEXEC;
8674#endif
8675
Steve Dowerb82e17e2019-05-23 08:45:22 -07008676 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
8677 return -1;
8678 }
8679
Steve Dower8fc89802015-04-12 00:26:27 -04008680 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008681 do {
8682 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008683#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008684 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008685#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008686#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008687 if (dir_fd != DEFAULT_DIR_FD)
8688 fd = openat(dir_fd, path->narrow, flags, mode);
8689 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008690#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008691 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008692#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008693 Py_END_ALLOW_THREADS
8694 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008695 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008696
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008697 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008698 if (!async_err)
8699 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008700 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008701 }
8702
Victor Stinnerdaf45552013-08-28 00:53:59 +02008703#ifndef MS_WINDOWS
8704 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8705 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008706 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008707 }
8708#endif
8709
Larry Hastings2f936352014-08-05 14:04:04 +10008710 return fd;
8711}
8712
8713
8714/*[clinic input]
8715os.close
8716
8717 fd: int
8718
8719Close a file descriptor.
8720[clinic start generated code]*/
8721
Barry Warsaw53699e91996-12-10 23:23:01 +00008722static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008723os_close_impl(PyObject *module, int fd)
8724/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008725{
Larry Hastings2f936352014-08-05 14:04:04 +10008726 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008727 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8728 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8729 * for more details.
8730 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008731 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008732 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008733 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008734 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008735 Py_END_ALLOW_THREADS
8736 if (res < 0)
8737 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008738 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008739}
8740
Larry Hastings2f936352014-08-05 14:04:04 +10008741/*[clinic input]
8742os.closerange
8743
8744 fd_low: int
8745 fd_high: int
8746 /
8747
8748Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8749[clinic start generated code]*/
8750
Larry Hastings2f936352014-08-05 14:04:04 +10008751static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008752os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8753/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008754{
Victor Stinner8c62be82010-05-06 00:08:46 +00008755 Py_BEGIN_ALLOW_THREADS
Kyle Evansc230fde2020-10-11 13:54:11 -05008756 _Py_closerange(fd_low, fd_high - 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00008757 Py_END_ALLOW_THREADS
8758 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008759}
8760
8761
Larry Hastings2f936352014-08-05 14:04:04 +10008762/*[clinic input]
8763os.dup -> int
8764
8765 fd: int
8766 /
8767
8768Return a duplicate of a file descriptor.
8769[clinic start generated code]*/
8770
Larry Hastings2f936352014-08-05 14:04:04 +10008771static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008772os_dup_impl(PyObject *module, int fd)
8773/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008774{
8775 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008776}
8777
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008778
Larry Hastings2f936352014-08-05 14:04:04 +10008779/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008780os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008781 fd: int
8782 fd2: int
8783 inheritable: bool=True
8784
8785Duplicate file descriptor.
8786[clinic start generated code]*/
8787
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008788static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008789os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008790/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008791{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008792 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008793#if defined(HAVE_DUP3) && \
8794 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8795 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008796 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008797#endif
8798
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008799 if (fd < 0 || fd2 < 0) {
8800 posix_error();
8801 return -1;
8802 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008803
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008804 /* dup2() can fail with EINTR if the target FD is already open, because it
8805 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8806 * upon close(), and therefore below.
8807 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008808#ifdef MS_WINDOWS
8809 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008810 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008811 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008812 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008813 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008814 if (res < 0) {
8815 posix_error();
8816 return -1;
8817 }
8818 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008819
8820 /* Character files like console cannot be make non-inheritable */
8821 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8822 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008823 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008824 }
8825
8826#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8827 Py_BEGIN_ALLOW_THREADS
8828 if (!inheritable)
8829 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8830 else
8831 res = dup2(fd, fd2);
8832 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008833 if (res < 0) {
8834 posix_error();
8835 return -1;
8836 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008837
8838#else
8839
8840#ifdef HAVE_DUP3
8841 if (!inheritable && dup3_works != 0) {
8842 Py_BEGIN_ALLOW_THREADS
8843 res = dup3(fd, fd2, O_CLOEXEC);
8844 Py_END_ALLOW_THREADS
8845 if (res < 0) {
8846 if (dup3_works == -1)
8847 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008848 if (dup3_works) {
8849 posix_error();
8850 return -1;
8851 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008852 }
8853 }
8854
8855 if (inheritable || dup3_works == 0)
8856 {
8857#endif
8858 Py_BEGIN_ALLOW_THREADS
8859 res = dup2(fd, fd2);
8860 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008861 if (res < 0) {
8862 posix_error();
8863 return -1;
8864 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008865
8866 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8867 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008868 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008869 }
8870#ifdef HAVE_DUP3
8871 }
8872#endif
8873
8874#endif
8875
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008876 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008877}
8878
Larry Hastings2f936352014-08-05 14:04:04 +10008879
Ross Lagerwall7807c352011-03-17 20:20:30 +02008880#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008881/*[clinic input]
8882os.lockf
8883
8884 fd: int
8885 An open file descriptor.
8886 command: int
8887 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8888 length: Py_off_t
8889 The number of bytes to lock, starting at the current position.
8890 /
8891
8892Apply, test or remove a POSIX lock on an open file descriptor.
8893
8894[clinic start generated code]*/
8895
Larry Hastings2f936352014-08-05 14:04:04 +10008896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008897os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8898/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008899{
8900 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008901
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008902 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
8903 return NULL;
8904 }
8905
Ross Lagerwall7807c352011-03-17 20:20:30 +02008906 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008907 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008908 Py_END_ALLOW_THREADS
8909
8910 if (res < 0)
8911 return posix_error();
8912
8913 Py_RETURN_NONE;
8914}
Larry Hastings2f936352014-08-05 14:04:04 +10008915#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008916
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008917
Larry Hastings2f936352014-08-05 14:04:04 +10008918/*[clinic input]
8919os.lseek -> Py_off_t
8920
8921 fd: int
8922 position: Py_off_t
8923 how: int
8924 /
8925
8926Set the position of a file descriptor. Return the new position.
8927
8928Return the new cursor position in number of bytes
8929relative to the beginning of the file.
8930[clinic start generated code]*/
8931
Larry Hastings2f936352014-08-05 14:04:04 +10008932static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008933os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8934/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008935{
8936 Py_off_t result;
8937
Guido van Rossum687dd131993-05-17 08:34:16 +00008938#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008939 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8940 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008941 case 0: how = SEEK_SET; break;
8942 case 1: how = SEEK_CUR; break;
8943 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008944 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008945#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008946
Victor Stinner8c62be82010-05-06 00:08:46 +00008947 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008948 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008949#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008950 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008951#else
Larry Hastings2f936352014-08-05 14:04:04 +10008952 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008953#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008954 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008955 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008956 if (result < 0)
8957 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008958
Larry Hastings2f936352014-08-05 14:04:04 +10008959 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008960}
8961
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008962
Larry Hastings2f936352014-08-05 14:04:04 +10008963/*[clinic input]
8964os.read
8965 fd: int
8966 length: Py_ssize_t
8967 /
8968
8969Read from a file descriptor. Returns a bytes object.
8970[clinic start generated code]*/
8971
Larry Hastings2f936352014-08-05 14:04:04 +10008972static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008973os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8974/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008975{
Victor Stinner8c62be82010-05-06 00:08:46 +00008976 Py_ssize_t n;
8977 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008978
8979 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008980 errno = EINVAL;
8981 return posix_error();
8982 }
Larry Hastings2f936352014-08-05 14:04:04 +10008983
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008984 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008985
8986 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008987 if (buffer == NULL)
8988 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008989
Victor Stinner66aab0c2015-03-19 22:53:20 +01008990 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8991 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008992 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008993 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008994 }
Larry Hastings2f936352014-08-05 14:04:04 +10008995
8996 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008997 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008998
Victor Stinner8c62be82010-05-06 00:08:46 +00008999 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00009000}
9001
Ross Lagerwall7807c352011-03-17 20:20:30 +02009002#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009003 || defined(__APPLE__))) \
9004 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
9005 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9006static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009007iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009008{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009009 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009010
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009011 *iov = PyMem_New(struct iovec, cnt);
9012 if (*iov == NULL) {
9013 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009014 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009015 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009016
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009017 *buf = PyMem_New(Py_buffer, cnt);
9018 if (*buf == NULL) {
9019 PyMem_Del(*iov);
9020 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009021 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009022 }
9023
9024 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009025 PyObject *item = PySequence_GetItem(seq, i);
9026 if (item == NULL)
9027 goto fail;
9028 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
9029 Py_DECREF(item);
9030 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009031 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009032 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009033 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009034 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009035 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009036 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009037
9038fail:
9039 PyMem_Del(*iov);
9040 for (j = 0; j < i; j++) {
9041 PyBuffer_Release(&(*buf)[j]);
9042 }
9043 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01009044 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009045}
9046
9047static void
9048iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9049{
9050 int i;
9051 PyMem_Del(iov);
9052 for (i = 0; i < cnt; i++) {
9053 PyBuffer_Release(&buf[i]);
9054 }
9055 PyMem_Del(buf);
9056}
9057#endif
9058
Larry Hastings2f936352014-08-05 14:04:04 +10009059
Ross Lagerwall7807c352011-03-17 20:20:30 +02009060#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10009061/*[clinic input]
9062os.readv -> Py_ssize_t
9063
9064 fd: int
9065 buffers: object
9066 /
9067
9068Read from a file descriptor fd into an iterable of buffers.
9069
9070The buffers should be mutable buffers accepting bytes.
9071readv will transfer data into each buffer until it is full
9072and then move on to the next buffer in the sequence to hold
9073the rest of the data.
9074
9075readv returns the total number of bytes read,
9076which may be less than the total capacity of all the buffers.
9077[clinic start generated code]*/
9078
Larry Hastings2f936352014-08-05 14:04:04 +10009079static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009080os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9081/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009082{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009083 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009084 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009085 struct iovec *iov;
9086 Py_buffer *buf;
9087
Larry Hastings2f936352014-08-05 14:04:04 +10009088 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009089 PyErr_SetString(PyExc_TypeError,
9090 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009091 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009092 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009093
Larry Hastings2f936352014-08-05 14:04:04 +10009094 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009095 if (cnt < 0)
9096 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009097
9098 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9099 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009100
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009101 do {
9102 Py_BEGIN_ALLOW_THREADS
9103 n = readv(fd, iov, cnt);
9104 Py_END_ALLOW_THREADS
9105 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009106
9107 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009108 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009109 if (!async_err)
9110 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009111 return -1;
9112 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009113
Larry Hastings2f936352014-08-05 14:04:04 +10009114 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009115}
Larry Hastings2f936352014-08-05 14:04:04 +10009116#endif /* HAVE_READV */
9117
Ross Lagerwall7807c352011-03-17 20:20:30 +02009118
9119#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009120/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009121os.pread
9122
9123 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009124 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009125 offset: Py_off_t
9126 /
9127
9128Read a number of bytes from a file descriptor starting at a particular offset.
9129
9130Read length bytes from file descriptor fd, starting at offset bytes from
9131the beginning of the file. The file offset remains unchanged.
9132[clinic start generated code]*/
9133
Larry Hastings2f936352014-08-05 14:04:04 +10009134static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009135os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9136/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009137{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009138 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009139 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009140 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009141
Larry Hastings2f936352014-08-05 14:04:04 +10009142 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009143 errno = EINVAL;
9144 return posix_error();
9145 }
Larry Hastings2f936352014-08-05 14:04:04 +10009146 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009147 if (buffer == NULL)
9148 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009149
9150 do {
9151 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009152 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009153 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009154 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009155 Py_END_ALLOW_THREADS
9156 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9157
Ross Lagerwall7807c352011-03-17 20:20:30 +02009158 if (n < 0) {
9159 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009160 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009161 }
Larry Hastings2f936352014-08-05 14:04:04 +10009162 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009163 _PyBytes_Resize(&buffer, n);
9164 return buffer;
9165}
Larry Hastings2f936352014-08-05 14:04:04 +10009166#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009167
Pablo Galindo4defba32018-01-27 16:16:37 +00009168#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9169/*[clinic input]
9170os.preadv -> Py_ssize_t
9171
9172 fd: int
9173 buffers: object
9174 offset: Py_off_t
9175 flags: int = 0
9176 /
9177
9178Reads from a file descriptor into a number of mutable bytes-like objects.
9179
9180Combines the functionality of readv() and pread(). As readv(), it will
9181transfer data into each buffer until it is full and then move on to the next
9182buffer in the sequence to hold the rest of the data. Its fourth argument,
9183specifies the file offset at which the input operation is to be performed. It
9184will return the total number of bytes read (which can be less than the total
9185capacity of all the objects).
9186
9187The flags argument contains a bitwise OR of zero or more of the following flags:
9188
9189- RWF_HIPRI
9190- RWF_NOWAIT
9191
9192Using non-zero flags requires Linux 4.6 or newer.
9193[clinic start generated code]*/
9194
9195static Py_ssize_t
9196os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9197 int flags)
9198/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9199{
9200 Py_ssize_t cnt, n;
9201 int async_err = 0;
9202 struct iovec *iov;
9203 Py_buffer *buf;
9204
9205 if (!PySequence_Check(buffers)) {
9206 PyErr_SetString(PyExc_TypeError,
9207 "preadv2() arg 2 must be a sequence");
9208 return -1;
9209 }
9210
9211 cnt = PySequence_Size(buffers);
9212 if (cnt < 0) {
9213 return -1;
9214 }
9215
9216#ifndef HAVE_PREADV2
9217 if(flags != 0) {
9218 argument_unavailable_error("preadv2", "flags");
9219 return -1;
9220 }
9221#endif
9222
9223 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9224 return -1;
9225 }
9226#ifdef HAVE_PREADV2
9227 do {
9228 Py_BEGIN_ALLOW_THREADS
9229 _Py_BEGIN_SUPPRESS_IPH
9230 n = preadv2(fd, iov, cnt, offset, flags);
9231 _Py_END_SUPPRESS_IPH
9232 Py_END_ALLOW_THREADS
9233 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9234#else
9235 do {
9236 Py_BEGIN_ALLOW_THREADS
9237 _Py_BEGIN_SUPPRESS_IPH
9238 n = preadv(fd, iov, cnt, offset);
9239 _Py_END_SUPPRESS_IPH
9240 Py_END_ALLOW_THREADS
9241 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9242#endif
9243
9244 iov_cleanup(iov, buf, cnt);
9245 if (n < 0) {
9246 if (!async_err) {
9247 posix_error();
9248 }
9249 return -1;
9250 }
9251
9252 return n;
9253}
9254#endif /* HAVE_PREADV */
9255
Larry Hastings2f936352014-08-05 14:04:04 +10009256
9257/*[clinic input]
9258os.write -> Py_ssize_t
9259
9260 fd: int
9261 data: Py_buffer
9262 /
9263
9264Write a bytes object to a file descriptor.
9265[clinic start generated code]*/
9266
Larry Hastings2f936352014-08-05 14:04:04 +10009267static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009268os_write_impl(PyObject *module, int fd, Py_buffer *data)
9269/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009270{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009271 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009272}
9273
9274#ifdef HAVE_SENDFILE
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009275#ifdef __APPLE__
9276/*[clinic input]
9277os.sendfile
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009278
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009279 out_fd: int
9280 in_fd: int
9281 offset: Py_off_t
9282 count as sbytes: Py_off_t
9283 headers: object(c_default="NULL") = ()
9284 trailers: object(c_default="NULL") = ()
9285 flags: int = 0
9286
9287Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9288[clinic start generated code]*/
9289
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009290static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009291os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9292 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9293 int flags)
9294/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9295#elif defined(__FreeBSD__) || defined(__DragonFly__)
9296/*[clinic input]
9297os.sendfile
9298
9299 out_fd: int
9300 in_fd: int
9301 offset: Py_off_t
9302 count: Py_ssize_t
9303 headers: object(c_default="NULL") = ()
9304 trailers: object(c_default="NULL") = ()
9305 flags: int = 0
9306
9307Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9308[clinic start generated code]*/
9309
9310static PyObject *
9311os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9312 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9313 int flags)
9314/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9315#else
9316/*[clinic input]
9317os.sendfile
9318
9319 out_fd: int
9320 in_fd: int
9321 offset as offobj: object
9322 count: Py_ssize_t
9323
9324Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9325[clinic start generated code]*/
9326
9327static PyObject *
9328os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9329 Py_ssize_t count)
9330/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9331#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009332{
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009333 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009334 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009335
9336#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9337#ifndef __APPLE__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009338 off_t sbytes;
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009339#endif
9340 Py_buffer *hbuf, *tbuf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009341 struct sf_hdtr sf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009342
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009343 sf.headers = NULL;
9344 sf.trailers = NULL;
9345
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009346 if (headers != NULL) {
9347 if (!PySequence_Check(headers)) {
9348 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009349 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009350 return NULL;
9351 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009352 Py_ssize_t i = PySequence_Size(headers);
9353 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009354 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009355 if (i > INT_MAX) {
9356 PyErr_SetString(PyExc_OverflowError,
9357 "sendfile() header is too large");
9358 return NULL;
9359 }
9360 if (i > 0) {
9361 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009362 if (iov_setup(&(sf.headers), &hbuf,
9363 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009364 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009365#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009366 for (i = 0; i < sf.hdr_cnt; i++) {
9367 Py_ssize_t blen = sf.headers[i].iov_len;
9368# define OFF_T_MAX 0x7fffffffffffffff
9369 if (sbytes >= OFF_T_MAX - blen) {
9370 PyErr_SetString(PyExc_OverflowError,
9371 "sendfile() header is too large");
9372 return NULL;
9373 }
9374 sbytes += blen;
9375 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009376#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009377 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009378 }
9379 }
9380 if (trailers != NULL) {
9381 if (!PySequence_Check(trailers)) {
9382 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009383 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009384 return NULL;
9385 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009386 Py_ssize_t i = PySequence_Size(trailers);
9387 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009388 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009389 if (i > INT_MAX) {
9390 PyErr_SetString(PyExc_OverflowError,
9391 "sendfile() trailer is too large");
9392 return NULL;
9393 }
9394 if (i > 0) {
9395 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009396 if (iov_setup(&(sf.trailers), &tbuf,
9397 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009398 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009399 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009400 }
9401 }
9402
Steve Dower8fc89802015-04-12 00:26:27 -04009403 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009404 do {
9405 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009406#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009407 ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009408#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009409 ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009410#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009411 Py_END_ALLOW_THREADS
9412 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009413 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009414
9415 if (sf.headers != NULL)
9416 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9417 if (sf.trailers != NULL)
9418 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9419
9420 if (ret < 0) {
9421 if ((errno == EAGAIN) || (errno == EBUSY)) {
9422 if (sbytes != 0) {
9423 // some data has been sent
9424 goto done;
9425 }
9426 else {
9427 // no data has been sent; upper application is supposed
9428 // to retry on EAGAIN or EBUSY
9429 return posix_error();
9430 }
9431 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009432 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009433 }
9434 goto done;
9435
9436done:
9437 #if !defined(HAVE_LARGEFILE_SUPPORT)
9438 return Py_BuildValue("l", sbytes);
9439 #else
9440 return Py_BuildValue("L", sbytes);
9441 #endif
9442
9443#else
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009444#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009445 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009446 do {
9447 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009448 ret = sendfile(out_fd, in_fd, NULL, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009449 Py_END_ALLOW_THREADS
9450 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009451 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009452 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009453 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009454 }
9455#endif
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009456 off_t offset;
Larry Hastings2f936352014-08-05 14:04:04 +10009457 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009458 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009459
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009460#if defined(__sun) && defined(__SVR4)
9461 // On Solaris, sendfile raises EINVAL rather than returning 0
9462 // when the offset is equal or bigger than the in_fd size.
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009463 struct stat st;
9464
9465 do {
9466 Py_BEGIN_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009467 ret = fstat(in_fd, &st);
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009468 Py_END_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009469 } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009470 if (ret < 0)
9471 return (!async_err) ? posix_error() : NULL;
9472
9473 if (offset >= st.st_size) {
9474 return Py_BuildValue("i", 0);
9475 }
9476#endif
9477
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009478 do {
9479 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009480 ret = sendfile(out_fd, in_fd, &offset, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009481 Py_END_ALLOW_THREADS
9482 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009483 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009484 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009485 return Py_BuildValue("n", ret);
9486#endif
9487}
Larry Hastings2f936352014-08-05 14:04:04 +10009488#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009489
Larry Hastings2f936352014-08-05 14:04:04 +10009490
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009491#if defined(__APPLE__)
9492/*[clinic input]
9493os._fcopyfile
9494
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009495 in_fd: int
9496 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009497 flags: int
9498 /
9499
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009500Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009501[clinic start generated code]*/
9502
9503static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009504os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9505/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009506{
9507 int ret;
9508
9509 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009510 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009511 Py_END_ALLOW_THREADS
9512 if (ret < 0)
9513 return posix_error();
9514 Py_RETURN_NONE;
9515}
9516#endif
9517
9518
Larry Hastings2f936352014-08-05 14:04:04 +10009519/*[clinic input]
9520os.fstat
9521
9522 fd : int
9523
9524Perform a stat system call on the given file descriptor.
9525
9526Like stat(), but for an open file descriptor.
9527Equivalent to os.stat(fd).
9528[clinic start generated code]*/
9529
Larry Hastings2f936352014-08-05 14:04:04 +10009530static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009531os_fstat_impl(PyObject *module, int fd)
9532/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009533{
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 STRUCT_STAT st;
9535 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009536 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009537
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009538 do {
9539 Py_BEGIN_ALLOW_THREADS
9540 res = FSTAT(fd, &st);
9541 Py_END_ALLOW_THREADS
9542 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009544#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009545 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009546#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009547 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009548#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 }
Tim Peters5aa91602002-01-30 05:46:57 +00009550
Victor Stinner1c2fa782020-05-10 11:05:29 +02009551 return _pystat_fromstructstat(module, &st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009552}
9553
Larry Hastings2f936352014-08-05 14:04:04 +10009554
9555/*[clinic input]
9556os.isatty -> bool
9557 fd: int
9558 /
9559
9560Return True if the fd is connected to a terminal.
9561
9562Return True if the file descriptor is an open file descriptor
9563connected to the slave end of a terminal.
9564[clinic start generated code]*/
9565
Larry Hastings2f936352014-08-05 14:04:04 +10009566static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009567os_isatty_impl(PyObject *module, int fd)
9568/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009569{
Steve Dower8fc89802015-04-12 00:26:27 -04009570 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009571 _Py_BEGIN_SUPPRESS_IPH
9572 return_value = isatty(fd);
9573 _Py_END_SUPPRESS_IPH
9574 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009575}
9576
9577
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009578#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009579/*[clinic input]
9580os.pipe
9581
9582Create a pipe.
9583
9584Returns a tuple of two file descriptors:
9585 (read_fd, write_fd)
9586[clinic start generated code]*/
9587
Larry Hastings2f936352014-08-05 14:04:04 +10009588static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009589os_pipe_impl(PyObject *module)
9590/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009591{
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009593#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009595 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009597#else
9598 int res;
9599#endif
9600
9601#ifdef MS_WINDOWS
9602 attr.nLength = sizeof(attr);
9603 attr.lpSecurityDescriptor = NULL;
9604 attr.bInheritHandle = FALSE;
9605
9606 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009607 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009608 ok = CreatePipe(&read, &write, &attr, 0);
9609 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009610 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9611 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009612 if (fds[0] == -1 || fds[1] == -1) {
9613 CloseHandle(read);
9614 CloseHandle(write);
9615 ok = 0;
9616 }
9617 }
Steve Dowerc3630612016-11-19 18:41:16 -08009618 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009619 Py_END_ALLOW_THREADS
9620
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009622 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009623#else
9624
9625#ifdef HAVE_PIPE2
9626 Py_BEGIN_ALLOW_THREADS
9627 res = pipe2(fds, O_CLOEXEC);
9628 Py_END_ALLOW_THREADS
9629
9630 if (res != 0 && errno == ENOSYS)
9631 {
9632#endif
9633 Py_BEGIN_ALLOW_THREADS
9634 res = pipe(fds);
9635 Py_END_ALLOW_THREADS
9636
9637 if (res == 0) {
9638 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9639 close(fds[0]);
9640 close(fds[1]);
9641 return NULL;
9642 }
9643 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9644 close(fds[0]);
9645 close(fds[1]);
9646 return NULL;
9647 }
9648 }
9649#ifdef HAVE_PIPE2
9650 }
9651#endif
9652
9653 if (res != 0)
9654 return PyErr_SetFromErrno(PyExc_OSError);
9655#endif /* !MS_WINDOWS */
9656 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009657}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009658#endif /* HAVE_PIPE */
9659
Larry Hastings2f936352014-08-05 14:04:04 +10009660
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009661#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009662/*[clinic input]
9663os.pipe2
9664
9665 flags: int
9666 /
9667
9668Create a pipe with flags set atomically.
9669
9670Returns a tuple of two file descriptors:
9671 (read_fd, write_fd)
9672
9673flags can be constructed by ORing together one or more of these values:
9674O_NONBLOCK, O_CLOEXEC.
9675[clinic start generated code]*/
9676
Larry Hastings2f936352014-08-05 14:04:04 +10009677static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009678os_pipe2_impl(PyObject *module, int flags)
9679/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009680{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009681 int fds[2];
9682 int res;
9683
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009684 res = pipe2(fds, flags);
9685 if (res != 0)
9686 return posix_error();
9687 return Py_BuildValue("(ii)", fds[0], fds[1]);
9688}
9689#endif /* HAVE_PIPE2 */
9690
Larry Hastings2f936352014-08-05 14:04:04 +10009691
Ross Lagerwall7807c352011-03-17 20:20:30 +02009692#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009693/*[clinic input]
9694os.writev -> Py_ssize_t
9695 fd: int
9696 buffers: object
9697 /
9698
9699Iterate over buffers, and write the contents of each to a file descriptor.
9700
9701Returns the total number of bytes written.
9702buffers must be a sequence of bytes-like objects.
9703[clinic start generated code]*/
9704
Larry Hastings2f936352014-08-05 14:04:04 +10009705static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009706os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9707/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009708{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009709 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009710 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009711 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009712 struct iovec *iov;
9713 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009714
9715 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009716 PyErr_SetString(PyExc_TypeError,
9717 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009718 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009719 }
Larry Hastings2f936352014-08-05 14:04:04 +10009720 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009721 if (cnt < 0)
9722 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009723
Larry Hastings2f936352014-08-05 14:04:04 +10009724 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9725 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009726 }
9727
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009728 do {
9729 Py_BEGIN_ALLOW_THREADS
9730 result = writev(fd, iov, cnt);
9731 Py_END_ALLOW_THREADS
9732 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009733
9734 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009735 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009736 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009737
Georg Brandl306336b2012-06-24 12:55:33 +02009738 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009739}
Larry Hastings2f936352014-08-05 14:04:04 +10009740#endif /* HAVE_WRITEV */
9741
9742
9743#ifdef HAVE_PWRITE
9744/*[clinic input]
9745os.pwrite -> Py_ssize_t
9746
9747 fd: int
9748 buffer: Py_buffer
9749 offset: Py_off_t
9750 /
9751
9752Write bytes to a file descriptor starting at a particular offset.
9753
9754Write buffer to fd, starting at offset bytes from the beginning of
9755the file. Returns the number of bytes writte. Does not change the
9756current file offset.
9757[clinic start generated code]*/
9758
Larry Hastings2f936352014-08-05 14:04:04 +10009759static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009760os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9761/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009762{
9763 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009764 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009765
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009766 do {
9767 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009768 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009769 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009770 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009771 Py_END_ALLOW_THREADS
9772 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009773
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009774 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009775 posix_error();
9776 return size;
9777}
9778#endif /* HAVE_PWRITE */
9779
Pablo Galindo4defba32018-01-27 16:16:37 +00009780#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9781/*[clinic input]
9782os.pwritev -> Py_ssize_t
9783
9784 fd: int
9785 buffers: object
9786 offset: Py_off_t
9787 flags: int = 0
9788 /
9789
9790Writes the contents of bytes-like objects to a file descriptor at a given offset.
9791
9792Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9793of bytes-like objects. Buffers are processed in array order. Entire contents of first
9794buffer is written before proceeding to second, and so on. The operating system may
9795set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9796This function writes the contents of each object to the file descriptor and returns
9797the total number of bytes written.
9798
9799The flags argument contains a bitwise OR of zero or more of the following flags:
9800
9801- RWF_DSYNC
9802- RWF_SYNC
YoSTEALTH76ef2552020-05-27 15:32:22 -06009803- RWF_APPEND
Pablo Galindo4defba32018-01-27 16:16:37 +00009804
9805Using non-zero flags requires Linux 4.7 or newer.
9806[clinic start generated code]*/
9807
9808static Py_ssize_t
9809os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9810 int flags)
YoSTEALTH76ef2552020-05-27 15:32:22 -06009811/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=35358c327e1a2a8e]*/
Pablo Galindo4defba32018-01-27 16:16:37 +00009812{
9813 Py_ssize_t cnt;
9814 Py_ssize_t result;
9815 int async_err = 0;
9816 struct iovec *iov;
9817 Py_buffer *buf;
9818
9819 if (!PySequence_Check(buffers)) {
9820 PyErr_SetString(PyExc_TypeError,
9821 "pwritev() arg 2 must be a sequence");
9822 return -1;
9823 }
9824
9825 cnt = PySequence_Size(buffers);
9826 if (cnt < 0) {
9827 return -1;
9828 }
9829
9830#ifndef HAVE_PWRITEV2
9831 if(flags != 0) {
9832 argument_unavailable_error("pwritev2", "flags");
9833 return -1;
9834 }
9835#endif
9836
9837 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9838 return -1;
9839 }
9840#ifdef HAVE_PWRITEV2
9841 do {
9842 Py_BEGIN_ALLOW_THREADS
9843 _Py_BEGIN_SUPPRESS_IPH
9844 result = pwritev2(fd, iov, cnt, offset, flags);
9845 _Py_END_SUPPRESS_IPH
9846 Py_END_ALLOW_THREADS
9847 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9848#else
9849 do {
9850 Py_BEGIN_ALLOW_THREADS
9851 _Py_BEGIN_SUPPRESS_IPH
9852 result = pwritev(fd, iov, cnt, offset);
9853 _Py_END_SUPPRESS_IPH
9854 Py_END_ALLOW_THREADS
9855 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9856#endif
9857
9858 iov_cleanup(iov, buf, cnt);
9859 if (result < 0) {
9860 if (!async_err) {
9861 posix_error();
9862 }
9863 return -1;
9864 }
9865
9866 return result;
9867}
9868#endif /* HAVE_PWRITEV */
9869
Pablo Galindoaac4d032019-05-31 19:39:47 +01009870#ifdef HAVE_COPY_FILE_RANGE
9871/*[clinic input]
9872
9873os.copy_file_range
9874 src: int
9875 Source file descriptor.
9876 dst: int
9877 Destination file descriptor.
9878 count: Py_ssize_t
9879 Number of bytes to copy.
9880 offset_src: object = None
9881 Starting offset in src.
9882 offset_dst: object = None
9883 Starting offset in dst.
9884
9885Copy count bytes from one file descriptor to another.
9886
9887If offset_src is None, then src is read from the current position;
9888respectively for offset_dst.
9889[clinic start generated code]*/
9890
9891static PyObject *
9892os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
9893 PyObject *offset_src, PyObject *offset_dst)
9894/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
9895{
9896 off_t offset_src_val, offset_dst_val;
9897 off_t *p_offset_src = NULL;
9898 off_t *p_offset_dst = NULL;
9899 Py_ssize_t ret;
9900 int async_err = 0;
9901 /* The flags argument is provided to allow
9902 * for future extensions and currently must be to 0. */
9903 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +00009904
9905
Pablo Galindoaac4d032019-05-31 19:39:47 +01009906 if (count < 0) {
9907 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
9908 return NULL;
9909 }
9910
9911 if (offset_src != Py_None) {
9912 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
9913 return NULL;
9914 }
9915 p_offset_src = &offset_src_val;
9916 }
9917
9918 if (offset_dst != Py_None) {
9919 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
9920 return NULL;
9921 }
9922 p_offset_dst = &offset_dst_val;
9923 }
9924
9925 do {
9926 Py_BEGIN_ALLOW_THREADS
9927 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
9928 Py_END_ALLOW_THREADS
9929 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9930
9931 if (ret < 0) {
9932 return (!async_err) ? posix_error() : NULL;
9933 }
9934
9935 return PyLong_FromSsize_t(ret);
9936}
9937#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +10009938
9939#ifdef HAVE_MKFIFO
9940/*[clinic input]
9941os.mkfifo
9942
9943 path: path_t
9944 mode: int=0o666
9945 *
9946 dir_fd: dir_fd(requires='mkfifoat')=None
9947
9948Create a "fifo" (a POSIX named pipe).
9949
9950If dir_fd is not None, it should be a file descriptor open to a directory,
9951 and path should be relative; path will then be relative to that directory.
9952dir_fd may not be implemented on your platform.
9953 If it is unavailable, using it will raise a NotImplementedError.
9954[clinic start generated code]*/
9955
Larry Hastings2f936352014-08-05 14:04:04 +10009956static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009957os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9958/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009959{
9960 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009961 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009962
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009963 do {
9964 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009965#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009966 if (dir_fd != DEFAULT_DIR_FD)
9967 result = mkfifoat(dir_fd, path->narrow, mode);
9968 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009969#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009970 result = mkfifo(path->narrow, mode);
9971 Py_END_ALLOW_THREADS
9972 } while (result != 0 && errno == EINTR &&
9973 !(async_err = PyErr_CheckSignals()));
9974 if (result != 0)
9975 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009976
9977 Py_RETURN_NONE;
9978}
9979#endif /* HAVE_MKFIFO */
9980
9981
9982#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9983/*[clinic input]
9984os.mknod
9985
9986 path: path_t
9987 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009988 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009989 *
9990 dir_fd: dir_fd(requires='mknodat')=None
9991
9992Create a node in the file system.
9993
9994Create a node in the file system (file, device special file or named pipe)
9995at path. mode specifies both the permissions to use and the
9996type of node to be created, being combined (bitwise OR) with one of
9997S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9998device defines the newly created device special file (probably using
9999os.makedev()). Otherwise device is ignored.
10000
10001If dir_fd is not None, it should be a file descriptor open to a directory,
10002 and path should be relative; path will then be relative to that directory.
10003dir_fd may not be implemented on your platform.
10004 If it is unavailable, using it will raise a NotImplementedError.
10005[clinic start generated code]*/
10006
Larry Hastings2f936352014-08-05 14:04:04 +100010007static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010008os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -040010009 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010010/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010011{
10012 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010013 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010014
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010015 do {
10016 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010017#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010018 if (dir_fd != DEFAULT_DIR_FD)
10019 result = mknodat(dir_fd, path->narrow, mode, device);
10020 else
Larry Hastings2f936352014-08-05 14:04:04 +100010021#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010022 result = mknod(path->narrow, mode, device);
10023 Py_END_ALLOW_THREADS
10024 } while (result != 0 && errno == EINTR &&
10025 !(async_err = PyErr_CheckSignals()));
10026 if (result != 0)
10027 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010028
10029 Py_RETURN_NONE;
10030}
10031#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10032
10033
10034#ifdef HAVE_DEVICE_MACROS
10035/*[clinic input]
10036os.major -> unsigned_int
10037
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010038 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010039 /
10040
10041Extracts a device major number from a raw device number.
10042[clinic start generated code]*/
10043
Larry Hastings2f936352014-08-05 14:04:04 +100010044static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010045os_major_impl(PyObject *module, dev_t device)
10046/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010047{
10048 return major(device);
10049}
10050
10051
10052/*[clinic input]
10053os.minor -> unsigned_int
10054
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010055 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010056 /
10057
10058Extracts a device minor number from a raw device number.
10059[clinic start generated code]*/
10060
Larry Hastings2f936352014-08-05 14:04:04 +100010061static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010062os_minor_impl(PyObject *module, dev_t device)
10063/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010064{
10065 return minor(device);
10066}
10067
10068
10069/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010070os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010071
10072 major: int
10073 minor: int
10074 /
10075
10076Composes a raw device number from the major and minor device numbers.
10077[clinic start generated code]*/
10078
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010079static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010080os_makedev_impl(PyObject *module, int major, int minor)
10081/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010082{
10083 return makedev(major, minor);
10084}
10085#endif /* HAVE_DEVICE_MACROS */
10086
10087
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010088#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010089/*[clinic input]
10090os.ftruncate
10091
10092 fd: int
10093 length: Py_off_t
10094 /
10095
10096Truncate a file, specified by file descriptor, to a specific length.
10097[clinic start generated code]*/
10098
Larry Hastings2f936352014-08-05 14:04:04 +100010099static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010100os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10101/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010102{
10103 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010104 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010105
Steve Dowerb82e17e2019-05-23 08:45:22 -070010106 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
10107 return NULL;
10108 }
10109
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010110 do {
10111 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010112 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010113#ifdef MS_WINDOWS
10114 result = _chsize_s(fd, length);
10115#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010116 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010117#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010118 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010119 Py_END_ALLOW_THREADS
10120 } while (result != 0 && errno == EINTR &&
10121 !(async_err = PyErr_CheckSignals()));
10122 if (result != 0)
10123 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010124 Py_RETURN_NONE;
10125}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010126#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010127
10128
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010129#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010130/*[clinic input]
10131os.truncate
10132 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10133 length: Py_off_t
10134
10135Truncate a file, specified by path, to a specific length.
10136
10137On some platforms, path may also be specified as an open file descriptor.
10138 If this functionality is unavailable, using it raises an exception.
10139[clinic start generated code]*/
10140
Larry Hastings2f936352014-08-05 14:04:04 +100010141static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010142os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10143/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010144{
10145 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010146#ifdef MS_WINDOWS
10147 int fd;
10148#endif
10149
10150 if (path->fd != -1)
10151 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010152
Steve Dowerb82e17e2019-05-23 08:45:22 -070010153 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10154 return NULL;
10155 }
10156
Larry Hastings2f936352014-08-05 14:04:04 +100010157 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010158 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010159#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010160 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010161 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010162 result = -1;
10163 else {
10164 result = _chsize_s(fd, length);
10165 close(fd);
10166 if (result < 0)
10167 errno = result;
10168 }
10169#else
10170 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010171#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010172 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010173 Py_END_ALLOW_THREADS
10174 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010175 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010176
10177 Py_RETURN_NONE;
10178}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010179#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010180
Ross Lagerwall7807c352011-03-17 20:20:30 +020010181
Victor Stinnerd6b17692014-09-30 12:20:05 +020010182/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10183 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10184 defined, which is the case in Python on AIX. AIX bug report:
10185 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10186#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10187# define POSIX_FADVISE_AIX_BUG
10188#endif
10189
Victor Stinnerec39e262014-09-30 12:35:58 +020010190
Victor Stinnerd6b17692014-09-30 12:20:05 +020010191#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010192/*[clinic input]
10193os.posix_fallocate
10194
10195 fd: int
10196 offset: Py_off_t
10197 length: Py_off_t
10198 /
10199
10200Ensure a file has allocated at least a particular number of bytes on disk.
10201
10202Ensure that the file specified by fd encompasses a range of bytes
10203starting at offset bytes from the beginning and continuing for length bytes.
10204[clinic start generated code]*/
10205
Larry Hastings2f936352014-08-05 14:04:04 +100010206static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010207os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010208 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010209/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010210{
10211 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010212 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010213
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010214 do {
10215 Py_BEGIN_ALLOW_THREADS
10216 result = posix_fallocate(fd, offset, length);
10217 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010218 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10219
10220 if (result == 0)
10221 Py_RETURN_NONE;
10222
10223 if (async_err)
10224 return NULL;
10225
10226 errno = result;
10227 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010228}
Victor Stinnerec39e262014-09-30 12:35:58 +020010229#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010230
Ross Lagerwall7807c352011-03-17 20:20:30 +020010231
Victor Stinnerd6b17692014-09-30 12:20:05 +020010232#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010233/*[clinic input]
10234os.posix_fadvise
10235
10236 fd: int
10237 offset: Py_off_t
10238 length: Py_off_t
10239 advice: int
10240 /
10241
10242Announce an intention to access data in a specific pattern.
10243
10244Announce an intention to access data in a specific pattern, thus allowing
10245the kernel to make optimizations.
10246The advice applies to the region of the file specified by fd starting at
10247offset and continuing for length bytes.
10248advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10249POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10250POSIX_FADV_DONTNEED.
10251[clinic start generated code]*/
10252
Larry Hastings2f936352014-08-05 14:04:04 +100010253static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010254os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010255 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010256/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010257{
10258 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010259 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010260
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010261 do {
10262 Py_BEGIN_ALLOW_THREADS
10263 result = posix_fadvise(fd, offset, length, advice);
10264 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010265 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10266
10267 if (result == 0)
10268 Py_RETURN_NONE;
10269
10270 if (async_err)
10271 return NULL;
10272
10273 errno = result;
10274 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010275}
Victor Stinnerec39e262014-09-30 12:35:58 +020010276#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010277
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010278
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010279#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010280static PyObject*
10281win32_putenv(PyObject *name, PyObject *value)
10282{
10283 /* Search from index 1 because on Windows starting '=' is allowed for
10284 defining hidden environment variables. */
10285 if (PyUnicode_GET_LENGTH(name) == 0 ||
10286 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10287 {
10288 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10289 return NULL;
10290 }
10291 PyObject *unicode;
10292 if (value != NULL) {
10293 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10294 }
10295 else {
10296 unicode = PyUnicode_FromFormat("%U=", name);
10297 }
10298 if (unicode == NULL) {
10299 return NULL;
10300 }
10301
10302 Py_ssize_t size;
10303 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10304 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10305 Py_DECREF(unicode);
10306
10307 if (env == NULL) {
10308 return NULL;
10309 }
10310 if (size > _MAX_ENV) {
10311 PyErr_Format(PyExc_ValueError,
10312 "the environment variable is longer than %u characters",
10313 _MAX_ENV);
10314 PyMem_Free(env);
10315 return NULL;
10316 }
10317
10318 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10319 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10320 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10321
10322 Prefer _wputenv() to be compatible with C libraries using CRT
10323 variables and CRT functions using these variables (ex: getenv()). */
10324 int err = _wputenv(env);
10325 PyMem_Free(env);
10326
10327 if (err) {
10328 posix_error();
10329 return NULL;
10330 }
10331
10332 Py_RETURN_NONE;
10333}
10334#endif
10335
10336
10337#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010338/*[clinic input]
10339os.putenv
10340
10341 name: unicode
10342 value: unicode
10343 /
10344
10345Change or add an environment variable.
10346[clinic start generated code]*/
10347
Larry Hastings2f936352014-08-05 14:04:04 +100010348static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010349os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10350/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010351{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010352 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10353 return NULL;
10354 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010355 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010356}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010357#else
Larry Hastings2f936352014-08-05 14:04:04 +100010358/*[clinic input]
10359os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010360
Larry Hastings2f936352014-08-05 14:04:04 +100010361 name: FSConverter
10362 value: FSConverter
10363 /
10364
10365Change or add an environment variable.
10366[clinic start generated code]*/
10367
Larry Hastings2f936352014-08-05 14:04:04 +100010368static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010369os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10370/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010371{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010372 const char *name_string = PyBytes_AS_STRING(name);
10373 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010374
Serhiy Storchaka77703942017-06-25 07:33:01 +030010375 if (strchr(name_string, '=') != NULL) {
10376 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10377 return NULL;
10378 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010379
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010380 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10381 return NULL;
10382 }
10383
Victor Stinnerb477d192020-01-22 22:48:16 +010010384 if (setenv(name_string, value_string, 1)) {
10385 return posix_error();
10386 }
Larry Hastings2f936352014-08-05 14:04:04 +100010387 Py_RETURN_NONE;
10388}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010389#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010390
10391
Victor Stinner161e7b32020-01-24 11:53:44 +010010392#ifdef MS_WINDOWS
10393/*[clinic input]
10394os.unsetenv
10395 name: unicode
10396 /
10397
10398Delete an environment variable.
10399[clinic start generated code]*/
10400
10401static PyObject *
10402os_unsetenv_impl(PyObject *module, PyObject *name)
10403/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10404{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010405 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10406 return NULL;
10407 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010408 return win32_putenv(name, NULL);
10409}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010410#else
Larry Hastings2f936352014-08-05 14:04:04 +100010411/*[clinic input]
10412os.unsetenv
10413 name: FSConverter
10414 /
10415
10416Delete an environment variable.
10417[clinic start generated code]*/
10418
Larry Hastings2f936352014-08-05 14:04:04 +100010419static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010420os_unsetenv_impl(PyObject *module, PyObject *name)
10421/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010422{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010423 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10424 return NULL;
10425 }
Victor Stinner984890f2011-11-24 13:53:38 +010010426#ifdef HAVE_BROKEN_UNSETENV
10427 unsetenv(PyBytes_AS_STRING(name));
10428#else
Victor Stinner161e7b32020-01-24 11:53:44 +010010429 int err = unsetenv(PyBytes_AS_STRING(name));
10430 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010010431 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010010432 }
Victor Stinner984890f2011-11-24 13:53:38 +010010433#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010434
Victor Stinner84ae1182010-05-06 22:05:07 +000010435 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010436}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010437#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000010438
Larry Hastings2f936352014-08-05 14:04:04 +100010439
10440/*[clinic input]
10441os.strerror
10442
10443 code: int
10444 /
10445
10446Translate an error code to a message string.
10447[clinic start generated code]*/
10448
Larry Hastings2f936352014-08-05 14:04:04 +100010449static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010450os_strerror_impl(PyObject *module, int code)
10451/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010452{
10453 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 if (message == NULL) {
10455 PyErr_SetString(PyExc_ValueError,
10456 "strerror() argument out of range");
10457 return NULL;
10458 }
Victor Stinner1b579672011-12-17 05:47:23 +010010459 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010460}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010461
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010462
Guido van Rossumc9641791998-08-04 15:26:23 +000010463#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010464#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010465/*[clinic input]
10466os.WCOREDUMP -> bool
10467
10468 status: int
10469 /
10470
10471Return True if the process returning status was dumped to a core file.
10472[clinic start generated code]*/
10473
Larry Hastings2f936352014-08-05 14:04:04 +100010474static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010475os_WCOREDUMP_impl(PyObject *module, int status)
10476/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010477{
10478 WAIT_TYPE wait_status;
10479 WAIT_STATUS_INT(wait_status) = status;
10480 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010481}
10482#endif /* WCOREDUMP */
10483
Larry Hastings2f936352014-08-05 14:04:04 +100010484
Fred Drake106c1a02002-04-23 15:58:02 +000010485#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010486/*[clinic input]
10487os.WIFCONTINUED -> bool
10488
10489 status: int
10490
10491Return True if a particular process was continued from a job control stop.
10492
10493Return True if the process returning status was continued from a
10494job control stop.
10495[clinic start generated code]*/
10496
Larry Hastings2f936352014-08-05 14:04:04 +100010497static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010498os_WIFCONTINUED_impl(PyObject *module, int status)
10499/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010500{
10501 WAIT_TYPE wait_status;
10502 WAIT_STATUS_INT(wait_status) = status;
10503 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010504}
10505#endif /* WIFCONTINUED */
10506
Larry Hastings2f936352014-08-05 14:04:04 +100010507
Guido van Rossumc9641791998-08-04 15:26:23 +000010508#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010509/*[clinic input]
10510os.WIFSTOPPED -> bool
10511
10512 status: int
10513
10514Return True if the process returning status was stopped.
10515[clinic start generated code]*/
10516
Larry Hastings2f936352014-08-05 14:04:04 +100010517static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010518os_WIFSTOPPED_impl(PyObject *module, int status)
10519/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010520{
10521 WAIT_TYPE wait_status;
10522 WAIT_STATUS_INT(wait_status) = status;
10523 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010524}
10525#endif /* WIFSTOPPED */
10526
Larry Hastings2f936352014-08-05 14:04:04 +100010527
Guido van Rossumc9641791998-08-04 15:26:23 +000010528#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010529/*[clinic input]
10530os.WIFSIGNALED -> bool
10531
10532 status: int
10533
10534Return True if the process returning status was terminated by a signal.
10535[clinic start generated code]*/
10536
Larry Hastings2f936352014-08-05 14:04:04 +100010537static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010538os_WIFSIGNALED_impl(PyObject *module, int status)
10539/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010540{
10541 WAIT_TYPE wait_status;
10542 WAIT_STATUS_INT(wait_status) = status;
10543 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010544}
10545#endif /* WIFSIGNALED */
10546
Larry Hastings2f936352014-08-05 14:04:04 +100010547
Guido van Rossumc9641791998-08-04 15:26:23 +000010548#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010549/*[clinic input]
10550os.WIFEXITED -> bool
10551
10552 status: int
10553
10554Return True if the process returning status exited via the exit() system call.
10555[clinic start generated code]*/
10556
Larry Hastings2f936352014-08-05 14:04:04 +100010557static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010558os_WIFEXITED_impl(PyObject *module, int status)
10559/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010560{
10561 WAIT_TYPE wait_status;
10562 WAIT_STATUS_INT(wait_status) = status;
10563 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010564}
10565#endif /* WIFEXITED */
10566
Larry Hastings2f936352014-08-05 14:04:04 +100010567
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010568#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010569/*[clinic input]
10570os.WEXITSTATUS -> int
10571
10572 status: int
10573
10574Return the process return code from status.
10575[clinic start generated code]*/
10576
Larry Hastings2f936352014-08-05 14:04:04 +100010577static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010578os_WEXITSTATUS_impl(PyObject *module, int status)
10579/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010580{
10581 WAIT_TYPE wait_status;
10582 WAIT_STATUS_INT(wait_status) = status;
10583 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010584}
10585#endif /* WEXITSTATUS */
10586
Larry Hastings2f936352014-08-05 14:04:04 +100010587
Guido van Rossumc9641791998-08-04 15:26:23 +000010588#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010589/*[clinic input]
10590os.WTERMSIG -> int
10591
10592 status: int
10593
10594Return the signal that terminated the process that provided the status value.
10595[clinic start generated code]*/
10596
Larry Hastings2f936352014-08-05 14:04:04 +100010597static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010598os_WTERMSIG_impl(PyObject *module, int status)
10599/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010600{
10601 WAIT_TYPE wait_status;
10602 WAIT_STATUS_INT(wait_status) = status;
10603 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010604}
10605#endif /* WTERMSIG */
10606
Larry Hastings2f936352014-08-05 14:04:04 +100010607
Guido van Rossumc9641791998-08-04 15:26:23 +000010608#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010609/*[clinic input]
10610os.WSTOPSIG -> int
10611
10612 status: int
10613
10614Return the signal that stopped the process that provided the status value.
10615[clinic start generated code]*/
10616
Larry Hastings2f936352014-08-05 14:04:04 +100010617static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010618os_WSTOPSIG_impl(PyObject *module, int status)
10619/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010620{
10621 WAIT_TYPE wait_status;
10622 WAIT_STATUS_INT(wait_status) = status;
10623 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010624}
10625#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010626#endif /* HAVE_SYS_WAIT_H */
10627
10628
Thomas Wouters477c8d52006-05-27 19:21:47 +000010629#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010630#ifdef _SCO_DS
10631/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10632 needed definitions in sys/statvfs.h */
10633#define _SVID3
10634#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010635#include <sys/statvfs.h>
10636
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010637static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +020010638_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
10639 PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080010640 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010641 if (v == NULL)
10642 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010643
10644#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010645 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10646 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10647 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10648 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10649 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10650 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10651 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10652 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10653 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10654 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010655#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10657 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10658 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010659 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010660 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010661 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010662 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010663 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010664 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010665 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010667 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010668 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010669 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010670 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10671 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010672#endif
Michael Felt502d5512018-01-05 13:01:58 +010010673/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10674 * (issue #32390). */
10675#if defined(_AIX) && defined(_ALL_SOURCE)
10676 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10677#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010678 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010679#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010680 if (PyErr_Occurred()) {
10681 Py_DECREF(v);
10682 return NULL;
10683 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010684
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010686}
10687
Larry Hastings2f936352014-08-05 14:04:04 +100010688
10689/*[clinic input]
10690os.fstatvfs
10691 fd: int
10692 /
10693
10694Perform an fstatvfs system call on the given fd.
10695
10696Equivalent to statvfs(fd).
10697[clinic start generated code]*/
10698
Larry Hastings2f936352014-08-05 14:04:04 +100010699static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010700os_fstatvfs_impl(PyObject *module, int fd)
10701/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010702{
10703 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010704 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010706
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010707 do {
10708 Py_BEGIN_ALLOW_THREADS
10709 result = fstatvfs(fd, &st);
10710 Py_END_ALLOW_THREADS
10711 } while (result != 0 && errno == EINTR &&
10712 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010713 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010714 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010715
Victor Stinner1c2fa782020-05-10 11:05:29 +020010716 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010717}
Larry Hastings2f936352014-08-05 14:04:04 +100010718#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010719
10720
Thomas Wouters477c8d52006-05-27 19:21:47 +000010721#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010722#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010723/*[clinic input]
10724os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010725
Larry Hastings2f936352014-08-05 14:04:04 +100010726 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10727
10728Perform a statvfs system call on the given path.
10729
10730path may always be specified as a string.
10731On some platforms, path may also be specified as an open file descriptor.
10732 If this functionality is unavailable, using it raises an exception.
10733[clinic start generated code]*/
10734
Larry Hastings2f936352014-08-05 14:04:04 +100010735static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010736os_statvfs_impl(PyObject *module, path_t *path)
10737/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010738{
10739 int result;
10740 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010741
10742 Py_BEGIN_ALLOW_THREADS
10743#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010744 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010745#ifdef __APPLE__
10746 /* handle weak-linking on Mac OS X 10.3 */
10747 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010748 fd_specified("statvfs", path->fd);
10749 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010750 }
10751#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010752 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753 }
10754 else
10755#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010756 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010757 Py_END_ALLOW_THREADS
10758
10759 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010760 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010761 }
10762
Victor Stinner1c2fa782020-05-10 11:05:29 +020010763 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010764}
Larry Hastings2f936352014-08-05 14:04:04 +100010765#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10766
Guido van Rossum94f6f721999-01-06 18:42:14 +000010767
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010768#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010769/*[clinic input]
10770os._getdiskusage
10771
Steve Dower23ad6d02018-02-22 10:39:10 -080010772 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010773
10774Return disk usage statistics about the given path as a (total, free) tuple.
10775[clinic start generated code]*/
10776
Larry Hastings2f936352014-08-05 14:04:04 +100010777static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010778os__getdiskusage_impl(PyObject *module, path_t *path)
10779/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010780{
10781 BOOL retval;
10782 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010783 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010784
10785 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010786 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010787 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010788 if (retval == 0) {
10789 if (GetLastError() == ERROR_DIRECTORY) {
10790 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010791
Joe Pamerc8c02492018-09-25 10:57:36 -040010792 dir_path = PyMem_New(wchar_t, path->length + 1);
10793 if (dir_path == NULL) {
10794 return PyErr_NoMemory();
10795 }
10796
10797 wcscpy_s(dir_path, path->length + 1, path->wide);
10798
10799 if (_dirnameW(dir_path) != -1) {
10800 Py_BEGIN_ALLOW_THREADS
10801 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10802 Py_END_ALLOW_THREADS
10803 }
10804 /* Record the last error in case it's modified by PyMem_Free. */
10805 err = GetLastError();
10806 PyMem_Free(dir_path);
10807 if (retval) {
10808 goto success;
10809 }
10810 }
10811 return PyErr_SetFromWindowsErr(err);
10812 }
10813
10814success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010815 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10816}
Larry Hastings2f936352014-08-05 14:04:04 +100010817#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010818
10819
Fred Drakec9680921999-12-13 16:37:25 +000010820/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10821 * It maps strings representing configuration variable names to
10822 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010823 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010824 * rarely-used constants. There are three separate tables that use
10825 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010826 *
10827 * This code is always included, even if none of the interfaces that
10828 * need it are included. The #if hackery needed to avoid it would be
10829 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010830 */
10831struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010832 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010833 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010834};
10835
Fred Drake12c6e2d1999-12-14 21:25:03 +000010836static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010837conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010838 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010839{
Christian Heimes217cfd12007-12-02 14:31:20 +000010840 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010841 int value = _PyLong_AsInt(arg);
10842 if (value == -1 && PyErr_Occurred())
10843 return 0;
10844 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010845 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010846 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010847 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010848 /* look up the value in the table using a binary search */
10849 size_t lo = 0;
10850 size_t mid;
10851 size_t hi = tablesize;
10852 int cmp;
10853 const char *confname;
10854 if (!PyUnicode_Check(arg)) {
10855 PyErr_SetString(PyExc_TypeError,
10856 "configuration names must be strings or integers");
10857 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010858 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010859 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010860 if (confname == NULL)
10861 return 0;
10862 while (lo < hi) {
10863 mid = (lo + hi) / 2;
10864 cmp = strcmp(confname, table[mid].name);
10865 if (cmp < 0)
10866 hi = mid;
10867 else if (cmp > 0)
10868 lo = mid + 1;
10869 else {
10870 *valuep = table[mid].value;
10871 return 1;
10872 }
10873 }
10874 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10875 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010877}
10878
10879
10880#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10881static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010882#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010883 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010884#endif
10885#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010886 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010887#endif
Fred Drakec9680921999-12-13 16:37:25 +000010888#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010889 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010890#endif
10891#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010892 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010893#endif
10894#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010895 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010896#endif
10897#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010899#endif
10900#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010901 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010902#endif
10903#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010905#endif
10906#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010908#endif
10909#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010910 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010911#endif
10912#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010914#endif
10915#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010917#endif
10918#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010920#endif
10921#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010923#endif
10924#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010925 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010926#endif
10927#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010928 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010929#endif
10930#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010931 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010932#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010933#ifdef _PC_ACL_ENABLED
10934 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10935#endif
10936#ifdef _PC_MIN_HOLE_SIZE
10937 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10938#endif
10939#ifdef _PC_ALLOC_SIZE_MIN
10940 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10941#endif
10942#ifdef _PC_REC_INCR_XFER_SIZE
10943 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10944#endif
10945#ifdef _PC_REC_MAX_XFER_SIZE
10946 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10947#endif
10948#ifdef _PC_REC_MIN_XFER_SIZE
10949 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10950#endif
10951#ifdef _PC_REC_XFER_ALIGN
10952 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10953#endif
10954#ifdef _PC_SYMLINK_MAX
10955 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10956#endif
10957#ifdef _PC_XATTR_ENABLED
10958 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10959#endif
10960#ifdef _PC_XATTR_EXISTS
10961 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10962#endif
10963#ifdef _PC_TIMESTAMP_RESOLUTION
10964 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10965#endif
Fred Drakec9680921999-12-13 16:37:25 +000010966};
10967
Fred Drakec9680921999-12-13 16:37:25 +000010968static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010969conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010970{
10971 return conv_confname(arg, valuep, posix_constants_pathconf,
10972 sizeof(posix_constants_pathconf)
10973 / sizeof(struct constdef));
10974}
10975#endif
10976
Larry Hastings2f936352014-08-05 14:04:04 +100010977
Fred Drakec9680921999-12-13 16:37:25 +000010978#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010979/*[clinic input]
10980os.fpathconf -> long
10981
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070010982 fd: fildes
Larry Hastings2f936352014-08-05 14:04:04 +100010983 name: path_confname
10984 /
10985
10986Return the configuration limit name for the file descriptor fd.
10987
10988If there is no limit, return -1.
10989[clinic start generated code]*/
10990
Larry Hastings2f936352014-08-05 14:04:04 +100010991static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010992os_fpathconf_impl(PyObject *module, int fd, int name)
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070010993/*[clinic end generated code: output=d5b7042425fc3e21 input=5b8d2471cfaae186]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010994{
10995 long limit;
10996
10997 errno = 0;
10998 limit = fpathconf(fd, name);
10999 if (limit == -1 && errno != 0)
11000 posix_error();
11001
11002 return limit;
11003}
11004#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011005
11006
11007#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011008/*[clinic input]
11009os.pathconf -> long
11010 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
11011 name: path_confname
11012
11013Return the configuration limit name for the file or directory path.
11014
11015If there is no limit, return -1.
11016On some platforms, path may also be specified as an open file descriptor.
11017 If this functionality is unavailable, using it raises an exception.
11018[clinic start generated code]*/
11019
Larry Hastings2f936352014-08-05 14:04:04 +100011020static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011021os_pathconf_impl(PyObject *module, path_t *path, int name)
11022/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011023{
Victor Stinner8c62be82010-05-06 00:08:46 +000011024 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000011025
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020011027#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011028 if (path->fd != -1)
11029 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020011030 else
11031#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011032 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000011033 if (limit == -1 && errno != 0) {
11034 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000011035 /* could be a path or name problem */
11036 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000011037 else
Larry Hastings2f936352014-08-05 14:04:04 +100011038 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000011039 }
Larry Hastings2f936352014-08-05 14:04:04 +100011040
11041 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000011042}
Larry Hastings2f936352014-08-05 14:04:04 +100011043#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011044
11045#ifdef HAVE_CONFSTR
11046static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011047#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000011048 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000011049#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000011050#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011051 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011052#endif
11053#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011054 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011055#endif
Fred Draked86ed291999-12-15 15:34:33 +000011056#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011057 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011058#endif
11059#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011060 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011061#endif
11062#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011063 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011064#endif
11065#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011066 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011067#endif
Fred Drakec9680921999-12-13 16:37:25 +000011068#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011069 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011070#endif
11071#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011072 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011073#endif
11074#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011075 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011076#endif
11077#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011078 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011079#endif
11080#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011081 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011082#endif
11083#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011084 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011085#endif
11086#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011087 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011088#endif
11089#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011090 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011091#endif
Fred Draked86ed291999-12-15 15:34:33 +000011092#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000011093 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000011094#endif
Fred Drakec9680921999-12-13 16:37:25 +000011095#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000011096 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000011097#endif
Fred Draked86ed291999-12-15 15:34:33 +000011098#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011099 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000011100#endif
11101#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011102 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000011103#endif
11104#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011105 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011106#endif
11107#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011108 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000011109#endif
Fred Drakec9680921999-12-13 16:37:25 +000011110#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011111 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011112#endif
11113#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011114 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011115#endif
11116#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011117 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011118#endif
11119#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011120 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011121#endif
11122#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011123 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011124#endif
11125#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011126 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011127#endif
11128#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011129 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011130#endif
11131#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011132 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011133#endif
11134#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011135 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011136#endif
11137#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011138 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011139#endif
11140#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011141 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011142#endif
11143#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011144 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011145#endif
11146#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011147 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011148#endif
11149#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011150 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011151#endif
11152#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011153 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011154#endif
11155#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011156 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011157#endif
Fred Draked86ed291999-12-15 15:34:33 +000011158#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011159 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011160#endif
11161#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011162 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011163#endif
11164#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011165 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011166#endif
11167#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011168 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011169#endif
11170#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011171 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011172#endif
11173#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011174 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011175#endif
11176#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011177 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011178#endif
11179#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011180 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011181#endif
11182#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011183 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011184#endif
11185#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011186 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011187#endif
11188#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011189 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011190#endif
11191#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011192 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011193#endif
11194#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011195 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011196#endif
Fred Drakec9680921999-12-13 16:37:25 +000011197};
11198
11199static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011200conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011201{
11202 return conv_confname(arg, valuep, posix_constants_confstr,
11203 sizeof(posix_constants_confstr)
11204 / sizeof(struct constdef));
11205}
11206
Larry Hastings2f936352014-08-05 14:04:04 +100011207
11208/*[clinic input]
11209os.confstr
11210
11211 name: confstr_confname
11212 /
11213
11214Return a string-valued system configuration variable.
11215[clinic start generated code]*/
11216
Larry Hastings2f936352014-08-05 14:04:04 +100011217static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011218os_confstr_impl(PyObject *module, int name)
11219/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011220{
11221 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011222 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011223 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011224
Victor Stinnercb043522010-09-10 23:49:04 +000011225 errno = 0;
11226 len = confstr(name, buffer, sizeof(buffer));
11227 if (len == 0) {
11228 if (errno) {
11229 posix_error();
11230 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011231 }
11232 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011233 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011234 }
11235 }
Victor Stinnercb043522010-09-10 23:49:04 +000011236
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011237 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011238 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011239 char *buf = PyMem_Malloc(len);
11240 if (buf == NULL)
11241 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011242 len2 = confstr(name, buf, len);
11243 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011244 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011245 PyMem_Free(buf);
11246 }
11247 else
11248 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011249 return result;
11250}
Larry Hastings2f936352014-08-05 14:04:04 +100011251#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011252
11253
11254#ifdef HAVE_SYSCONF
11255static struct constdef posix_constants_sysconf[] = {
11256#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011258#endif
11259#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011260 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011261#endif
11262#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011263 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011264#endif
11265#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011266 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011267#endif
11268#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011269 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011270#endif
11271#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011272 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011273#endif
11274#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011275 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011276#endif
11277#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011278 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011279#endif
11280#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011281 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011282#endif
11283#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011284 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011285#endif
Fred Draked86ed291999-12-15 15:34:33 +000011286#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011287 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011288#endif
11289#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011290 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011291#endif
Fred Drakec9680921999-12-13 16:37:25 +000011292#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011293 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011294#endif
Fred Drakec9680921999-12-13 16:37:25 +000011295#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011297#endif
11298#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011299 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011300#endif
11301#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011302 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011303#endif
11304#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011306#endif
11307#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011308 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011309#endif
Fred Draked86ed291999-12-15 15:34:33 +000011310#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011311 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011312#endif
Fred Drakec9680921999-12-13 16:37:25 +000011313#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011314 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011315#endif
11316#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011317 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011318#endif
11319#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011320 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011321#endif
11322#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011323 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011324#endif
11325#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011326 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011327#endif
Fred Draked86ed291999-12-15 15:34:33 +000011328#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011329 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011330#endif
Fred Drakec9680921999-12-13 16:37:25 +000011331#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011332 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011333#endif
11334#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011335 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011336#endif
11337#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011338 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011339#endif
11340#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011341 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011342#endif
11343#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011344 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011345#endif
11346#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011347 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011348#endif
11349#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011350 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011351#endif
11352#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011354#endif
11355#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011356 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011357#endif
11358#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011360#endif
11361#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011362 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011363#endif
11364#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011365 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011366#endif
11367#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011368 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011369#endif
11370#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011371 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011372#endif
11373#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011374 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011375#endif
11376#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011377 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011378#endif
11379#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011380 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011381#endif
11382#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011383 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011384#endif
11385#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011386 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011387#endif
11388#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011389 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011390#endif
11391#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011392 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011393#endif
11394#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011395 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011396#endif
11397#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011398 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011399#endif
Fred Draked86ed291999-12-15 15:34:33 +000011400#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011401 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011402#endif
Fred Drakec9680921999-12-13 16:37:25 +000011403#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011404 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011405#endif
11406#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011407 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011408#endif
11409#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011410 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011411#endif
Fred Draked86ed291999-12-15 15:34:33 +000011412#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011413 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011414#endif
Fred Drakec9680921999-12-13 16:37:25 +000011415#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011416 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011417#endif
Fred Draked86ed291999-12-15 15:34:33 +000011418#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011419 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011420#endif
11421#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011422 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011423#endif
Fred Drakec9680921999-12-13 16:37:25 +000011424#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011425 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011426#endif
11427#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011428 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011429#endif
11430#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011431 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011432#endif
11433#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011434 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011435#endif
Fred Draked86ed291999-12-15 15:34:33 +000011436#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011437 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011438#endif
Fred Drakec9680921999-12-13 16:37:25 +000011439#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011440 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011441#endif
11442#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011443 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011444#endif
11445#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011446 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011447#endif
11448#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011449 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011450#endif
11451#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011452 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011453#endif
11454#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011455 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011456#endif
11457#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011458 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011459#endif
Fred Draked86ed291999-12-15 15:34:33 +000011460#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011461 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011462#endif
Fred Drakec9680921999-12-13 16:37:25 +000011463#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011464 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011465#endif
11466#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011467 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011468#endif
Fred Draked86ed291999-12-15 15:34:33 +000011469#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011470 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011471#endif
Fred Drakec9680921999-12-13 16:37:25 +000011472#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011473 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011474#endif
11475#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011476 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011477#endif
11478#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011479 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011480#endif
11481#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011482 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011483#endif
11484#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011485 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011486#endif
11487#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011488 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011489#endif
11490#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011491 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011492#endif
11493#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011494 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011495#endif
11496#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011497 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011498#endif
Fred Draked86ed291999-12-15 15:34:33 +000011499#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011500 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011501#endif
11502#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011503 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011504#endif
Fred Drakec9680921999-12-13 16:37:25 +000011505#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011506 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011507#endif
11508#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011509 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011510#endif
11511#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011512 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011513#endif
11514#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011515 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011516#endif
Batuhan Taşkaya909f4a32020-04-05 03:40:49 +030011517#ifdef _SC_AIX_REALMEM
11518 {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
11519#endif
Fred Drakec9680921999-12-13 16:37:25 +000011520#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011521 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011522#endif
11523#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011524 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011525#endif
11526#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011527 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011528#endif
11529#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011530 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011531#endif
11532#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011533 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011534#endif
11535#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011536 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011537#endif
11538#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011539 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011540#endif
11541#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011542 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011543#endif
11544#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011545 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011546#endif
11547#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011549#endif
11550#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011551 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011552#endif
11553#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011554 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011555#endif
11556#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011557 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011558#endif
11559#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011560 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011561#endif
11562#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011563 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011564#endif
11565#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011566 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011567#endif
11568#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011569 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011570#endif
11571#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011572 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011573#endif
11574#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011575 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011576#endif
11577#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011578 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011579#endif
11580#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011581 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011582#endif
11583#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011584 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011585#endif
11586#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011587 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011588#endif
11589#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011590 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011591#endif
11592#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011593 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011594#endif
11595#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011596 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011597#endif
11598#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011599 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011600#endif
11601#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011602 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011603#endif
11604#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011605 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011606#endif
11607#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011608 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011609#endif
11610#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011611 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011612#endif
Fred Draked86ed291999-12-15 15:34:33 +000011613#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011614 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011615#endif
Fred Drakec9680921999-12-13 16:37:25 +000011616#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011617 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011618#endif
11619#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011620 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011621#endif
11622#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011623 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011624#endif
11625#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011626 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011627#endif
11628#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011629 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011630#endif
11631#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011632 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011633#endif
11634#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011635 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011636#endif
11637#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011638 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011639#endif
11640#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011641 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011642#endif
11643#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011644 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011645#endif
11646#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011647 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011648#endif
11649#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011650 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011651#endif
11652#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011653 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011654#endif
11655#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011656 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011657#endif
11658#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011659 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011660#endif
11661#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011662 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011663#endif
11664#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011665 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011666#endif
11667#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011668 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011669#endif
11670#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011671 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011672#endif
11673#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011674 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011675#endif
11676#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011677 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011678#endif
11679#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011680 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011681#endif
11682#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011683 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011684#endif
11685#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011686 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011687#endif
11688#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011689 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011690#endif
11691#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011692 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011693#endif
11694#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011695 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011696#endif
11697#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011698 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011699#endif
11700#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011701 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011702#endif
11703#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011704 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011705#endif
11706#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011707 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011708#endif
11709#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011710 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011711#endif
11712#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011713 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011714#endif
11715#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011716 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011717#endif
11718#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011719 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011720#endif
11721#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011722 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011723#endif
11724#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011725 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011726#endif
11727#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011728 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011729#endif
11730#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011731 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011732#endif
11733#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011734 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011735#endif
11736#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011737 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011738#endif
11739#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011740 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011741#endif
11742#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011743 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011744#endif
11745#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011746 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011747#endif
11748#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011749 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011750#endif
11751};
11752
11753static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011754conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011755{
11756 return conv_confname(arg, valuep, posix_constants_sysconf,
11757 sizeof(posix_constants_sysconf)
11758 / sizeof(struct constdef));
11759}
11760
Larry Hastings2f936352014-08-05 14:04:04 +100011761
11762/*[clinic input]
11763os.sysconf -> long
11764 name: sysconf_confname
11765 /
11766
11767Return an integer-valued system configuration variable.
11768[clinic start generated code]*/
11769
Larry Hastings2f936352014-08-05 14:04:04 +100011770static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011771os_sysconf_impl(PyObject *module, int name)
11772/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011773{
11774 long value;
11775
11776 errno = 0;
11777 value = sysconf(name);
11778 if (value == -1 && errno != 0)
11779 posix_error();
11780 return value;
11781}
11782#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011783
11784
Fred Drakebec628d1999-12-15 18:31:10 +000011785/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011786 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011787 * the exported dictionaries that are used to publish information about the
11788 * names available on the host platform.
11789 *
11790 * Sorting the table at runtime ensures that the table is properly ordered
11791 * when used, even for platforms we're not able to test on. It also makes
11792 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011793 */
Fred Drakebec628d1999-12-15 18:31:10 +000011794
11795static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011796cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011797{
11798 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011799 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011800 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011801 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011802
11803 return strcmp(c1->name, c2->name);
11804}
11805
11806static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011807setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011808 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011809{
Fred Drakebec628d1999-12-15 18:31:10 +000011810 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011811 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011812
11813 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11814 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011815 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011816 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011817
Barry Warsaw3155db32000-04-13 15:20:40 +000011818 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011819 PyObject *o = PyLong_FromLong(table[i].value);
11820 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11821 Py_XDECREF(o);
11822 Py_DECREF(d);
11823 return -1;
11824 }
11825 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011826 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011827 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011828}
11829
Fred Drakebec628d1999-12-15 18:31:10 +000011830/* Return -1 on failure, 0 on success. */
11831static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011832setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011833{
11834#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011835 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011836 sizeof(posix_constants_pathconf)
11837 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011838 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011839 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011840#endif
11841#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011842 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011843 sizeof(posix_constants_confstr)
11844 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011845 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011846 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011847#endif
11848#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011849 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011850 sizeof(posix_constants_sysconf)
11851 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011852 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011853 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011854#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011855 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011856}
Fred Draked86ed291999-12-15 15:34:33 +000011857
11858
Larry Hastings2f936352014-08-05 14:04:04 +100011859/*[clinic input]
11860os.abort
11861
11862Abort the interpreter immediately.
11863
11864This function 'dumps core' or otherwise fails in the hardest way possible
11865on the hosting operating system. This function never returns.
11866[clinic start generated code]*/
11867
Larry Hastings2f936352014-08-05 14:04:04 +100011868static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011869os_abort_impl(PyObject *module)
11870/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011871{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011872 abort();
11873 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011874#ifndef __clang__
11875 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11876 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11877 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011878 Py_FatalError("abort() called from Python code didn't abort!");
11879 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011880#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011881}
Fred Drakebec628d1999-12-15 18:31:10 +000011882
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011883#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011884/* Grab ShellExecute dynamically from shell32 */
11885static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011886static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11887 LPCWSTR, INT);
11888static int
11889check_ShellExecute()
11890{
11891 HINSTANCE hShell32;
11892
11893 /* only recheck */
11894 if (-1 == has_ShellExecute) {
11895 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011896 /* Security note: this call is not vulnerable to "DLL hijacking".
11897 SHELL32 is part of "KnownDLLs" and so Windows always load
11898 the system SHELL32.DLL, even if there is another SHELL32.DLL
11899 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011900 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011901 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011902 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11903 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011904 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011905 } else {
11906 has_ShellExecute = 0;
11907 }
Tony Roberts4860f012019-02-02 18:16:42 +010011908 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011909 }
11910 return has_ShellExecute;
11911}
11912
11913
Steve Dowercc16be82016-09-08 10:35:16 -070011914/*[clinic input]
11915os.startfile
11916 filepath: path_t
11917 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011918
Steve Dowercc16be82016-09-08 10:35:16 -070011919Start a file with its associated application.
11920
11921When "operation" is not specified or "open", this acts like
11922double-clicking the file in Explorer, or giving the file name as an
11923argument to the DOS "start" command: the file is opened with whatever
11924application (if any) its extension is associated.
11925When another "operation" is given, it specifies what should be done with
11926the file. A typical operation is "print".
11927
11928startfile returns as soon as the associated application is launched.
11929There is no option to wait for the application to close, and no way
11930to retrieve the application's exit status.
11931
11932The filepath is relative to the current directory. If you want to use
11933an absolute path, make sure the first character is not a slash ("/");
11934the underlying Win32 ShellExecute function doesn't work if it is.
11935[clinic start generated code]*/
11936
11937static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011938os_startfile_impl(PyObject *module, path_t *filepath,
11939 const Py_UNICODE *operation)
Serhiy Storchaka279f4462019-09-14 12:24:05 +030011940/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011941{
11942 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011943
11944 if(!check_ShellExecute()) {
11945 /* If the OS doesn't have ShellExecute, return a
11946 NotImplementedError. */
11947 return PyErr_Format(PyExc_NotImplementedError,
11948 "startfile not available on this platform");
11949 }
11950
Saiyang Gou7514f4f2020-02-12 23:47:42 -080011951 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080011952 return NULL;
11953 }
11954
Victor Stinner8c62be82010-05-06 00:08:46 +000011955 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011956 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011957 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011958 Py_END_ALLOW_THREADS
11959
Victor Stinner8c62be82010-05-06 00:08:46 +000011960 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011961 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011962 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011963 }
Steve Dowercc16be82016-09-08 10:35:16 -070011964 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011965}
Larry Hastings2f936352014-08-05 14:04:04 +100011966#endif /* MS_WINDOWS */
11967
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011968
Martin v. Löwis438b5342002-12-27 10:16:42 +000011969#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011970/*[clinic input]
11971os.getloadavg
11972
11973Return average recent system load information.
11974
11975Return the number of processes in the system run queue averaged over
11976the last 1, 5, and 15 minutes as a tuple of three floats.
11977Raises OSError if the load average was unobtainable.
11978[clinic start generated code]*/
11979
Larry Hastings2f936352014-08-05 14:04:04 +100011980static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011981os_getloadavg_impl(PyObject *module)
11982/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011983{
11984 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011985 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011986 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11987 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011988 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011989 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011990}
Larry Hastings2f936352014-08-05 14:04:04 +100011991#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011992
Larry Hastings2f936352014-08-05 14:04:04 +100011993
11994/*[clinic input]
11995os.device_encoding
11996 fd: int
11997
11998Return a string describing the encoding of a terminal's file descriptor.
11999
12000The file descriptor must be attached to a terminal.
12001If the device is not a terminal, return None.
12002[clinic start generated code]*/
12003
Larry Hastings2f936352014-08-05 14:04:04 +100012004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012005os_device_encoding_impl(PyObject *module, int fd)
12006/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012007{
Brett Cannonefb00c02012-02-29 18:31:31 -050012008 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000012009}
12010
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012011
Larry Hastings2f936352014-08-05 14:04:04 +100012012#ifdef HAVE_SETRESUID
12013/*[clinic input]
12014os.setresuid
12015
12016 ruid: uid_t
12017 euid: uid_t
12018 suid: uid_t
12019 /
12020
12021Set the current process's real, effective, and saved user ids.
12022[clinic start generated code]*/
12023
Larry Hastings2f936352014-08-05 14:04:04 +100012024static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012025os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
12026/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012027{
Victor Stinner8c62be82010-05-06 00:08:46 +000012028 if (setresuid(ruid, euid, suid) < 0)
12029 return posix_error();
12030 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012031}
Larry Hastings2f936352014-08-05 14:04:04 +100012032#endif /* HAVE_SETRESUID */
12033
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012034
12035#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012036/*[clinic input]
12037os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012038
Larry Hastings2f936352014-08-05 14:04:04 +100012039 rgid: gid_t
12040 egid: gid_t
12041 sgid: gid_t
12042 /
12043
12044Set the current process's real, effective, and saved group ids.
12045[clinic start generated code]*/
12046
Larry Hastings2f936352014-08-05 14:04:04 +100012047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012048os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12049/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012050{
Victor Stinner8c62be82010-05-06 00:08:46 +000012051 if (setresgid(rgid, egid, sgid) < 0)
12052 return posix_error();
12053 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012054}
Larry Hastings2f936352014-08-05 14:04:04 +100012055#endif /* HAVE_SETRESGID */
12056
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012057
12058#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100012059/*[clinic input]
12060os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012061
Larry Hastings2f936352014-08-05 14:04:04 +100012062Return a tuple of the current process's real, effective, and saved user ids.
12063[clinic start generated code]*/
12064
Larry Hastings2f936352014-08-05 14:04:04 +100012065static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012066os_getresuid_impl(PyObject *module)
12067/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012068{
Victor Stinner8c62be82010-05-06 00:08:46 +000012069 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012070 if (getresuid(&ruid, &euid, &suid) < 0)
12071 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012072 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
12073 _PyLong_FromUid(euid),
12074 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012075}
Larry Hastings2f936352014-08-05 14:04:04 +100012076#endif /* HAVE_GETRESUID */
12077
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012078
12079#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012080/*[clinic input]
12081os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012082
Larry Hastings2f936352014-08-05 14:04:04 +100012083Return a tuple of the current process's real, effective, and saved group ids.
12084[clinic start generated code]*/
12085
Larry Hastings2f936352014-08-05 14:04:04 +100012086static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012087os_getresgid_impl(PyObject *module)
12088/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012089{
12090 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012091 if (getresgid(&rgid, &egid, &sgid) < 0)
12092 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012093 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
12094 _PyLong_FromGid(egid),
12095 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012096}
Larry Hastings2f936352014-08-05 14:04:04 +100012097#endif /* HAVE_GETRESGID */
12098
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012099
Benjamin Peterson9428d532011-09-14 11:45:52 -040012100#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100012101/*[clinic input]
12102os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040012103
Larry Hastings2f936352014-08-05 14:04:04 +100012104 path: path_t(allow_fd=True)
12105 attribute: path_t
12106 *
12107 follow_symlinks: bool = True
12108
12109Return the value of extended attribute attribute on path.
12110
BNMetricsb9427072018-11-02 15:20:19 +000012111path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012112If follow_symlinks is False, and the last element of the path is a symbolic
12113 link, getxattr will examine the symbolic link itself instead of the file
12114 the link points to.
12115
12116[clinic start generated code]*/
12117
Larry Hastings2f936352014-08-05 14:04:04 +100012118static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012119os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012120 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012121/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012122{
12123 Py_ssize_t i;
12124 PyObject *buffer = NULL;
12125
12126 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12127 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012128
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012129 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12130 return NULL;
12131 }
12132
Larry Hastings9cf065c2012-06-22 16:30:09 -070012133 for (i = 0; ; i++) {
12134 void *ptr;
12135 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012136 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012137 Py_ssize_t buffer_size = buffer_sizes[i];
12138 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012139 path_error(path);
12140 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012141 }
12142 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12143 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012144 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012145 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012146
Larry Hastings9cf065c2012-06-22 16:30:09 -070012147 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012148 if (path->fd >= 0)
12149 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012150 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012151 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012152 else
Larry Hastings2f936352014-08-05 14:04:04 +100012153 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012154 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012155
Larry Hastings9cf065c2012-06-22 16:30:09 -070012156 if (result < 0) {
12157 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012158 if (errno == ERANGE)
12159 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012160 path_error(path);
12161 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012162 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012163
Larry Hastings9cf065c2012-06-22 16:30:09 -070012164 if (result != buffer_size) {
12165 /* Can only shrink. */
12166 _PyBytes_Resize(&buffer, result);
12167 }
12168 break;
12169 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012170
Larry Hastings9cf065c2012-06-22 16:30:09 -070012171 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012172}
12173
Larry Hastings2f936352014-08-05 14:04:04 +100012174
12175/*[clinic input]
12176os.setxattr
12177
12178 path: path_t(allow_fd=True)
12179 attribute: path_t
12180 value: Py_buffer
12181 flags: int = 0
12182 *
12183 follow_symlinks: bool = True
12184
12185Set extended attribute attribute on path to value.
12186
BNMetricsb9427072018-11-02 15:20:19 +000012187path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012188If follow_symlinks is False, and the last element of the path is a symbolic
12189 link, setxattr will modify the symbolic link itself instead of the file
12190 the link points to.
12191
12192[clinic start generated code]*/
12193
Benjamin Peterson799bd802011-08-31 22:15:17 -040012194static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012195os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012196 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012197/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012198{
Larry Hastings2f936352014-08-05 14:04:04 +100012199 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012200
Larry Hastings2f936352014-08-05 14:04:04 +100012201 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012202 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012203
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012204 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12205 value->buf, value->len, flags) < 0) {
12206 return NULL;
12207 }
12208
Benjamin Peterson799bd802011-08-31 22:15:17 -040012209 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012210 if (path->fd > -1)
12211 result = fsetxattr(path->fd, attribute->narrow,
12212 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012213 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012214 result = setxattr(path->narrow, attribute->narrow,
12215 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012216 else
Larry Hastings2f936352014-08-05 14:04:04 +100012217 result = lsetxattr(path->narrow, attribute->narrow,
12218 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012219 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012220
Larry Hastings9cf065c2012-06-22 16:30:09 -070012221 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012222 path_error(path);
12223 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012224 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012225
Larry Hastings2f936352014-08-05 14:04:04 +100012226 Py_RETURN_NONE;
12227}
12228
12229
12230/*[clinic input]
12231os.removexattr
12232
12233 path: path_t(allow_fd=True)
12234 attribute: path_t
12235 *
12236 follow_symlinks: bool = True
12237
12238Remove extended attribute attribute on path.
12239
BNMetricsb9427072018-11-02 15:20:19 +000012240path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012241If follow_symlinks is False, and the last element of the path is a symbolic
12242 link, removexattr will modify the symbolic link itself instead of the file
12243 the link points to.
12244
12245[clinic start generated code]*/
12246
Larry Hastings2f936352014-08-05 14:04:04 +100012247static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012248os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012249 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012250/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012251{
12252 ssize_t result;
12253
12254 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12255 return NULL;
12256
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012257 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12258 return NULL;
12259 }
12260
Larry Hastings2f936352014-08-05 14:04:04 +100012261 Py_BEGIN_ALLOW_THREADS;
12262 if (path->fd > -1)
12263 result = fremovexattr(path->fd, attribute->narrow);
12264 else if (follow_symlinks)
12265 result = removexattr(path->narrow, attribute->narrow);
12266 else
12267 result = lremovexattr(path->narrow, attribute->narrow);
12268 Py_END_ALLOW_THREADS;
12269
12270 if (result) {
12271 return path_error(path);
12272 }
12273
12274 Py_RETURN_NONE;
12275}
12276
12277
12278/*[clinic input]
12279os.listxattr
12280
12281 path: path_t(allow_fd=True, nullable=True) = None
12282 *
12283 follow_symlinks: bool = True
12284
12285Return a list of extended attributes on path.
12286
BNMetricsb9427072018-11-02 15:20:19 +000012287path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012288if path is None, listxattr will examine the current directory.
12289If follow_symlinks is False, and the last element of the path is a symbolic
12290 link, listxattr will examine the symbolic link itself instead of the file
12291 the link points to.
12292[clinic start generated code]*/
12293
Larry Hastings2f936352014-08-05 14:04:04 +100012294static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012295os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012296/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012297{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012298 Py_ssize_t i;
12299 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012300 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012301 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012302
Larry Hastings2f936352014-08-05 14:04:04 +100012303 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012304 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012305
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012306 if (PySys_Audit("os.listxattr", "(O)",
12307 path->object ? path->object : Py_None) < 0) {
12308 return NULL;
12309 }
12310
Larry Hastings2f936352014-08-05 14:04:04 +100012311 name = path->narrow ? path->narrow : ".";
12312
Larry Hastings9cf065c2012-06-22 16:30:09 -070012313 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012314 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012315 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012316 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012317 Py_ssize_t buffer_size = buffer_sizes[i];
12318 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012319 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012320 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012321 break;
12322 }
12323 buffer = PyMem_MALLOC(buffer_size);
12324 if (!buffer) {
12325 PyErr_NoMemory();
12326 break;
12327 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012328
Larry Hastings9cf065c2012-06-22 16:30:09 -070012329 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012330 if (path->fd > -1)
12331 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012332 else if (follow_symlinks)
12333 length = listxattr(name, buffer, buffer_size);
12334 else
12335 length = llistxattr(name, buffer, buffer_size);
12336 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012337
Larry Hastings9cf065c2012-06-22 16:30:09 -070012338 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012339 if (errno == ERANGE) {
12340 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012341 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012342 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012343 }
Larry Hastings2f936352014-08-05 14:04:04 +100012344 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012345 break;
12346 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012347
Larry Hastings9cf065c2012-06-22 16:30:09 -070012348 result = PyList_New(0);
12349 if (!result) {
12350 goto exit;
12351 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012352
Larry Hastings9cf065c2012-06-22 16:30:09 -070012353 end = buffer + length;
12354 for (trace = start = buffer; trace != end; trace++) {
12355 if (!*trace) {
12356 int error;
12357 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12358 trace - start);
12359 if (!attribute) {
12360 Py_DECREF(result);
12361 result = NULL;
12362 goto exit;
12363 }
12364 error = PyList_Append(result, attribute);
12365 Py_DECREF(attribute);
12366 if (error) {
12367 Py_DECREF(result);
12368 result = NULL;
12369 goto exit;
12370 }
12371 start = trace + 1;
12372 }
12373 }
12374 break;
12375 }
12376exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012377 if (buffer)
12378 PyMem_FREE(buffer);
12379 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012380}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012381#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012382
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012383
Larry Hastings2f936352014-08-05 14:04:04 +100012384/*[clinic input]
12385os.urandom
12386
12387 size: Py_ssize_t
12388 /
12389
12390Return a bytes object containing random bytes suitable for cryptographic use.
12391[clinic start generated code]*/
12392
Larry Hastings2f936352014-08-05 14:04:04 +100012393static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012394os_urandom_impl(PyObject *module, Py_ssize_t size)
12395/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012396{
12397 PyObject *bytes;
12398 int result;
12399
Georg Brandl2fb477c2012-02-21 00:33:36 +010012400 if (size < 0)
12401 return PyErr_Format(PyExc_ValueError,
12402 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012403 bytes = PyBytes_FromStringAndSize(NULL, size);
12404 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012405 return NULL;
12406
Victor Stinnere66987e2016-09-06 16:33:52 -070012407 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012408 if (result == -1) {
12409 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012410 return NULL;
12411 }
Larry Hastings2f936352014-08-05 14:04:04 +100012412 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012413}
12414
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012415#ifdef HAVE_MEMFD_CREATE
12416/*[clinic input]
12417os.memfd_create
12418
12419 name: FSConverter
12420 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12421
12422[clinic start generated code]*/
12423
12424static PyObject *
12425os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12426/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12427{
12428 int fd;
12429 const char *bytes = PyBytes_AS_STRING(name);
12430 Py_BEGIN_ALLOW_THREADS
12431 fd = memfd_create(bytes, flags);
12432 Py_END_ALLOW_THREADS
12433 if (fd == -1) {
12434 return PyErr_SetFromErrno(PyExc_OSError);
12435 }
12436 return PyLong_FromLong(fd);
12437}
12438#endif
12439
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012440/* Terminal size querying */
12441
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012442PyDoc_STRVAR(TerminalSize_docstring,
12443 "A tuple of (columns, lines) for holding terminal window size");
12444
12445static PyStructSequence_Field TerminalSize_fields[] = {
12446 {"columns", "width of the terminal window in characters"},
12447 {"lines", "height of the terminal window in characters"},
12448 {NULL, NULL}
12449};
12450
12451static PyStructSequence_Desc TerminalSize_desc = {
12452 "os.terminal_size",
12453 TerminalSize_docstring,
12454 TerminalSize_fields,
12455 2,
12456};
12457
12458#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012459/*[clinic input]
12460os.get_terminal_size
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012461
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012462 fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
12463 /
12464
12465Return the size of the terminal window as (columns, lines).
12466
12467The optional argument fd (default standard output) specifies
12468which file descriptor should be queried.
12469
12470If the file descriptor is not connected to a terminal, an OSError
12471is thrown.
12472
12473This function will only be defined if an implementation is
12474available for this system.
12475
12476shutil.get_terminal_size is the high-level function which should
12477normally be used, os.get_terminal_size is the low-level implementation.
12478[clinic start generated code]*/
12479
12480static PyObject *
12481os_get_terminal_size_impl(PyObject *module, int fd)
12482/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012483{
12484 int columns, lines;
12485 PyObject *termsize;
12486
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012487 /* Under some conditions stdout may not be connected and
12488 * fileno(stdout) may point to an invalid file descriptor. For example
12489 * GUI apps don't have valid standard streams by default.
12490 *
12491 * If this happens, and the optional fd argument is not present,
12492 * the ioctl below will fail returning EBADF. This is what we want.
12493 */
12494
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012495#ifdef TERMSIZE_USE_IOCTL
12496 {
12497 struct winsize w;
12498 if (ioctl(fd, TIOCGWINSZ, &w))
12499 return PyErr_SetFromErrno(PyExc_OSError);
12500 columns = w.ws_col;
12501 lines = w.ws_row;
12502 }
12503#endif /* TERMSIZE_USE_IOCTL */
12504
12505#ifdef TERMSIZE_USE_CONIO
12506 {
12507 DWORD nhandle;
12508 HANDLE handle;
12509 CONSOLE_SCREEN_BUFFER_INFO csbi;
12510 switch (fd) {
12511 case 0: nhandle = STD_INPUT_HANDLE;
12512 break;
12513 case 1: nhandle = STD_OUTPUT_HANDLE;
12514 break;
12515 case 2: nhandle = STD_ERROR_HANDLE;
12516 break;
12517 default:
12518 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12519 }
12520 handle = GetStdHandle(nhandle);
12521 if (handle == NULL)
12522 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12523 if (handle == INVALID_HANDLE_VALUE)
12524 return PyErr_SetFromWindowsErr(0);
12525
12526 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12527 return PyErr_SetFromWindowsErr(0);
12528
12529 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12530 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12531 }
12532#endif /* TERMSIZE_USE_CONIO */
12533
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012534 PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080012535 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012536 if (termsize == NULL)
12537 return NULL;
12538 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12539 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12540 if (PyErr_Occurred()) {
12541 Py_DECREF(termsize);
12542 return NULL;
12543 }
12544 return termsize;
12545}
12546#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12547
Larry Hastings2f936352014-08-05 14:04:04 +100012548
12549/*[clinic input]
12550os.cpu_count
12551
Charles-François Natali80d62e62015-08-13 20:37:08 +010012552Return the number of CPUs in the system; return None if indeterminable.
12553
12554This number is not equivalent to the number of CPUs the current process can
12555use. The number of usable CPUs can be obtained with
12556``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012557[clinic start generated code]*/
12558
Larry Hastings2f936352014-08-05 14:04:04 +100012559static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012560os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012561/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012562{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012563 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012564#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010012565 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012566#elif defined(__hpux)
12567 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12568#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12569 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
pxinwr3405e052020-08-07 13:21:52 +080012570#elif defined(__VXWORKS__)
12571 ncpu = _Py_popcount32(vxCpuEnabledGet());
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012572#elif defined(__DragonFly__) || \
12573 defined(__OpenBSD__) || \
12574 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012575 defined(__NetBSD__) || \
12576 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012577 int mib[2];
12578 size_t len = sizeof(ncpu);
12579 mib[0] = CTL_HW;
12580 mib[1] = HW_NCPU;
12581 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12582 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012583#endif
12584 if (ncpu >= 1)
12585 return PyLong_FromLong(ncpu);
12586 else
12587 Py_RETURN_NONE;
12588}
12589
Victor Stinnerdaf45552013-08-28 00:53:59 +020012590
Larry Hastings2f936352014-08-05 14:04:04 +100012591/*[clinic input]
12592os.get_inheritable -> bool
12593
12594 fd: int
12595 /
12596
12597Get the close-on-exe flag of the specified file descriptor.
12598[clinic start generated code]*/
12599
Larry Hastings2f936352014-08-05 14:04:04 +100012600static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012601os_get_inheritable_impl(PyObject *module, int fd)
12602/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012603{
Steve Dower8fc89802015-04-12 00:26:27 -040012604 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012605 _Py_BEGIN_SUPPRESS_IPH
12606 return_value = _Py_get_inheritable(fd);
12607 _Py_END_SUPPRESS_IPH
12608 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012609}
12610
12611
12612/*[clinic input]
12613os.set_inheritable
12614 fd: int
12615 inheritable: int
12616 /
12617
12618Set the inheritable flag of the specified file descriptor.
12619[clinic start generated code]*/
12620
Larry Hastings2f936352014-08-05 14:04:04 +100012621static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012622os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12623/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012624{
Steve Dower8fc89802015-04-12 00:26:27 -040012625 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012626
Steve Dower8fc89802015-04-12 00:26:27 -040012627 _Py_BEGIN_SUPPRESS_IPH
12628 result = _Py_set_inheritable(fd, inheritable, NULL);
12629 _Py_END_SUPPRESS_IPH
12630 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012631 return NULL;
12632 Py_RETURN_NONE;
12633}
12634
12635
12636#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012637/*[clinic input]
12638os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012639 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012640 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012641
Larry Hastings2f936352014-08-05 14:04:04 +100012642Get the close-on-exe flag of the specified file descriptor.
12643[clinic start generated code]*/
12644
Larry Hastings2f936352014-08-05 14:04:04 +100012645static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012646os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012647/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012648{
12649 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012650
12651 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12652 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012653 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012654 }
12655
Larry Hastings2f936352014-08-05 14:04:04 +100012656 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012657}
12658
Victor Stinnerdaf45552013-08-28 00:53:59 +020012659
Larry Hastings2f936352014-08-05 14:04:04 +100012660/*[clinic input]
12661os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012662 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012663 inheritable: bool
12664 /
12665
12666Set the inheritable flag of the specified handle.
12667[clinic start generated code]*/
12668
Larry Hastings2f936352014-08-05 14:04:04 +100012669static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012670os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012671 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012672/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012673{
12674 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012675 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12676 PyErr_SetFromWindowsErr(0);
12677 return NULL;
12678 }
12679 Py_RETURN_NONE;
12680}
Larry Hastings2f936352014-08-05 14:04:04 +100012681#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012682
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012683#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012684/*[clinic input]
12685os.get_blocking -> bool
12686 fd: int
12687 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012688
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012689Get the blocking mode of the file descriptor.
12690
12691Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12692[clinic start generated code]*/
12693
12694static int
12695os_get_blocking_impl(PyObject *module, int fd)
12696/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012697{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012698 int blocking;
12699
Steve Dower8fc89802015-04-12 00:26:27 -040012700 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012701 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012702 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012703 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012704}
12705
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012706/*[clinic input]
12707os.set_blocking
12708 fd: int
12709 blocking: bool(accept={int})
12710 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012711
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012712Set the blocking mode of the specified file descriptor.
12713
12714Set the O_NONBLOCK flag if blocking is False,
12715clear the O_NONBLOCK flag otherwise.
12716[clinic start generated code]*/
12717
12718static PyObject *
12719os_set_blocking_impl(PyObject *module, int fd, int blocking)
12720/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012721{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012722 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012723
Steve Dower8fc89802015-04-12 00:26:27 -040012724 _Py_BEGIN_SUPPRESS_IPH
12725 result = _Py_set_blocking(fd, blocking);
12726 _Py_END_SUPPRESS_IPH
12727 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012728 return NULL;
12729 Py_RETURN_NONE;
12730}
12731#endif /* !MS_WINDOWS */
12732
12733
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012734/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080012735class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012736[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080012737/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012738
12739typedef struct {
12740 PyObject_HEAD
12741 PyObject *name;
12742 PyObject *path;
12743 PyObject *stat;
12744 PyObject *lstat;
12745#ifdef MS_WINDOWS
12746 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012747 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012748 int got_file_index;
12749#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012750#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012751 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012752#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012753 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012754 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012755#endif
12756} DirEntry;
12757
Eddie Elizondob3966632019-11-05 07:16:14 -080012758static PyObject *
12759_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
12760{
12761 PyErr_Format(PyExc_TypeError,
12762 "cannot create '%.100s' instances", _PyType_Name(type));
12763 return NULL;
12764}
12765
Victor Stinner6036e442015-03-08 01:58:04 +010012766static void
12767DirEntry_dealloc(DirEntry *entry)
12768{
Eddie Elizondob3966632019-11-05 07:16:14 -080012769 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010012770 Py_XDECREF(entry->name);
12771 Py_XDECREF(entry->path);
12772 Py_XDECREF(entry->stat);
12773 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080012774 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
12775 free_func(entry);
12776 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010012777}
12778
12779/* Forward reference */
12780static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012781DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
12782 int follow_symlinks, unsigned short mode_bits);
Victor Stinner6036e442015-03-08 01:58:04 +010012783
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012784/*[clinic input]
12785os.DirEntry.is_symlink -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020012786 defining_class: defining_class
12787 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012788
12789Return True if the entry is a symbolic link; cached per entry.
12790[clinic start generated code]*/
12791
Victor Stinner6036e442015-03-08 01:58:04 +010012792static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012793os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
12794/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012795{
12796#ifdef MS_WINDOWS
12797 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012798#elif defined(HAVE_DIRENT_D_TYPE)
12799 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012800 if (self->d_type != DT_UNKNOWN)
12801 return self->d_type == DT_LNK;
12802 else
Victor Stinner97f33c32020-05-14 18:05:58 +020012803 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012804#else
12805 /* POSIX without d_type */
Victor Stinner97f33c32020-05-14 18:05:58 +020012806 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012807#endif
12808}
12809
12810static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020012811DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
Victor Stinner6036e442015-03-08 01:58:04 +010012812{
12813 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012814 STRUCT_STAT st;
12815 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012816
12817#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012818 if (!PyUnicode_FSDecoder(self->path, &ub))
12819 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030012820#if USE_UNICODE_WCHAR_CACHE
12821_Py_COMP_DIAG_PUSH
12822_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012823 const wchar_t *path = PyUnicode_AsUnicode(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030012824_Py_COMP_DIAG_POP
12825#else /* USE_UNICODE_WCHAR_CACHE */
12826 wchar_t *path = PyUnicode_AsWideCharString(ub, NULL);
12827 Py_DECREF(ub);
12828#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010012829#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012830 if (!PyUnicode_FSConverter(self->path, &ub))
12831 return NULL;
12832 const char *path = PyBytes_AS_STRING(ub);
12833 if (self->dir_fd != DEFAULT_DIR_FD) {
12834#ifdef HAVE_FSTATAT
12835 result = fstatat(self->dir_fd, path, &st,
12836 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12837#else
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030012838 Py_DECREF(ub);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012839 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12840 return NULL;
12841#endif /* HAVE_FSTATAT */
12842 }
12843 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012844#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012845 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012846 if (follow_symlinks)
12847 result = STAT(path, &st);
12848 else
12849 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012850 }
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030012851#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE
12852 PyMem_Free(path);
12853#else /* USE_UNICODE_WCHAR_CACHE */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012854 Py_DECREF(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030012855#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010012856
12857 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012858 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012859
Victor Stinner97f33c32020-05-14 18:05:58 +020012860 return _pystat_fromstructstat(module, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010012861}
12862
12863static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020012864DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
Victor Stinner6036e442015-03-08 01:58:04 +010012865{
12866 if (!self->lstat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020012867 PyObject *module = PyType_GetModule(defining_class);
Victor Stinner6036e442015-03-08 01:58:04 +010012868#ifdef MS_WINDOWS
Victor Stinner97f33c32020-05-14 18:05:58 +020012869 self->lstat = _pystat_fromstructstat(module, &self->win32_lstat);
Victor Stinner6036e442015-03-08 01:58:04 +010012870#else /* POSIX */
Victor Stinner97f33c32020-05-14 18:05:58 +020012871 self->lstat = DirEntry_fetch_stat(module, self, 0);
Victor Stinner6036e442015-03-08 01:58:04 +010012872#endif
12873 }
12874 Py_XINCREF(self->lstat);
12875 return self->lstat;
12876}
12877
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012878/*[clinic input]
12879os.DirEntry.stat
Victor Stinner97f33c32020-05-14 18:05:58 +020012880 defining_class: defining_class
12881 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012882 *
12883 follow_symlinks: bool = True
12884
12885Return stat_result object for the entry; cached per entry.
12886[clinic start generated code]*/
12887
Victor Stinner6036e442015-03-08 01:58:04 +010012888static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020012889os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
12890 int follow_symlinks)
12891/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012892{
Victor Stinner97f33c32020-05-14 18:05:58 +020012893 if (!follow_symlinks) {
12894 return DirEntry_get_lstat(defining_class, self);
12895 }
Victor Stinner6036e442015-03-08 01:58:04 +010012896
12897 if (!self->stat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020012898 int result = os_DirEntry_is_symlink_impl(self, defining_class);
12899 if (result == -1) {
Victor Stinner6036e442015-03-08 01:58:04 +010012900 return NULL;
Victor Stinner97f33c32020-05-14 18:05:58 +020012901 }
12902 if (result) {
12903 PyObject *module = PyType_GetModule(defining_class);
12904 self->stat = DirEntry_fetch_stat(module, self, 1);
12905 }
12906 else {
12907 self->stat = DirEntry_get_lstat(defining_class, self);
12908 }
Victor Stinner6036e442015-03-08 01:58:04 +010012909 }
12910
12911 Py_XINCREF(self->stat);
12912 return self->stat;
12913}
12914
Victor Stinner6036e442015-03-08 01:58:04 +010012915/* Set exception and return -1 on error, 0 for False, 1 for True */
12916static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012917DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
12918 int follow_symlinks, unsigned short mode_bits)
Victor Stinner6036e442015-03-08 01:58:04 +010012919{
12920 PyObject *stat = NULL;
12921 PyObject *st_mode = NULL;
12922 long mode;
12923 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012924#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012925 int is_symlink;
12926 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012927#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012928#ifdef MS_WINDOWS
12929 unsigned long dir_bits;
12930#endif
12931
12932#ifdef MS_WINDOWS
12933 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12934 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012935#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012936 is_symlink = self->d_type == DT_LNK;
12937 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12938#endif
12939
Victor Stinner35a97c02015-03-08 02:59:09 +010012940#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012941 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012942#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020012943 stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012944 if (!stat) {
12945 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12946 /* If file doesn't exist (anymore), then return False
12947 (i.e., say it's not a file/directory) */
12948 PyErr_Clear();
12949 return 0;
12950 }
12951 goto error;
12952 }
Victor Stinner97f33c32020-05-14 18:05:58 +020012953 _posixstate* state = get_posix_state(PyType_GetModule(defining_class));
12954 st_mode = PyObject_GetAttr(stat, state->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012955 if (!st_mode)
12956 goto error;
12957
12958 mode = PyLong_AsLong(st_mode);
12959 if (mode == -1 && PyErr_Occurred())
12960 goto error;
12961 Py_CLEAR(st_mode);
12962 Py_CLEAR(stat);
12963 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012964#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012965 }
12966 else if (is_symlink) {
12967 assert(mode_bits != S_IFLNK);
12968 result = 0;
12969 }
12970 else {
12971 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12972#ifdef MS_WINDOWS
12973 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12974 if (mode_bits == S_IFDIR)
12975 result = dir_bits != 0;
12976 else
12977 result = dir_bits == 0;
12978#else /* POSIX */
12979 if (mode_bits == S_IFDIR)
12980 result = self->d_type == DT_DIR;
12981 else
12982 result = self->d_type == DT_REG;
12983#endif
12984 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012985#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012986
12987 return result;
12988
12989error:
12990 Py_XDECREF(st_mode);
12991 Py_XDECREF(stat);
12992 return -1;
12993}
12994
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012995/*[clinic input]
12996os.DirEntry.is_dir -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020012997 defining_class: defining_class
12998 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012999 *
13000 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010013001
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013002Return True if the entry is a directory; cached per entry.
13003[clinic start generated code]*/
13004
13005static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013006os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
13007 int follow_symlinks)
13008/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013009{
Victor Stinner97f33c32020-05-14 18:05:58 +020013010 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010013011}
13012
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013013/*[clinic input]
13014os.DirEntry.is_file -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013015 defining_class: defining_class
13016 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013017 *
13018 follow_symlinks: bool = True
13019
13020Return True if the entry is a file; cached per entry.
13021[clinic start generated code]*/
13022
13023static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013024os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
13025 int follow_symlinks)
13026/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013027{
Victor Stinner97f33c32020-05-14 18:05:58 +020013028 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010013029}
13030
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013031/*[clinic input]
13032os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010013033
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013034Return inode of the entry; cached per entry.
13035[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013036
13037static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013038os_DirEntry_inode_impl(DirEntry *self)
13039/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013040{
13041#ifdef MS_WINDOWS
13042 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013043 PyObject *unicode;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013044 STRUCT_STAT stat;
13045 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010013046
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013047 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010013048 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013049#if USE_UNICODE_WCHAR_CACHE
13050_Py_COMP_DIAG_PUSH
13051_Py_COMP_DIAG_IGNORE_DEPR_DECLS
13052 const wchar_t *path = PyUnicode_AsUnicode(unicode);
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013053 result = LSTAT(path, &stat);
13054 Py_DECREF(unicode);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013055_Py_COMP_DIAG_POP
13056#else /* USE_UNICODE_WCHAR_CACHE */
13057 wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL);
13058 Py_DECREF(unicode);
13059 result = LSTAT(path, &stat);
13060 PyMem_Free(path);
13061#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013062
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013063 if (result != 0)
13064 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013065
13066 self->win32_file_index = stat.st_ino;
13067 self->got_file_index = 1;
13068 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010013069 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
13070 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010013071#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020013072 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
13073 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010013074#endif
13075}
13076
13077static PyObject *
13078DirEntry_repr(DirEntry *self)
13079{
13080 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13081}
13082
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013083/*[clinic input]
13084os.DirEntry.__fspath__
13085
13086Returns the path for the entry.
13087[clinic start generated code]*/
13088
Brett Cannon96881cd2016-06-10 14:37:21 -070013089static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013090os_DirEntry___fspath___impl(DirEntry *self)
13091/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070013092{
13093 Py_INCREF(self->path);
13094 return self->path;
13095}
13096
Victor Stinner6036e442015-03-08 01:58:04 +010013097static PyMemberDef DirEntry_members[] = {
13098 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13099 "the entry's base filename, relative to scandir() \"path\" argument"},
13100 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13101 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13102 {NULL}
13103};
13104
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013105#include "clinic/posixmodule.c.h"
13106
Victor Stinner6036e442015-03-08 01:58:04 +010013107static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013108 OS_DIRENTRY_IS_DIR_METHODDEF
13109 OS_DIRENTRY_IS_FILE_METHODDEF
13110 OS_DIRENTRY_IS_SYMLINK_METHODDEF
13111 OS_DIRENTRY_STAT_METHODDEF
13112 OS_DIRENTRY_INODE_METHODDEF
13113 OS_DIRENTRY___FSPATH___METHODDEF
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013114 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
13115 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Victor Stinner6036e442015-03-08 01:58:04 +010013116 {NULL}
13117};
13118
Eddie Elizondob3966632019-11-05 07:16:14 -080013119static PyType_Slot DirEntryType_slots[] = {
13120 {Py_tp_new, _disabled_new},
13121 {Py_tp_dealloc, DirEntry_dealloc},
13122 {Py_tp_repr, DirEntry_repr},
13123 {Py_tp_methods, DirEntry_methods},
13124 {Py_tp_members, DirEntry_members},
13125 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010013126};
13127
Eddie Elizondob3966632019-11-05 07:16:14 -080013128static PyType_Spec DirEntryType_spec = {
13129 MODNAME ".DirEntry",
13130 sizeof(DirEntry),
13131 0,
13132 Py_TPFLAGS_DEFAULT,
13133 DirEntryType_slots
13134};
13135
13136
Victor Stinner6036e442015-03-08 01:58:04 +010013137#ifdef MS_WINDOWS
13138
13139static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013140join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010013141{
13142 Py_ssize_t path_len;
13143 Py_ssize_t size;
13144 wchar_t *result;
13145 wchar_t ch;
13146
13147 if (!path_wide) { /* Default arg: "." */
13148 path_wide = L".";
13149 path_len = 1;
13150 }
13151 else {
13152 path_len = wcslen(path_wide);
13153 }
13154
13155 /* The +1's are for the path separator and the NUL */
13156 size = path_len + 1 + wcslen(filename) + 1;
13157 result = PyMem_New(wchar_t, size);
13158 if (!result) {
13159 PyErr_NoMemory();
13160 return NULL;
13161 }
13162 wcscpy(result, path_wide);
13163 if (path_len > 0) {
13164 ch = result[path_len - 1];
13165 if (ch != SEP && ch != ALTSEP && ch != L':')
13166 result[path_len++] = SEP;
13167 wcscpy(result + path_len, filename);
13168 }
13169 return result;
13170}
13171
13172static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013173DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
Victor Stinner6036e442015-03-08 01:58:04 +010013174{
13175 DirEntry *entry;
13176 BY_HANDLE_FILE_INFORMATION file_info;
13177 ULONG reparse_tag;
13178 wchar_t *joined_path;
13179
Victor Stinner1c2fa782020-05-10 11:05:29 +020013180 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013181 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013182 if (!entry)
13183 return NULL;
13184 entry->name = NULL;
13185 entry->path = NULL;
13186 entry->stat = NULL;
13187 entry->lstat = NULL;
13188 entry->got_file_index = 0;
13189
13190 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13191 if (!entry->name)
13192 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013193 if (path->narrow) {
13194 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13195 if (!entry->name)
13196 goto error;
13197 }
Victor Stinner6036e442015-03-08 01:58:04 +010013198
13199 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13200 if (!joined_path)
13201 goto error;
13202
13203 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13204 PyMem_Free(joined_path);
13205 if (!entry->path)
13206 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013207 if (path->narrow) {
13208 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13209 if (!entry->path)
13210 goto error;
13211 }
Victor Stinner6036e442015-03-08 01:58:04 +010013212
Steve Dowercc16be82016-09-08 10:35:16 -070013213 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013214 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13215
13216 return (PyObject *)entry;
13217
13218error:
13219 Py_DECREF(entry);
13220 return NULL;
13221}
13222
13223#else /* POSIX */
13224
13225static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013226join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013227{
13228 Py_ssize_t path_len;
13229 Py_ssize_t size;
13230 char *result;
13231
13232 if (!path_narrow) { /* Default arg: "." */
13233 path_narrow = ".";
13234 path_len = 1;
13235 }
13236 else {
13237 path_len = strlen(path_narrow);
13238 }
13239
13240 if (filename_len == -1)
13241 filename_len = strlen(filename);
13242
13243 /* The +1's are for the path separator and the NUL */
13244 size = path_len + 1 + filename_len + 1;
13245 result = PyMem_New(char, size);
13246 if (!result) {
13247 PyErr_NoMemory();
13248 return NULL;
13249 }
13250 strcpy(result, path_narrow);
13251 if (path_len > 0 && result[path_len - 1] != '/')
13252 result[path_len++] = '/';
13253 strcpy(result + path_len, filename);
13254 return result;
13255}
13256
13257static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013258DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13259 Py_ssize_t name_len, ino_t d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013260#ifdef HAVE_DIRENT_D_TYPE
13261 , unsigned char d_type
13262#endif
13263 )
Victor Stinner6036e442015-03-08 01:58:04 +010013264{
13265 DirEntry *entry;
13266 char *joined_path;
13267
Victor Stinner1c2fa782020-05-10 11:05:29 +020013268 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013269 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013270 if (!entry)
13271 return NULL;
13272 entry->name = NULL;
13273 entry->path = NULL;
13274 entry->stat = NULL;
13275 entry->lstat = NULL;
13276
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013277 if (path->fd != -1) {
13278 entry->dir_fd = path->fd;
13279 joined_path = NULL;
13280 }
13281 else {
13282 entry->dir_fd = DEFAULT_DIR_FD;
13283 joined_path = join_path_filename(path->narrow, name, name_len);
13284 if (!joined_path)
13285 goto error;
13286 }
Victor Stinner6036e442015-03-08 01:58:04 +010013287
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013288 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013289 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013290 if (joined_path)
13291 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013292 }
13293 else {
13294 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013295 if (joined_path)
13296 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013297 }
13298 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013299 if (!entry->name)
13300 goto error;
13301
13302 if (path->fd != -1) {
13303 entry->path = entry->name;
13304 Py_INCREF(entry->path);
13305 }
13306 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013307 goto error;
13308
Victor Stinner35a97c02015-03-08 02:59:09 +010013309#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013310 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013311#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013312 entry->d_ino = d_ino;
13313
13314 return (PyObject *)entry;
13315
13316error:
13317 Py_XDECREF(entry);
13318 return NULL;
13319}
13320
13321#endif
13322
13323
13324typedef struct {
13325 PyObject_HEAD
13326 path_t path;
13327#ifdef MS_WINDOWS
13328 HANDLE handle;
13329 WIN32_FIND_DATAW file_data;
13330 int first_time;
13331#else /* POSIX */
13332 DIR *dirp;
13333#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013334#ifdef HAVE_FDOPENDIR
13335 int fd;
13336#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013337} ScandirIterator;
13338
13339#ifdef MS_WINDOWS
13340
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013341static int
13342ScandirIterator_is_closed(ScandirIterator *iterator)
13343{
13344 return iterator->handle == INVALID_HANDLE_VALUE;
13345}
13346
Victor Stinner6036e442015-03-08 01:58:04 +010013347static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013348ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013349{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013350 HANDLE handle = iterator->handle;
13351
13352 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013353 return;
13354
Victor Stinner6036e442015-03-08 01:58:04 +010013355 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013356 Py_BEGIN_ALLOW_THREADS
13357 FindClose(handle);
13358 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013359}
13360
13361static PyObject *
13362ScandirIterator_iternext(ScandirIterator *iterator)
13363{
13364 WIN32_FIND_DATAW *file_data = &iterator->file_data;
13365 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013366 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013367
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013368 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013369 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013370 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013371
13372 while (1) {
13373 if (!iterator->first_time) {
13374 Py_BEGIN_ALLOW_THREADS
13375 success = FindNextFileW(iterator->handle, file_data);
13376 Py_END_ALLOW_THREADS
13377 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013378 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013379 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013380 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013381 break;
13382 }
13383 }
13384 iterator->first_time = 0;
13385
13386 /* Skip over . and .. */
13387 if (wcscmp(file_data->cFileName, L".") != 0 &&
Victor Stinner1c2fa782020-05-10 11:05:29 +020013388 wcscmp(file_data->cFileName, L"..") != 0)
13389 {
13390 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13391 entry = DirEntry_from_find_data(module, &iterator->path, file_data);
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013392 if (!entry)
13393 break;
13394 return entry;
13395 }
Victor Stinner6036e442015-03-08 01:58:04 +010013396
13397 /* Loop till we get a non-dot directory or finish iterating */
13398 }
13399
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013400 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013401 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013402 return NULL;
13403}
13404
13405#else /* POSIX */
13406
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013407static int
13408ScandirIterator_is_closed(ScandirIterator *iterator)
13409{
13410 return !iterator->dirp;
13411}
13412
Victor Stinner6036e442015-03-08 01:58:04 +010013413static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013414ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013415{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013416 DIR *dirp = iterator->dirp;
13417
13418 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013419 return;
13420
Victor Stinner6036e442015-03-08 01:58:04 +010013421 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013422 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013423#ifdef HAVE_FDOPENDIR
13424 if (iterator->path.fd != -1)
13425 rewinddir(dirp);
13426#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013427 closedir(dirp);
13428 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013429 return;
13430}
13431
13432static PyObject *
13433ScandirIterator_iternext(ScandirIterator *iterator)
13434{
13435 struct dirent *direntp;
13436 Py_ssize_t name_len;
13437 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013438 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013439
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013440 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013441 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013442 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013443
13444 while (1) {
13445 errno = 0;
13446 Py_BEGIN_ALLOW_THREADS
13447 direntp = readdir(iterator->dirp);
13448 Py_END_ALLOW_THREADS
13449
13450 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013451 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013452 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013453 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013454 break;
13455 }
13456
13457 /* Skip over . and .. */
13458 name_len = NAMLEN(direntp);
13459 is_dot = direntp->d_name[0] == '.' &&
13460 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
13461 if (!is_dot) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020013462 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13463 entry = DirEntry_from_posix_info(module,
13464 &iterator->path, direntp->d_name,
13465 name_len, direntp->d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013466#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner1c2fa782020-05-10 11:05:29 +020013467 , direntp->d_type
Victor Stinner35a97c02015-03-08 02:59:09 +010013468#endif
13469 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013470 if (!entry)
13471 break;
13472 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013473 }
13474
13475 /* Loop till we get a non-dot directory or finish iterating */
13476 }
13477
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013478 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013479 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013480 return NULL;
13481}
13482
13483#endif
13484
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013485static PyObject *
13486ScandirIterator_close(ScandirIterator *self, PyObject *args)
13487{
13488 ScandirIterator_closedir(self);
13489 Py_RETURN_NONE;
13490}
13491
13492static PyObject *
13493ScandirIterator_enter(PyObject *self, PyObject *args)
13494{
13495 Py_INCREF(self);
13496 return self;
13497}
13498
13499static PyObject *
13500ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13501{
13502 ScandirIterator_closedir(self);
13503 Py_RETURN_NONE;
13504}
13505
Victor Stinner6036e442015-03-08 01:58:04 +010013506static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013507ScandirIterator_finalize(ScandirIterator *iterator)
13508{
13509 PyObject *error_type, *error_value, *error_traceback;
13510
13511 /* Save the current exception, if any. */
13512 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13513
13514 if (!ScandirIterator_is_closed(iterator)) {
13515 ScandirIterator_closedir(iterator);
13516
13517 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13518 "unclosed scandir iterator %R", iterator)) {
13519 /* Spurious errors can appear at shutdown */
13520 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13521 PyErr_WriteUnraisable((PyObject *) iterator);
13522 }
13523 }
13524 }
13525
Victor Stinner7bfa4092016-03-23 00:43:54 +010013526 path_cleanup(&iterator->path);
13527
13528 /* Restore the saved exception. */
13529 PyErr_Restore(error_type, error_value, error_traceback);
13530}
13531
13532static void
Victor Stinner6036e442015-03-08 01:58:04 +010013533ScandirIterator_dealloc(ScandirIterator *iterator)
13534{
Eddie Elizondob3966632019-11-05 07:16:14 -080013535 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010013536 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13537 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013538
Eddie Elizondob3966632019-11-05 07:16:14 -080013539 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13540 free_func(iterator);
13541 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013542}
13543
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013544static PyMethodDef ScandirIterator_methods[] = {
13545 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13546 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13547 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13548 {NULL}
13549};
13550
Eddie Elizondob3966632019-11-05 07:16:14 -080013551static PyType_Slot ScandirIteratorType_slots[] = {
13552 {Py_tp_new, _disabled_new},
13553 {Py_tp_dealloc, ScandirIterator_dealloc},
13554 {Py_tp_finalize, ScandirIterator_finalize},
13555 {Py_tp_iter, PyObject_SelfIter},
13556 {Py_tp_iternext, ScandirIterator_iternext},
13557 {Py_tp_methods, ScandirIterator_methods},
13558 {0, 0},
13559};
13560
13561static PyType_Spec ScandirIteratorType_spec = {
13562 MODNAME ".ScandirIterator",
13563 sizeof(ScandirIterator),
13564 0,
Victor Stinner97f33c32020-05-14 18:05:58 +020013565 // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
13566 // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
Eddie Elizondob3966632019-11-05 07:16:14 -080013567 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
13568 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010013569};
13570
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013571/*[clinic input]
13572os.scandir
13573
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013574 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013575
13576Return an iterator of DirEntry objects for given path.
13577
BNMetricsb9427072018-11-02 15:20:19 +000013578path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013579is bytes, the names of yielded DirEntry objects will also be bytes; in
13580all other circumstances they will be str.
13581
13582If path is None, uses the path='.'.
13583[clinic start generated code]*/
13584
Victor Stinner6036e442015-03-08 01:58:04 +010013585static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013586os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013587/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013588{
13589 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013590#ifdef MS_WINDOWS
13591 wchar_t *path_strW;
13592#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013593 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013594#ifdef HAVE_FDOPENDIR
13595 int fd = -1;
13596#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013597#endif
13598
Steve Dower60419a72019-06-24 08:42:54 -070013599 if (PySys_Audit("os.scandir", "O",
13600 path->object ? path->object : Py_None) < 0) {
13601 return NULL;
13602 }
13603
Hai Shif707d942020-03-16 21:15:01 +080013604 PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013605 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010013606 if (!iterator)
13607 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013608
13609#ifdef MS_WINDOWS
13610 iterator->handle = INVALID_HANDLE_VALUE;
13611#else
13612 iterator->dirp = NULL;
13613#endif
13614
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013615 /* Move the ownership to iterator->path */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013616 memcpy(&iterator->path, path, sizeof(path_t));
13617 memset(path, 0, sizeof(path_t));
Victor Stinner6036e442015-03-08 01:58:04 +010013618
13619#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013620 iterator->first_time = 1;
13621
13622 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13623 if (!path_strW)
13624 goto error;
13625
13626 Py_BEGIN_ALLOW_THREADS
13627 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13628 Py_END_ALLOW_THREADS
13629
13630 PyMem_Free(path_strW);
13631
13632 if (iterator->handle == INVALID_HANDLE_VALUE) {
13633 path_error(&iterator->path);
13634 goto error;
13635 }
13636#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013637 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013638#ifdef HAVE_FDOPENDIR
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013639 if (iterator->path.fd != -1) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013640 /* closedir() closes the FD, so we duplicate it */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013641 fd = _Py_dup(iterator->path.fd);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013642 if (fd == -1)
13643 goto error;
13644
13645 Py_BEGIN_ALLOW_THREADS
13646 iterator->dirp = fdopendir(fd);
13647 Py_END_ALLOW_THREADS
13648 }
13649 else
13650#endif
13651 {
13652 if (iterator->path.narrow)
13653 path_str = iterator->path.narrow;
13654 else
13655 path_str = ".";
13656
13657 Py_BEGIN_ALLOW_THREADS
13658 iterator->dirp = opendir(path_str);
13659 Py_END_ALLOW_THREADS
13660 }
Victor Stinner6036e442015-03-08 01:58:04 +010013661
13662 if (!iterator->dirp) {
13663 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013664#ifdef HAVE_FDOPENDIR
13665 if (fd != -1) {
13666 Py_BEGIN_ALLOW_THREADS
13667 close(fd);
13668 Py_END_ALLOW_THREADS
13669 }
13670#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013671 goto error;
13672 }
13673#endif
13674
13675 return (PyObject *)iterator;
13676
13677error:
13678 Py_DECREF(iterator);
13679 return NULL;
13680}
13681
Ethan Furman410ef8e2016-06-04 12:06:26 -070013682/*
13683 Return the file system path representation of the object.
13684
13685 If the object is str or bytes, then allow it to pass through with
13686 an incremented refcount. If the object defines __fspath__(), then
13687 return the result of that method. All other types raise a TypeError.
13688*/
13689PyObject *
13690PyOS_FSPath(PyObject *path)
13691{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013692 /* For error message reasons, this function is manually inlined in
13693 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013694 PyObject *func = NULL;
13695 PyObject *path_repr = NULL;
13696
13697 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13698 Py_INCREF(path);
13699 return path;
13700 }
13701
13702 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13703 if (NULL == func) {
13704 return PyErr_Format(PyExc_TypeError,
13705 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013706 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080013707 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070013708 }
13709
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013710 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013711 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013712 if (NULL == path_repr) {
13713 return NULL;
13714 }
13715
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013716 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13717 PyErr_Format(PyExc_TypeError,
13718 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080013719 "not %.200s", _PyType_Name(Py_TYPE(path)),
13720 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013721 Py_DECREF(path_repr);
13722 return NULL;
13723 }
13724
Ethan Furman410ef8e2016-06-04 12:06:26 -070013725 return path_repr;
13726}
13727
13728/*[clinic input]
13729os.fspath
13730
13731 path: object
13732
13733Return the file system path representation of the object.
13734
Brett Cannonb4f43e92016-06-09 14:32:08 -070013735If the object is str or bytes, then allow it to pass through as-is. If the
13736object defines __fspath__(), then return the result of that method. All other
13737types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013738[clinic start generated code]*/
13739
13740static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013741os_fspath_impl(PyObject *module, PyObject *path)
13742/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013743{
13744 return PyOS_FSPath(path);
13745}
Victor Stinner6036e442015-03-08 01:58:04 +010013746
Victor Stinner9b1f4742016-09-06 16:18:52 -070013747#ifdef HAVE_GETRANDOM_SYSCALL
13748/*[clinic input]
13749os.getrandom
13750
13751 size: Py_ssize_t
13752 flags: int=0
13753
13754Obtain a series of random bytes.
13755[clinic start generated code]*/
13756
13757static PyObject *
13758os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13759/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13760{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013761 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013762 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013763
13764 if (size < 0) {
13765 errno = EINVAL;
13766 return posix_error();
13767 }
13768
Victor Stinnerec2319c2016-09-20 23:00:59 +020013769 bytes = PyBytes_FromStringAndSize(NULL, size);
13770 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013771 PyErr_NoMemory();
13772 return NULL;
13773 }
13774
13775 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013776 n = syscall(SYS_getrandom,
13777 PyBytes_AS_STRING(bytes),
13778 PyBytes_GET_SIZE(bytes),
13779 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013780 if (n < 0 && errno == EINTR) {
13781 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013782 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013783 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013784
13785 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013786 continue;
13787 }
13788 break;
13789 }
13790
13791 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013792 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013793 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013794 }
13795
Victor Stinnerec2319c2016-09-20 23:00:59 +020013796 if (n != size) {
13797 _PyBytes_Resize(&bytes, n);
13798 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013799
13800 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013801
13802error:
13803 Py_DECREF(bytes);
13804 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013805}
13806#endif /* HAVE_GETRANDOM_SYSCALL */
13807
Steve Dower2438cdf2019-03-29 16:37:16 -070013808#ifdef MS_WINDOWS
13809/* bpo-36085: Helper functions for managing DLL search directories
13810 * on win32
13811 */
13812
13813typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13814typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13815
13816/*[clinic input]
13817os._add_dll_directory
13818
13819 path: path_t
13820
13821Add a path to the DLL search path.
13822
13823This search path is used when resolving dependencies for imported
13824extension modules (the module itself is resolved through sys.path),
13825and also by ctypes.
13826
13827Returns an opaque value that may be passed to os.remove_dll_directory
13828to remove this directory from the search path.
13829[clinic start generated code]*/
13830
13831static PyObject *
13832os__add_dll_directory_impl(PyObject *module, path_t *path)
13833/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13834{
13835 HMODULE hKernel32;
13836 PAddDllDirectory AddDllDirectory;
13837 DLL_DIRECTORY_COOKIE cookie = 0;
13838 DWORD err = 0;
13839
Saiyang Gou7514f4f2020-02-12 23:47:42 -080013840 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
13841 return NULL;
13842 }
13843
Steve Dower2438cdf2019-03-29 16:37:16 -070013844 /* For Windows 7, we have to load this. As this will be a fairly
13845 infrequent operation, just do it each time. Kernel32 is always
13846 loaded. */
13847 Py_BEGIN_ALLOW_THREADS
13848 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13849 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13850 hKernel32, "AddDllDirectory")) ||
13851 !(cookie = (*AddDllDirectory)(path->wide))) {
13852 err = GetLastError();
13853 }
13854 Py_END_ALLOW_THREADS
13855
13856 if (err) {
13857 return win32_error_object_err("add_dll_directory",
13858 path->object, err);
13859 }
13860
13861 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13862}
13863
13864/*[clinic input]
13865os._remove_dll_directory
13866
13867 cookie: object
13868
13869Removes a path from the DLL search path.
13870
13871The parameter is an opaque value that was returned from
13872os.add_dll_directory. You can only remove directories that you added
13873yourself.
13874[clinic start generated code]*/
13875
13876static PyObject *
13877os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13878/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13879{
13880 HMODULE hKernel32;
13881 PRemoveDllDirectory RemoveDllDirectory;
13882 DLL_DIRECTORY_COOKIE cookieValue;
13883 DWORD err = 0;
13884
13885 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13886 PyErr_SetString(PyExc_TypeError,
13887 "Provided cookie was not returned from os.add_dll_directory");
13888 return NULL;
13889 }
13890
13891 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13892 cookie, "DLL directory cookie");
13893
13894 /* For Windows 7, we have to load this. As this will be a fairly
13895 infrequent operation, just do it each time. Kernel32 is always
13896 loaded. */
13897 Py_BEGIN_ALLOW_THREADS
13898 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13899 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13900 hKernel32, "RemoveDllDirectory")) ||
13901 !(*RemoveDllDirectory)(cookieValue)) {
13902 err = GetLastError();
13903 }
13904 Py_END_ALLOW_THREADS
13905
13906 if (err) {
13907 return win32_error_object_err("remove_dll_directory",
13908 NULL, err);
13909 }
13910
13911 if (PyCapsule_SetName(cookie, NULL)) {
13912 return NULL;
13913 }
13914
13915 Py_RETURN_NONE;
13916}
13917
13918#endif
Larry Hastings31826802013-10-19 00:09:25 -070013919
Victor Stinner65a796e2020-04-01 18:49:29 +020013920
13921/* Only check if WIFEXITED is available: expect that it comes
13922 with WEXITSTATUS, WIFSIGNALED, etc.
13923
13924 os.waitstatus_to_exitcode() is implemented in C and not in Python, so
13925 subprocess can safely call it during late Python finalization without
13926 risking that used os attributes were set to None by _PyImport_Cleanup(). */
13927#if defined(WIFEXITED) || defined(MS_WINDOWS)
13928/*[clinic input]
13929os.waitstatus_to_exitcode
13930
Victor Stinner9bee32b2020-04-22 16:30:35 +020013931 status as status_obj: object
Victor Stinner65a796e2020-04-01 18:49:29 +020013932
13933Convert a wait status to an exit code.
13934
13935On Unix:
13936
13937* If WIFEXITED(status) is true, return WEXITSTATUS(status).
13938* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
13939* Otherwise, raise a ValueError.
13940
13941On Windows, return status shifted right by 8 bits.
13942
13943On Unix, if the process is being traced or if waitpid() was called with
13944WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
13945This function must not be called if WIFSTOPPED(status) is true.
13946[clinic start generated code]*/
13947
13948static PyObject *
Victor Stinner9bee32b2020-04-22 16:30:35 +020013949os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
13950/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
Victor Stinner65a796e2020-04-01 18:49:29 +020013951{
13952#ifndef MS_WINDOWS
Victor Stinner9bee32b2020-04-22 16:30:35 +020013953 int status = _PyLong_AsInt(status_obj);
13954 if (status == -1 && PyErr_Occurred()) {
13955 return NULL;
13956 }
13957
Victor Stinner65a796e2020-04-01 18:49:29 +020013958 WAIT_TYPE wait_status;
13959 WAIT_STATUS_INT(wait_status) = status;
13960 int exitcode;
13961 if (WIFEXITED(wait_status)) {
13962 exitcode = WEXITSTATUS(wait_status);
13963 /* Sanity check to provide warranty on the function behavior.
13964 It should not occur in practice */
13965 if (exitcode < 0) {
13966 PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
13967 return NULL;
13968 }
13969 }
13970 else if (WIFSIGNALED(wait_status)) {
13971 int signum = WTERMSIG(wait_status);
13972 /* Sanity check to provide warranty on the function behavior.
13973 It should not occurs in practice */
13974 if (signum <= 0) {
13975 PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
13976 return NULL;
13977 }
13978 exitcode = -signum;
13979 } else if (WIFSTOPPED(wait_status)) {
13980 /* Status only received if the process is being traced
13981 or if waitpid() was called with WUNTRACED option. */
13982 int signum = WSTOPSIG(wait_status);
13983 PyErr_Format(PyExc_ValueError,
13984 "process stopped by delivery of signal %i",
13985 signum);
13986 return NULL;
13987 }
13988 else {
13989 PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
13990 return NULL;
13991 }
13992 return PyLong_FromLong(exitcode);
13993#else
13994 /* Windows implementation: see os.waitpid() implementation
13995 which uses _cwait(). */
Victor Stinner9bee32b2020-04-22 16:30:35 +020013996 unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
13997 if (status == (unsigned long long)-1 && PyErr_Occurred()) {
13998 return NULL;
13999 }
14000
14001 unsigned long long exitcode = (status >> 8);
14002 /* ExitProcess() accepts an UINT type:
14003 reject exit code which doesn't fit in an UINT */
14004 if (exitcode > UINT_MAX) {
14005 PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
14006 return NULL;
14007 }
14008 return PyLong_FromUnsignedLong((unsigned long)exitcode);
Victor Stinner65a796e2020-04-01 18:49:29 +020014009#endif
14010}
14011#endif
14012
14013
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014014static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070014015
14016 OS_STAT_METHODDEF
14017 OS_ACCESS_METHODDEF
14018 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014019 OS_CHDIR_METHODDEF
14020 OS_CHFLAGS_METHODDEF
14021 OS_CHMOD_METHODDEF
14022 OS_FCHMOD_METHODDEF
14023 OS_LCHMOD_METHODDEF
14024 OS_CHOWN_METHODDEF
14025 OS_FCHOWN_METHODDEF
14026 OS_LCHOWN_METHODDEF
14027 OS_LCHFLAGS_METHODDEF
14028 OS_CHROOT_METHODDEF
14029 OS_CTERMID_METHODDEF
14030 OS_GETCWD_METHODDEF
14031 OS_GETCWDB_METHODDEF
14032 OS_LINK_METHODDEF
14033 OS_LISTDIR_METHODDEF
14034 OS_LSTAT_METHODDEF
14035 OS_MKDIR_METHODDEF
14036 OS_NICE_METHODDEF
14037 OS_GETPRIORITY_METHODDEF
14038 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014039 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030014040 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014041 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010014042 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014043 OS_RENAME_METHODDEF
14044 OS_REPLACE_METHODDEF
14045 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014046 OS_SYMLINK_METHODDEF
14047 OS_SYSTEM_METHODDEF
14048 OS_UMASK_METHODDEF
14049 OS_UNAME_METHODDEF
14050 OS_UNLINK_METHODDEF
14051 OS_REMOVE_METHODDEF
14052 OS_UTIME_METHODDEF
14053 OS_TIMES_METHODDEF
14054 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014055 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014056 OS_EXECV_METHODDEF
14057 OS_EXECVE_METHODDEF
14058 OS_SPAWNV_METHODDEF
14059 OS_SPAWNVE_METHODDEF
14060 OS_FORK1_METHODDEF
14061 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020014062 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014063 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14064 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14065 OS_SCHED_GETPARAM_METHODDEF
14066 OS_SCHED_GETSCHEDULER_METHODDEF
14067 OS_SCHED_RR_GET_INTERVAL_METHODDEF
14068 OS_SCHED_SETPARAM_METHODDEF
14069 OS_SCHED_SETSCHEDULER_METHODDEF
14070 OS_SCHED_YIELD_METHODDEF
14071 OS_SCHED_SETAFFINITY_METHODDEF
14072 OS_SCHED_GETAFFINITY_METHODDEF
14073 OS_OPENPTY_METHODDEF
14074 OS_FORKPTY_METHODDEF
14075 OS_GETEGID_METHODDEF
14076 OS_GETEUID_METHODDEF
14077 OS_GETGID_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014078 OS_GETGROUPLIST_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014079 OS_GETGROUPS_METHODDEF
14080 OS_GETPID_METHODDEF
14081 OS_GETPGRP_METHODDEF
14082 OS_GETPPID_METHODDEF
14083 OS_GETUID_METHODDEF
14084 OS_GETLOGIN_METHODDEF
14085 OS_KILL_METHODDEF
14086 OS_KILLPG_METHODDEF
14087 OS_PLOCK_METHODDEF
Steve Dowercc16be82016-09-08 10:35:16 -070014088 OS_STARTFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014089 OS_SETUID_METHODDEF
14090 OS_SETEUID_METHODDEF
14091 OS_SETREUID_METHODDEF
14092 OS_SETGID_METHODDEF
14093 OS_SETEGID_METHODDEF
14094 OS_SETREGID_METHODDEF
14095 OS_SETGROUPS_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014096 OS_INITGROUPS_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014097 OS_GETPGID_METHODDEF
14098 OS_SETPGRP_METHODDEF
14099 OS_WAIT_METHODDEF
14100 OS_WAIT3_METHODDEF
14101 OS_WAIT4_METHODDEF
14102 OS_WAITID_METHODDEF
14103 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080014104 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014105 OS_GETSID_METHODDEF
14106 OS_SETSID_METHODDEF
14107 OS_SETPGID_METHODDEF
14108 OS_TCGETPGRP_METHODDEF
14109 OS_TCSETPGRP_METHODDEF
14110 OS_OPEN_METHODDEF
14111 OS_CLOSE_METHODDEF
14112 OS_CLOSERANGE_METHODDEF
14113 OS_DEVICE_ENCODING_METHODDEF
14114 OS_DUP_METHODDEF
14115 OS_DUP2_METHODDEF
14116 OS_LOCKF_METHODDEF
14117 OS_LSEEK_METHODDEF
14118 OS_READ_METHODDEF
14119 OS_READV_METHODDEF
14120 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014121 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014122 OS_WRITE_METHODDEF
14123 OS_WRITEV_METHODDEF
14124 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014125 OS_PWRITEV_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014126 OS_SENDFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014127 OS_FSTAT_METHODDEF
14128 OS_ISATTY_METHODDEF
14129 OS_PIPE_METHODDEF
14130 OS_PIPE2_METHODDEF
14131 OS_MKFIFO_METHODDEF
14132 OS_MKNOD_METHODDEF
14133 OS_MAJOR_METHODDEF
14134 OS_MINOR_METHODDEF
14135 OS_MAKEDEV_METHODDEF
14136 OS_FTRUNCATE_METHODDEF
14137 OS_TRUNCATE_METHODDEF
14138 OS_POSIX_FALLOCATE_METHODDEF
14139 OS_POSIX_FADVISE_METHODDEF
14140 OS_PUTENV_METHODDEF
14141 OS_UNSETENV_METHODDEF
14142 OS_STRERROR_METHODDEF
14143 OS_FCHDIR_METHODDEF
14144 OS_FSYNC_METHODDEF
14145 OS_SYNC_METHODDEF
14146 OS_FDATASYNC_METHODDEF
14147 OS_WCOREDUMP_METHODDEF
14148 OS_WIFCONTINUED_METHODDEF
14149 OS_WIFSTOPPED_METHODDEF
14150 OS_WIFSIGNALED_METHODDEF
14151 OS_WIFEXITED_METHODDEF
14152 OS_WEXITSTATUS_METHODDEF
14153 OS_WTERMSIG_METHODDEF
14154 OS_WSTOPSIG_METHODDEF
14155 OS_FSTATVFS_METHODDEF
14156 OS_STATVFS_METHODDEF
14157 OS_CONFSTR_METHODDEF
14158 OS_SYSCONF_METHODDEF
14159 OS_FPATHCONF_METHODDEF
14160 OS_PATHCONF_METHODDEF
14161 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030014162 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014163 OS__GETDISKUSAGE_METHODDEF
14164 OS__GETFINALPATHNAME_METHODDEF
14165 OS__GETVOLUMEPATHNAME_METHODDEF
14166 OS_GETLOADAVG_METHODDEF
14167 OS_URANDOM_METHODDEF
14168 OS_SETRESUID_METHODDEF
14169 OS_SETRESGID_METHODDEF
14170 OS_GETRESUID_METHODDEF
14171 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000014172
Larry Hastings2f936352014-08-05 14:04:04 +100014173 OS_GETXATTR_METHODDEF
14174 OS_SETXATTR_METHODDEF
14175 OS_REMOVEXATTR_METHODDEF
14176 OS_LISTXATTR_METHODDEF
14177
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014178 OS_GET_TERMINAL_SIZE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014179 OS_CPU_COUNT_METHODDEF
14180 OS_GET_INHERITABLE_METHODDEF
14181 OS_SET_INHERITABLE_METHODDEF
14182 OS_GET_HANDLE_INHERITABLE_METHODDEF
14183 OS_SET_HANDLE_INHERITABLE_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014184 OS_GET_BLOCKING_METHODDEF
14185 OS_SET_BLOCKING_METHODDEF
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014186 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070014187 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070014188 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014189 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070014190 OS__ADD_DLL_DIRECTORY_METHODDEF
14191 OS__REMOVE_DLL_DIRECTORY_METHODDEF
Victor Stinner65a796e2020-04-01 18:49:29 +020014192 OS_WAITSTATUS_TO_EXITCODE_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014193 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014194};
14195
Barry Warsaw4a342091996-12-19 23:50:02 +000014196static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014197all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000014198{
Guido van Rossum94f6f721999-01-06 18:42:14 +000014199#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014200 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014201#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014202#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014203 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014204#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014205#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014206 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014207#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014208#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014209 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014210#endif
Fred Drakec9680921999-12-13 16:37:25 +000014211#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014212 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000014213#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014214#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014215 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014216#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014217#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014218 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014219#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014220#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014221 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014222#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014223#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014224 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014225#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014226#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014227 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014228#endif
14229#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014230 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014231#endif
14232#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014233 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014234#endif
14235#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014236 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014237#endif
14238#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014239 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014240#endif
14241#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014242 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014243#endif
14244#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014245 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014246#endif
14247#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014248 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014249#endif
14250#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014251 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014252#endif
14253#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014254 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014255#endif
14256#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014257 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014258#endif
14259#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014260 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014261#endif
14262#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014263 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014264#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014265#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014266 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014267#endif
14268#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014269 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014270#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014271#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014272 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014273#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014274#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014275 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014276#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014277#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014278#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014279 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014280#endif
14281#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014282 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014283#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014284#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014285#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014286 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014287#endif
14288#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014289 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014290#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014291#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014292 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014293#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014294#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014295 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014296#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014297#ifdef O_TMPFILE
14298 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14299#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014300#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014301 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014302#endif
14303#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014304 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014305#endif
14306#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014307 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014308#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014309#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014310 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014311#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014312#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014313 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014314#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014315
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014316
Jesus Cea94363612012-06-22 18:32:07 +020014317#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014318 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014319#endif
14320#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014321 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014322#endif
14323
Tim Peters5aa91602002-01-30 05:46:57 +000014324/* MS Windows */
14325#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014326 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014327 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014328#endif
14329#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000014330 /* Optimize for short life (keep in memory). */
14331 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014332 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014333#endif
14334#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000014335 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014336 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014337#endif
14338#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000014339 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014340 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014341#endif
14342#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014343 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014344 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014345#endif
14346
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014347/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014348#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014349 /* Send a SIGIO signal whenever input or output
14350 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014351 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014352#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014353#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014354 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014355 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014356#endif
14357#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000014358 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014359 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014360#endif
14361#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000014362 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014363 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014364#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014365#ifdef O_NOLINKS
14366 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014367 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014368#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014369#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014370 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014371 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014372#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000014373
Victor Stinner8c62be82010-05-06 00:08:46 +000014374 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014375#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014376 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014377#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014378#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014379 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014380#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014381#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014382 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014383#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014384#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014385 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014386#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014387#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014388 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014389#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014390#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014391 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014392#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014393#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014394 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014395#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014396#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014397 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014398#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014399#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014400 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014401#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014402#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014403 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014404#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014405#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014406 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014407#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014408#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014409 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014410#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014411#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014412 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014413#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014414#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014415 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014416#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014417#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014418 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014419#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014420#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014421 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014422#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014423#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014424 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014425#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014426
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000014427 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014428#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014429 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014430#endif /* ST_RDONLY */
14431#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014432 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014433#endif /* ST_NOSUID */
14434
doko@ubuntu.comca616a22013-12-08 15:23:07 +010014435 /* GNU extensions */
14436#ifdef ST_NODEV
14437 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
14438#endif /* ST_NODEV */
14439#ifdef ST_NOEXEC
14440 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
14441#endif /* ST_NOEXEC */
14442#ifdef ST_SYNCHRONOUS
14443 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
14444#endif /* ST_SYNCHRONOUS */
14445#ifdef ST_MANDLOCK
14446 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
14447#endif /* ST_MANDLOCK */
14448#ifdef ST_WRITE
14449 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
14450#endif /* ST_WRITE */
14451#ifdef ST_APPEND
14452 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
14453#endif /* ST_APPEND */
14454#ifdef ST_NOATIME
14455 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
14456#endif /* ST_NOATIME */
14457#ifdef ST_NODIRATIME
14458 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
14459#endif /* ST_NODIRATIME */
14460#ifdef ST_RELATIME
14461 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
14462#endif /* ST_RELATIME */
14463
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014464 /* FreeBSD sendfile() constants */
14465#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014466 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014467#endif
14468#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014469 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014470#endif
14471#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014472 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014473#endif
14474
Ross Lagerwall7807c352011-03-17 20:20:30 +020014475 /* constants for posix_fadvise */
14476#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014477 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014478#endif
14479#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014480 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014481#endif
14482#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014483 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014484#endif
14485#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014486 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014487#endif
14488#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014489 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014490#endif
14491#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014492 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014493#endif
14494
14495 /* constants for waitid */
14496#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014497 if (PyModule_AddIntMacro(m, P_PID)) return -1;
14498 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
14499 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080014500#ifdef P_PIDFD
14501 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
14502#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014503#endif
14504#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014505 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014506#endif
14507#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014508 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014509#endif
14510#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014511 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014512#endif
14513#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014514 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014515#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014516#ifdef CLD_KILLED
14517 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
14518#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014519#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014520 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014521#endif
14522#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014523 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014524#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014525#ifdef CLD_STOPPED
14526 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
14527#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014528#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014529 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014530#endif
14531
14532 /* constants for lockf */
14533#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014534 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014535#endif
14536#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014537 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014538#endif
14539#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014540 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014541#endif
14542#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014543 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014544#endif
14545
Pablo Galindo4defba32018-01-27 16:16:37 +000014546#ifdef RWF_DSYNC
14547 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14548#endif
14549#ifdef RWF_HIPRI
14550 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14551#endif
14552#ifdef RWF_SYNC
14553 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14554#endif
14555#ifdef RWF_NOWAIT
14556 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14557#endif
YoSTEALTH76ef2552020-05-27 15:32:22 -060014558#ifdef RWF_APPEND
14559 if (PyModule_AddIntConstant(m, "RWF_APPEND", RWF_APPEND)) return -1;
14560#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000014561
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014562/* constants for posix_spawn */
14563#ifdef HAVE_POSIX_SPAWN
14564 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14565 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14566 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14567#endif
14568
pxinwrf2d7ac72019-05-21 18:46:37 +080014569#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014570 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14571 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014572 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014573#endif
14574#ifdef HAVE_SPAWNV
14575 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014576 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014577#endif
14578
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014579#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014580#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014581 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014582#endif
14583#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014584 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014585#endif
14586#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014587 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014588#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014589#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014590 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014591#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014592#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014593 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014594#endif
14595#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014596 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014597#endif
14598#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014599 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014600#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014601#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014602 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014603#endif
14604#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014605 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014606#endif
14607#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014608 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014609#endif
14610#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014611 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014612#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014613#endif
14614
Benjamin Peterson9428d532011-09-14 11:45:52 -040014615#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014616 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
14617 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
14618 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040014619#endif
14620
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014621#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014622 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014623#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014624#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014625 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014626#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014627#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014628 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014629#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014630#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014631 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014632#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014633#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014634 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014635#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014636#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014637 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014638#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014639#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014640 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014641#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010014642#if HAVE_DECL_RTLD_MEMBER
14643 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
14644#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020014645
Victor Stinner9b1f4742016-09-06 16:18:52 -070014646#ifdef HAVE_GETRANDOM_SYSCALL
14647 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
14648 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
14649#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014650#ifdef HAVE_MEMFD_CREATE
14651 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
14652 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
14653#ifdef MFD_HUGETLB
14654 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014655#endif
14656#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014657 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014658#endif
14659#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014660 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014661#endif
14662#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014663 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014664#endif
14665#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014666 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014667#endif
14668#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014669 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014670#endif
14671#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014672 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014673#endif
14674#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014675 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014676#endif
14677#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014678 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014679#endif
14680#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014681 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014682#endif
14683#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014684 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014685#endif
14686#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014687 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014688#endif
14689#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014690 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014691#endif
14692#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014693 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014694#endif
14695#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014696 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
14697#endif
14698#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070014699
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014700#if defined(__APPLE__)
14701 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
14702#endif
14703
Steve Dower2438cdf2019-03-29 16:37:16 -070014704#ifdef MS_WINDOWS
14705 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
14706 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
14707 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
14708 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
14709 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
14710#endif
14711
Victor Stinner8c62be82010-05-06 00:08:46 +000014712 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000014713}
14714
14715
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014716static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014717
14718#ifdef HAVE_FACCESSAT
14719 "HAVE_FACCESSAT",
14720#endif
14721
14722#ifdef HAVE_FCHDIR
14723 "HAVE_FCHDIR",
14724#endif
14725
14726#ifdef HAVE_FCHMOD
14727 "HAVE_FCHMOD",
14728#endif
14729
14730#ifdef HAVE_FCHMODAT
14731 "HAVE_FCHMODAT",
14732#endif
14733
14734#ifdef HAVE_FCHOWN
14735 "HAVE_FCHOWN",
14736#endif
14737
Larry Hastings00964ed2013-08-12 13:49:30 -040014738#ifdef HAVE_FCHOWNAT
14739 "HAVE_FCHOWNAT",
14740#endif
14741
Larry Hastings9cf065c2012-06-22 16:30:09 -070014742#ifdef HAVE_FEXECVE
14743 "HAVE_FEXECVE",
14744#endif
14745
14746#ifdef HAVE_FDOPENDIR
14747 "HAVE_FDOPENDIR",
14748#endif
14749
Georg Brandl306336b2012-06-24 12:55:33 +020014750#ifdef HAVE_FPATHCONF
14751 "HAVE_FPATHCONF",
14752#endif
14753
Larry Hastings9cf065c2012-06-22 16:30:09 -070014754#ifdef HAVE_FSTATAT
14755 "HAVE_FSTATAT",
14756#endif
14757
14758#ifdef HAVE_FSTATVFS
14759 "HAVE_FSTATVFS",
14760#endif
14761
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014762#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014763 "HAVE_FTRUNCATE",
14764#endif
14765
Larry Hastings9cf065c2012-06-22 16:30:09 -070014766#ifdef HAVE_FUTIMENS
14767 "HAVE_FUTIMENS",
14768#endif
14769
14770#ifdef HAVE_FUTIMES
14771 "HAVE_FUTIMES",
14772#endif
14773
14774#ifdef HAVE_FUTIMESAT
14775 "HAVE_FUTIMESAT",
14776#endif
14777
14778#ifdef HAVE_LINKAT
14779 "HAVE_LINKAT",
14780#endif
14781
14782#ifdef HAVE_LCHFLAGS
14783 "HAVE_LCHFLAGS",
14784#endif
14785
14786#ifdef HAVE_LCHMOD
14787 "HAVE_LCHMOD",
14788#endif
14789
14790#ifdef HAVE_LCHOWN
14791 "HAVE_LCHOWN",
14792#endif
14793
14794#ifdef HAVE_LSTAT
14795 "HAVE_LSTAT",
14796#endif
14797
14798#ifdef HAVE_LUTIMES
14799 "HAVE_LUTIMES",
14800#endif
14801
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014802#ifdef HAVE_MEMFD_CREATE
14803 "HAVE_MEMFD_CREATE",
14804#endif
14805
Larry Hastings9cf065c2012-06-22 16:30:09 -070014806#ifdef HAVE_MKDIRAT
14807 "HAVE_MKDIRAT",
14808#endif
14809
14810#ifdef HAVE_MKFIFOAT
14811 "HAVE_MKFIFOAT",
14812#endif
14813
14814#ifdef HAVE_MKNODAT
14815 "HAVE_MKNODAT",
14816#endif
14817
14818#ifdef HAVE_OPENAT
14819 "HAVE_OPENAT",
14820#endif
14821
14822#ifdef HAVE_READLINKAT
14823 "HAVE_READLINKAT",
14824#endif
14825
14826#ifdef HAVE_RENAMEAT
14827 "HAVE_RENAMEAT",
14828#endif
14829
14830#ifdef HAVE_SYMLINKAT
14831 "HAVE_SYMLINKAT",
14832#endif
14833
14834#ifdef HAVE_UNLINKAT
14835 "HAVE_UNLINKAT",
14836#endif
14837
14838#ifdef HAVE_UTIMENSAT
14839 "HAVE_UTIMENSAT",
14840#endif
14841
14842#ifdef MS_WINDOWS
14843 "MS_WINDOWS",
14844#endif
14845
14846 NULL
14847};
14848
14849
Victor Stinner1c2fa782020-05-10 11:05:29 +020014850static int
14851posixmodule_exec(PyObject *m)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014852{
Victor Stinner97f33c32020-05-14 18:05:58 +020014853 _posixstate *state = get_posix_state(m);
Tim Peters5aa91602002-01-30 05:46:57 +000014854
Victor Stinner8c62be82010-05-06 00:08:46 +000014855 /* Initialize environ dictionary */
Victor Stinner97f33c32020-05-14 18:05:58 +020014856 PyObject *v = convertenviron();
Victor Stinner8c62be82010-05-06 00:08:46 +000014857 Py_XINCREF(v);
14858 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014859 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014860 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014861
Victor Stinner8c62be82010-05-06 00:08:46 +000014862 if (all_ins(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020014863 return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014864
Victor Stinner8c62be82010-05-06 00:08:46 +000014865 if (setup_confname_tables(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020014866 return -1;
Fred Drakebec628d1999-12-15 18:31:10 +000014867
Victor Stinner8c62be82010-05-06 00:08:46 +000014868 Py_INCREF(PyExc_OSError);
14869 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014870
Ross Lagerwall7807c352011-03-17 20:20:30 +020014871#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080014872 waitid_result_desc.name = MODNAME ".waitid_result";
14873 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
14874 if (WaitidResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014875 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014876 }
14877 Py_INCREF(WaitidResultType);
14878 PyModule_AddObject(m, "waitid_result", WaitidResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014879 state->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014880#endif
14881
Eddie Elizondob3966632019-11-05 07:16:14 -080014882 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
14883 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14884 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14885 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
14886 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
14887 if (StatResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014888 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014889 }
14890 Py_INCREF(StatResultType);
14891 PyModule_AddObject(m, "stat_result", StatResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014892 state->StatResultType = StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014893 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
14894 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014895
Eddie Elizondob3966632019-11-05 07:16:14 -080014896 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
14897 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
14898 if (StatVFSResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014899 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014900 }
14901 Py_INCREF(StatVFSResultType);
14902 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014903 state->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014904#ifdef NEED_TICKS_PER_SECOND
14905# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080014906 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014907# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080014908 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014909# else
Eddie Elizondob3966632019-11-05 07:16:14 -080014910 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014911# endif
14912#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014913
William Orr81574b82018-10-01 22:19:56 -070014914#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080014915 sched_param_desc.name = MODNAME ".sched_param";
14916 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
14917 if (SchedParamType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014918 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014919 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014920 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080014921 PyModule_AddObject(m, "sched_param", SchedParamType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014922 state->SchedParamType = SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014923 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014924#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014925
Eddie Elizondob3966632019-11-05 07:16:14 -080014926 /* initialize TerminalSize_info */
14927 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
14928 if (TerminalSizeType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014929 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014930 }
14931 Py_INCREF(TerminalSizeType);
14932 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014933 state->TerminalSizeType = TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014934
14935 /* initialize scandir types */
Victor Stinner1c2fa782020-05-10 11:05:29 +020014936 PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080014937 if (ScandirIteratorType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014938 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014939 }
Victor Stinner97f33c32020-05-14 18:05:58 +020014940 state->ScandirIteratorType = ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014941
Victor Stinner1c2fa782020-05-10 11:05:29 +020014942 PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080014943 if (DirEntryType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014944 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014945 }
14946 Py_INCREF(DirEntryType);
14947 PyModule_AddObject(m, "DirEntry", DirEntryType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014948 state->DirEntryType = DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014949
Larry Hastings605a62d2012-06-24 04:33:36 -070014950 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080014951 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014952 if (TimesResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014953 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014954 }
Eddie Elizondob3966632019-11-05 07:16:14 -080014955 Py_INCREF(TimesResultType);
14956 PyModule_AddObject(m, "times_result", TimesResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014957 state->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070014958
Eddie Elizondob3966632019-11-05 07:16:14 -080014959 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014960 if (UnameResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014961 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014962 }
Eddie Elizondob3966632019-11-05 07:16:14 -080014963 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014964 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014965 state->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070014966
Thomas Wouters477c8d52006-05-27 19:21:47 +000014967#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014968 /*
14969 * Step 2 of weak-linking support on Mac OS X.
14970 *
14971 * The code below removes functions that are not available on the
14972 * currently active platform.
14973 *
14974 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014975 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014976 * OSX 10.4.
14977 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014978#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014979 if (fstatvfs == NULL) {
14980 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014981 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014982 }
14983 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014984#endif /* HAVE_FSTATVFS */
14985
14986#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014987 if (statvfs == NULL) {
14988 if (PyObject_DelAttrString(m, "statvfs") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014989 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014990 }
14991 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014992#endif /* HAVE_STATVFS */
14993
14994# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014995 if (lchown == NULL) {
14996 if (PyObject_DelAttrString(m, "lchown") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014997 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014998 }
14999 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000015000#endif /* HAVE_LCHOWN */
15001
15002
15003#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010015004
Victor Stinner97f33c32020-05-14 18:05:58 +020015005 if ((state->billion = PyLong_FromLong(1000000000)) == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015006 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015007#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +020015008 state->struct_rusage = PyUnicode_InternFromString("struct_rusage");
15009 if (state->struct_rusage == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015010 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015011#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020015012 state->st_mode = PyUnicode_InternFromString("st_mode");
15013 if (state->st_mode == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015014 return -1;
Larry Hastings6fe20b32012-04-19 15:07:49 -070015015
Larry Hastings9cf065c2012-06-22 16:30:09 -070015016 /* suppress "function not used" warnings */
15017 {
15018 int ignored;
15019 fd_specified("", -1);
15020 follow_symlinks_specified("", 1);
15021 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
15022 dir_fd_converter(Py_None, &ignored);
15023 dir_fd_unavailable(Py_None, &ignored);
15024 }
15025
15026 /*
15027 * provide list of locally available functions
15028 * so os.py can populate support_* lists
15029 */
Victor Stinner97f33c32020-05-14 18:05:58 +020015030 PyObject *list = PyList_New(0);
15031 if (!list) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015032 return -1;
Victor Stinner97f33c32020-05-14 18:05:58 +020015033 }
15034 for (const char * const *trace = have_functions; *trace; trace++) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070015035 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
15036 if (!unicode)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015037 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015038 if (PyList_Append(list, unicode))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015039 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015040 Py_DECREF(unicode);
15041 }
15042 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040015043
Victor Stinner1c2fa782020-05-10 11:05:29 +020015044 return 0;
15045}
15046
15047
15048static PyModuleDef_Slot posixmodile_slots[] = {
15049 {Py_mod_exec, posixmodule_exec},
15050 {0, NULL}
15051};
15052
15053static struct PyModuleDef posixmodule = {
15054 PyModuleDef_HEAD_INIT,
15055 .m_name = MODNAME,
15056 .m_doc = posix__doc__,
15057 .m_size = sizeof(_posixstate),
15058 .m_methods = posix_methods,
15059 .m_slots = posixmodile_slots,
15060 .m_traverse = _posix_traverse,
15061 .m_clear = _posix_clear,
15062 .m_free = _posix_free,
15063};
15064
15065PyMODINIT_FUNC
15066INITFUNC(void)
15067{
15068 return PyModuleDef_Init(&posixmodule);
Guido van Rossumb6775db1994-08-01 11:34:53 +000015069}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015070
15071#ifdef __cplusplus
15072}
15073#endif