blob: 29aeca4169dd1717c66bc266d2018a2e52cdbba7 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02009 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Victor Stinnerd5d9e812019-05-13 12:35:37 +020028#ifdef MS_WINDOWS
29 /* include <windows.h> early to avoid conflict with pycore_condvar.h:
30
31 #define WIN32_LEAN_AND_MEAN
32 #include <windows.h>
33
34 FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */
35# include <windows.h>
36#endif
37
38#include "pycore_ceval.h" /* _PyEval_ReInitThreads() */
Victor Stinner01b63ec2019-06-19 00:48:09 +020039#include "pycore_import.h" /* _PyImport_ReInitLock() */
Victor Stinnerd5d9e812019-05-13 12:35:37 +020040#include "pycore_pystate.h" /* _PyRuntime */
Antoine Pitrou346cbd32017-05-27 17:50:54 +020041#include "pythread.h"
Victor Stinner6036e442015-03-08 01:58:04 +010042#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020043#ifndef MS_WINDOWS
Victor Stinnerd5d9e812019-05-13 12:35:37 +020044# include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010045#else
Victor Stinnerd5d9e812019-05-13 12:35:37 +020046# include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020047#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000048
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020049/* On android API level 21, 'AT_EACCESS' is not declared although
50 * HAVE_FACCESSAT is defined. */
51#ifdef __ANDROID__
52#undef HAVE_FACCESSAT
53#endif
54
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000055#include <stdio.h> /* needed for ctermid() */
56
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000057#ifdef __cplusplus
58extern "C" {
59#endif
60
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000061PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000062"This module provides access to operating system functionality that is\n\
63standardized by the C Standard and the POSIX standard (a thinly\n\
64disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000065corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000067
Ross Lagerwall4d076da2011-03-18 06:56:53 +020068#ifdef HAVE_SYS_UIO_H
69#include <sys/uio.h>
70#endif
71
Christian Heimes75b96182017-09-05 15:53:09 +020072#ifdef HAVE_SYS_SYSMACROS_H
73/* GNU C Library: major(), minor(), makedev() */
74#include <sys/sysmacros.h>
75#endif
76
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000078#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000079#endif /* HAVE_SYS_TYPES_H */
80
81#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000082#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000083#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000084
Guido van Rossum36bc6801995-06-14 22:54:23 +000085#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000086#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000087#endif
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080088#ifdef HAVE_LINUX_WAIT_H
89#include <linux/wait.h> // For P_PIDFD
90#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000091
Thomas Wouters0e3f5912006-08-11 14:57:12 +000092#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000093#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000094#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000095
Guido van Rossumb6775db1994-08-01 11:34:53 +000096#ifdef HAVE_FCNTL_H
97#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000098#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000099
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000100#ifdef HAVE_GRP_H
101#include <grp.h>
102#endif
103
Barry Warsaw5676bd12003-01-07 20:57:09 +0000104#ifdef HAVE_SYSEXITS_H
105#include <sysexits.h>
106#endif /* HAVE_SYSEXITS_H */
107
Anthony Baxter8a560de2004-10-13 15:30:56 +0000108#ifdef HAVE_SYS_LOADAVG_H
109#include <sys/loadavg.h>
110#endif
111
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000112#ifdef HAVE_SYS_SENDFILE_H
113#include <sys/sendfile.h>
114#endif
115
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200116#if defined(__APPLE__)
117#include <copyfile.h>
118#endif
119
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500120#ifdef HAVE_SCHED_H
121#include <sched.h>
122#endif
123
Pablo Galindoaac4d032019-05-31 19:39:47 +0100124#ifdef HAVE_COPY_FILE_RANGE
125#include <unistd.h>
126#endif
127
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500128#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500129#undef HAVE_SCHED_SETAFFINITY
130#endif
131
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200132#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400133#define USE_XATTRS
134#endif
135
136#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400137#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400138#endif
139
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000140#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
141#ifdef HAVE_SYS_SOCKET_H
142#include <sys/socket.h>
143#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000144#endif
145
Victor Stinner8b905bd2011-10-25 13:34:04 +0200146#ifdef HAVE_DLFCN_H
147#include <dlfcn.h>
148#endif
149
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200150#ifdef __hpux
151#include <sys/mpctl.h>
152#endif
153
154#if defined(__DragonFly__) || \
155 defined(__OpenBSD__) || \
156 defined(__FreeBSD__) || \
157 defined(__NetBSD__) || \
158 defined(__APPLE__)
159#include <sys/sysctl.h>
160#endif
161
Victor Stinner9b1f4742016-09-06 16:18:52 -0700162#ifdef HAVE_LINUX_RANDOM_H
163# include <linux/random.h>
164#endif
165#ifdef HAVE_GETRANDOM_SYSCALL
166# include <sys/syscall.h>
167#endif
168
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100169#if defined(MS_WINDOWS)
170# define TERMSIZE_USE_CONIO
171#elif defined(HAVE_SYS_IOCTL_H)
172# include <sys/ioctl.h>
173# if defined(HAVE_TERMIOS_H)
174# include <termios.h>
175# endif
176# if defined(TIOCGWINSZ)
177# define TERMSIZE_USE_IOCTL
178# endif
179#endif /* MS_WINDOWS */
180
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000182/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000183#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000184#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000185#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000186#include <process.h>
187#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000188#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000189#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000190#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000191#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000192#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700193#define HAVE_WSPAWNV 1
194#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000195#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000196#define HAVE_SYSTEM 1
197#define HAVE_CWAIT 1
198#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000199#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000200#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201/* Unix functions that the configure script doesn't check for */
pxinwrf2d7ac72019-05-21 18:46:37 +0800202#ifndef __VXWORKS__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#define HAVE_EXECV 1
204#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000205#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000206#define HAVE_FORK1 1
207#endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800208#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#define HAVE_GETEGID 1
210#define HAVE_GETEUID 1
211#define HAVE_GETGID 1
212#define HAVE_GETPPID 1
213#define HAVE_GETUID 1
214#define HAVE_KILL 1
215#define HAVE_OPENDIR 1
216#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000217#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000219#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000220#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000221#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000222
Eddie Elizondob3966632019-11-05 07:16:14 -0800223_Py_IDENTIFIER(__fspath__);
Victor Stinnera2f7c002012-02-08 03:36:25 +0100224
Larry Hastings61272b72014-01-07 12:41:53 -0800225/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000226# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800227module os
Larry Hastings61272b72014-01-07 12:41:53 -0800228[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000229/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100230
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000231#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000232
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000233#if defined(__sgi)&&_COMPILER_VERSION>=700
234/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
235 (default) */
236extern char *ctermid_r(char *);
237#endif
238
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000239#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000240
pxinwrf2d7ac72019-05-21 18:46:37 +0800241#if defined(__VXWORKS__)
242#include <vxCpuLib.h>
243#include <rtpLib.h>
244#include <wait.h>
245#include <taskLib.h>
246#ifndef _P_WAIT
247#define _P_WAIT 0
248#define _P_NOWAIT 1
249#define _P_NOWAITO 1
250#endif
251#endif /* __VXWORKS__ */
252
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000253#ifdef HAVE_POSIX_SPAWN
254#include <spawn.h>
255#endif
256
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#ifdef HAVE_UTIME_H
258#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000259#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000261#ifdef HAVE_SYS_UTIME_H
262#include <sys/utime.h>
263#define HAVE_UTIME_H /* pretend we do for the rest of this file */
264#endif /* HAVE_SYS_UTIME_H */
265
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266#ifdef HAVE_SYS_TIMES_H
267#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000268#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269
270#ifdef HAVE_SYS_PARAM_H
271#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000272#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273
274#ifdef HAVE_SYS_UTSNAME_H
275#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000276#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#define NAMLEN(dirent) strlen((dirent)->d_name)
281#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000282#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000283#include <direct.h>
284#define NAMLEN(dirent) strlen((dirent)->d_name)
285#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000286#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000287#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000289#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000291#endif
292#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000294#endif
295#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000297#endif
298#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000300#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000301#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000302#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000303#endif
304#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000305#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000306#endif
307#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000308#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000309#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000310#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000311#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000312#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100313#ifndef IO_REPARSE_TAG_MOUNT_POINT
314#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
315#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000317#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000319#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000320#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000321#define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000322#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000323
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325#if defined(PATH_MAX) && PATH_MAX > 1024
326#define MAXPATHLEN PATH_MAX
327#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000328#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000329#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000330#endif /* MAXPATHLEN */
331
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000332#ifdef UNION_WAIT
333/* Emulate some macros on systems that have a union instead of macros */
334
335#ifndef WIFEXITED
336#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
337#endif
338
339#ifndef WEXITSTATUS
340#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
341#endif
342
343#ifndef WTERMSIG
344#define WTERMSIG(u_wait) ((u_wait).w_termsig)
345#endif
346
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000347#define WAIT_TYPE union wait
348#define WAIT_STATUS_INT(s) (s.w_status)
349
350#else /* !UNION_WAIT */
351#define WAIT_TYPE int
352#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000353#endif /* UNION_WAIT */
354
Greg Wardb48bc172000-03-01 21:51:56 +0000355/* Don't use the "_r" form if we don't need it (also, won't have a
356 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200357#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000358#define USE_CTERMID_R
359#endif
360
Fred Drake699f3522000-06-29 21:12:41 +0000361/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000362#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000363#undef FSTAT
364#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200365#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000366# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700367# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200368# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800369# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000370#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000371# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700372# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000373# define FSTAT fstat
374# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000375#endif
376
Tim Peters11b23062003-04-23 02:39:17 +0000377#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000378#include <sys/mkdev.h>
379#else
380#if defined(MAJOR_IN_SYSMACROS)
381#include <sys/sysmacros.h>
382#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000383#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
384#include <sys/mkdev.h>
385#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000386#endif
Fred Drake699f3522000-06-29 21:12:41 +0000387
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200388#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100389#define INITFUNC PyInit_nt
390#define MODNAME "nt"
391#else
392#define INITFUNC PyInit_posix
393#define MODNAME "posix"
394#endif
395
jcea6c51d512018-01-28 14:00:08 +0100396#if defined(__sun)
397/* Something to implement in autoconf, not present in autoconf 2.69 */
398#define HAVE_STRUCT_STAT_ST_FSTYPE 1
399#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200400
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600401/* memfd_create is either defined in sys/mman.h or sys/memfd.h
402 * linux/memfd.h defines additional flags
403 */
404#ifdef HAVE_SYS_MMAN_H
405#include <sys/mman.h>
406#endif
407#ifdef HAVE_SYS_MEMFD_H
408#include <sys/memfd.h>
409#endif
410#ifdef HAVE_LINUX_MEMFD_H
411#include <linux/memfd.h>
412#endif
413
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800414#ifdef _Py_MEMORY_SANITIZER
415# include <sanitizer/msan_interface.h>
416#endif
417
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200418#ifdef HAVE_FORK
419static void
420run_at_forkers(PyObject *lst, int reverse)
421{
422 Py_ssize_t i;
423 PyObject *cpy;
424
425 if (lst != NULL) {
426 assert(PyList_CheckExact(lst));
427
428 /* Use a list copy in case register_at_fork() is called from
429 * one of the callbacks.
430 */
431 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
432 if (cpy == NULL)
433 PyErr_WriteUnraisable(lst);
434 else {
435 if (reverse)
436 PyList_Reverse(cpy);
437 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
438 PyObject *func, *res;
439 func = PyList_GET_ITEM(cpy, i);
Jeroen Demeyer7f41c8e2019-07-04 12:35:31 +0200440 res = _PyObject_CallNoArg(func);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200441 if (res == NULL)
442 PyErr_WriteUnraisable(func);
443 else
444 Py_DECREF(res);
445 }
446 Py_DECREF(cpy);
447 }
448 }
449}
450
451void
452PyOS_BeforeFork(void)
453{
Victor Stinnercaba55b2018-08-03 15:33:52 +0200454 run_at_forkers(_PyInterpreterState_Get()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200455
456 _PyImport_AcquireLock();
457}
458
459void
460PyOS_AfterFork_Parent(void)
461{
462 if (_PyImport_ReleaseLock() <= 0)
463 Py_FatalError("failed releasing import lock after fork");
464
Victor Stinnercaba55b2018-08-03 15:33:52 +0200465 run_at_forkers(_PyInterpreterState_Get()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200466}
467
468void
469PyOS_AfterFork_Child(void)
470{
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200471 _PyRuntimeState *runtime = &_PyRuntime;
472 _PyGILState_Reinit(runtime);
Victor Stinnerd5d9e812019-05-13 12:35:37 +0200473 _PyEval_ReInitThreads(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200474 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200475 _PySignal_AfterFork();
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200476 _PyRuntimeState_ReInitThreads(runtime);
Victor Stinnerb49858b2019-05-24 15:20:23 +0200477 _PyInterpreterState_DeleteExceptMain(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200478
Victor Stinnercaba55b2018-08-03 15:33:52 +0200479 run_at_forkers(_PyInterpreterState_Get()->after_forkers_child, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200480}
481
482static int
483register_at_forker(PyObject **lst, PyObject *func)
484{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700485 if (func == NULL) /* nothing to register? do nothing. */
486 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200487 if (*lst == NULL) {
488 *lst = PyList_New(0);
489 if (*lst == NULL)
490 return -1;
491 }
492 return PyList_Append(*lst, func);
493}
494#endif
495
496/* Legacy wrapper */
497void
498PyOS_AfterFork(void)
499{
500#ifdef HAVE_FORK
501 PyOS_AfterFork_Child();
502#endif
503}
504
505
Victor Stinner6036e442015-03-08 01:58:04 +0100506#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200507/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700508void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
509void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200510 ULONG, struct _Py_stat_struct *);
511#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700512
Larry Hastings9cf065c2012-06-22 16:30:09 -0700513
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200514#ifndef MS_WINDOWS
515PyObject *
516_PyLong_FromUid(uid_t uid)
517{
518 if (uid == (uid_t)-1)
519 return PyLong_FromLong(-1);
520 return PyLong_FromUnsignedLong(uid);
521}
522
523PyObject *
524_PyLong_FromGid(gid_t gid)
525{
526 if (gid == (gid_t)-1)
527 return PyLong_FromLong(-1);
528 return PyLong_FromUnsignedLong(gid);
529}
530
531int
532_Py_Uid_Converter(PyObject *obj, void *p)
533{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700534 uid_t uid;
535 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200536 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200537 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700538 unsigned long uresult;
539
540 index = PyNumber_Index(obj);
541 if (index == NULL) {
542 PyErr_Format(PyExc_TypeError,
543 "uid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800544 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200545 return 0;
546 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700547
548 /*
549 * Handling uid_t is complicated for two reasons:
550 * * Although uid_t is (always?) unsigned, it still
551 * accepts -1.
552 * * We don't know its size in advance--it may be
553 * bigger than an int, or it may be smaller than
554 * a long.
555 *
556 * So a bit of defensive programming is in order.
557 * Start with interpreting the value passed
558 * in as a signed long and see if it works.
559 */
560
561 result = PyLong_AsLongAndOverflow(index, &overflow);
562
563 if (!overflow) {
564 uid = (uid_t)result;
565
566 if (result == -1) {
567 if (PyErr_Occurred())
568 goto fail;
569 /* It's a legitimate -1, we're done. */
570 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200571 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700572
573 /* Any other negative number is disallowed. */
574 if (result < 0)
575 goto underflow;
576
577 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200578 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700579 (long)uid != result)
580 goto underflow;
581 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200582 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700583
584 if (overflow < 0)
585 goto underflow;
586
587 /*
588 * Okay, the value overflowed a signed long. If it
589 * fits in an *unsigned* long, it may still be okay,
590 * as uid_t may be unsigned long on this platform.
591 */
592 uresult = PyLong_AsUnsignedLong(index);
593 if (PyErr_Occurred()) {
594 if (PyErr_ExceptionMatches(PyExc_OverflowError))
595 goto overflow;
596 goto fail;
597 }
598
599 uid = (uid_t)uresult;
600
601 /*
602 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
603 * but this value would get interpreted as (uid_t)-1 by chown
604 * and its siblings. That's not what the user meant! So we
605 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100606 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700607 */
608 if (uid == (uid_t)-1)
609 goto overflow;
610
611 /* Ensure the value wasn't truncated. */
612 if (sizeof(uid_t) < sizeof(long) &&
613 (unsigned long)uid != uresult)
614 goto overflow;
615 /* fallthrough */
616
617success:
618 Py_DECREF(index);
619 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620 return 1;
621
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700622underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200623 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700624 "uid is less than minimum");
625 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200626
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700627overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200628 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700629 "uid is greater than maximum");
630 /* fallthrough */
631
632fail:
633 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200634 return 0;
635}
636
637int
638_Py_Gid_Converter(PyObject *obj, void *p)
639{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700640 gid_t gid;
641 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200642 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200643 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700644 unsigned long uresult;
645
646 index = PyNumber_Index(obj);
647 if (index == NULL) {
648 PyErr_Format(PyExc_TypeError,
649 "gid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800650 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200651 return 0;
652 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700653
654 /*
655 * Handling gid_t is complicated for two reasons:
656 * * Although gid_t is (always?) unsigned, it still
657 * accepts -1.
658 * * We don't know its size in advance--it may be
659 * bigger than an int, or it may be smaller than
660 * a long.
661 *
662 * So a bit of defensive programming is in order.
663 * Start with interpreting the value passed
664 * in as a signed long and see if it works.
665 */
666
667 result = PyLong_AsLongAndOverflow(index, &overflow);
668
669 if (!overflow) {
670 gid = (gid_t)result;
671
672 if (result == -1) {
673 if (PyErr_Occurred())
674 goto fail;
675 /* It's a legitimate -1, we're done. */
676 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200677 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700678
679 /* Any other negative number is disallowed. */
680 if (result < 0) {
681 goto underflow;
682 }
683
684 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200685 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700686 (long)gid != result)
687 goto underflow;
688 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200689 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700690
691 if (overflow < 0)
692 goto underflow;
693
694 /*
695 * Okay, the value overflowed a signed long. If it
696 * fits in an *unsigned* long, it may still be okay,
697 * as gid_t may be unsigned long on this platform.
698 */
699 uresult = PyLong_AsUnsignedLong(index);
700 if (PyErr_Occurred()) {
701 if (PyErr_ExceptionMatches(PyExc_OverflowError))
702 goto overflow;
703 goto fail;
704 }
705
706 gid = (gid_t)uresult;
707
708 /*
709 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
710 * but this value would get interpreted as (gid_t)-1 by chown
711 * and its siblings. That's not what the user meant! So we
712 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100713 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700714 */
715 if (gid == (gid_t)-1)
716 goto overflow;
717
718 /* Ensure the value wasn't truncated. */
719 if (sizeof(gid_t) < sizeof(long) &&
720 (unsigned long)gid != uresult)
721 goto overflow;
722 /* fallthrough */
723
724success:
725 Py_DECREF(index);
726 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200727 return 1;
728
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700729underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200730 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700731 "gid is less than minimum");
732 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200733
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700734overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200735 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700736 "gid is greater than maximum");
737 /* fallthrough */
738
739fail:
740 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200741 return 0;
742}
743#endif /* MS_WINDOWS */
744
745
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700746#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800747
748
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200749#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
750static int
751_Py_Dev_Converter(PyObject *obj, void *p)
752{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200753 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200754 if (PyErr_Occurred())
755 return 0;
756 return 1;
757}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800758#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200759
760
Larry Hastings9cf065c2012-06-22 16:30:09 -0700761#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400762/*
763 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
764 * without the int cast, the value gets interpreted as uint (4291925331),
765 * which doesn't play nicely with all the initializer lines in this file that
766 * look like this:
767 * int dir_fd = DEFAULT_DIR_FD;
768 */
769#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700770#else
771#define DEFAULT_DIR_FD (-100)
772#endif
773
774static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300775_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200776{
777 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700778 long long_value;
779
780 PyObject *index = PyNumber_Index(o);
781 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700782 return 0;
783 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700784
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300785 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700786 long_value = PyLong_AsLongAndOverflow(index, &overflow);
787 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300788 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200789 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700790 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700791 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700792 return 0;
793 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200794 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700795 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700796 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700797 return 0;
798 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700799
Larry Hastings9cf065c2012-06-22 16:30:09 -0700800 *p = (int)long_value;
801 return 1;
802}
803
804static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200805dir_fd_converter(PyObject *o, void *p)
806{
807 if (o == Py_None) {
808 *(int *)p = DEFAULT_DIR_FD;
809 return 1;
810 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300811 else if (PyIndex_Check(o)) {
812 return _fd_converter(o, (int *)p);
813 }
814 else {
815 PyErr_Format(PyExc_TypeError,
816 "argument should be integer or None, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800817 _PyType_Name(Py_TYPE(o)));
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300818 return 0;
819 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700820}
821
Eddie Elizondob3966632019-11-05 07:16:14 -0800822typedef struct {
823 PyObject *billion;
Eddie Elizondob3966632019-11-05 07:16:14 -0800824 PyObject *DirEntryType;
825 PyObject *ScandirIteratorType;
826#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
827 PyObject *SchedParamType;
828#endif
829 PyObject *StatResultType;
830 PyObject *StatVFSResultType;
831 PyObject *TerminalSizeType;
832 PyObject *TimesResultType;
833 PyObject *UnameResultType;
834#if defined(HAVE_WAITID) && !defined(__APPLE__)
835 PyObject *WaitidResultType;
836#endif
837#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
838 PyObject *struct_rusage;
839#endif
840 PyObject *st_mode;
841} _posixstate;
842
843static struct PyModuleDef posixmodule;
844
845#define _posixstate(o) ((_posixstate *)PyModule_GetState(o))
846#define _posixstate_global ((_posixstate *)PyModule_GetState(PyState_FindModule(&posixmodule)))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700847
Larry Hastings9cf065c2012-06-22 16:30:09 -0700848/*
849 * A PyArg_ParseTuple "converter" function
850 * that handles filesystem paths in the manner
851 * preferred by the os module.
852 *
853 * path_converter accepts (Unicode) strings and their
854 * subclasses, and bytes and their subclasses. What
855 * it does with the argument depends on the platform:
856 *
857 * * On Windows, if we get a (Unicode) string we
858 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700859 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700860 *
861 * * On all other platforms, strings are encoded
862 * to bytes using PyUnicode_FSConverter, then we
863 * extract the char * from the bytes object and
864 * return that.
865 *
866 * path_converter also optionally accepts signed
867 * integers (representing open file descriptors) instead
868 * of path strings.
869 *
870 * Input fields:
871 * path.nullable
872 * If nonzero, the path is permitted to be None.
873 * path.allow_fd
874 * If nonzero, the path is permitted to be a file handle
875 * (a signed int) instead of a string.
876 * path.function_name
877 * If non-NULL, path_converter will use that as the name
878 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700879 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700880 * path.argument_name
881 * If non-NULL, path_converter will use that as the name
882 * of the parameter in error messages.
883 * (If path.argument_name is NULL it uses "path".)
884 *
885 * Output fields:
886 * path.wide
887 * Points to the path if it was expressed as Unicode
888 * and was not encoded. (Only used on Windows.)
889 * path.narrow
890 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700891 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000892 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700893 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700894 * path.fd
895 * Contains a file descriptor if path.accept_fd was true
896 * and the caller provided a signed integer instead of any
897 * sort of string.
898 *
899 * WARNING: if your "path" parameter is optional, and is
900 * unspecified, path_converter will never get called.
901 * So if you set allow_fd, you *MUST* initialize path.fd = -1
902 * yourself!
903 * path.length
904 * The length of the path in characters, if specified as
905 * a string.
906 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800907 * The original object passed in (if get a PathLike object,
908 * the result of PyOS_FSPath() is treated as the original object).
909 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700910 * path.cleanup
911 * For internal use only. May point to a temporary object.
912 * (Pay no attention to the man behind the curtain.)
913 *
914 * At most one of path.wide or path.narrow will be non-NULL.
915 * If path was None and path.nullable was set,
916 * or if path was an integer and path.allow_fd was set,
917 * both path.wide and path.narrow will be NULL
918 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200919 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700920 * path_converter takes care to not write to the path_t
921 * unless it's successful. However it must reset the
922 * "cleanup" field each time it's called.
923 *
924 * Use as follows:
925 * path_t path;
926 * memset(&path, 0, sizeof(path));
927 * PyArg_ParseTuple(args, "O&", path_converter, &path);
928 * // ... use values from path ...
929 * path_cleanup(&path);
930 *
931 * (Note that if PyArg_Parse fails you don't need to call
932 * path_cleanup(). However it is safe to do so.)
933 */
934typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100935 const char *function_name;
936 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700937 int nullable;
938 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300939 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700940#ifdef MS_WINDOWS
941 BOOL narrow;
942#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300943 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700944#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700945 int fd;
946 Py_ssize_t length;
947 PyObject *object;
948 PyObject *cleanup;
949} path_t;
950
Steve Dowercc16be82016-09-08 10:35:16 -0700951#ifdef MS_WINDOWS
952#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
953 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
954#else
Larry Hastings2f936352014-08-05 14:04:04 +1000955#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
956 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700957#endif
Larry Hastings31826802013-10-19 00:09:25 -0700958
Larry Hastings9cf065c2012-06-22 16:30:09 -0700959static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800960path_cleanup(path_t *path)
961{
962 Py_CLEAR(path->object);
963 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964}
965
966static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300967path_converter(PyObject *o, void *p)
968{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700969 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800970 PyObject *bytes = NULL;
971 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700972 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300973 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700974#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800975 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700976 const wchar_t *wide;
977#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700978
979#define FORMAT_EXCEPTION(exc, fmt) \
980 PyErr_Format(exc, "%s%s" fmt, \
981 path->function_name ? path->function_name : "", \
982 path->function_name ? ": " : "", \
983 path->argument_name ? path->argument_name : "path")
984
985 /* Py_CLEANUP_SUPPORTED support */
986 if (o == NULL) {
987 path_cleanup(path);
988 return 1;
989 }
990
Brett Cannon3f9183b2016-08-26 14:44:48 -0700991 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800992 path->object = path->cleanup = NULL;
993 /* path->object owns a reference to the original object */
994 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700995
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300996 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700997 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700998#ifdef MS_WINDOWS
999 path->narrow = FALSE;
1000#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001002#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001003 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001004 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001005 }
1006
Brett Cannon3f9183b2016-08-26 14:44:48 -07001007 /* Only call this here so that we don't treat the return value of
1008 os.fspath() as an fd or buffer. */
1009 is_index = path->allow_fd && PyIndex_Check(o);
1010 is_buffer = PyObject_CheckBuffer(o);
1011 is_bytes = PyBytes_Check(o);
1012 is_unicode = PyUnicode_Check(o);
1013
1014 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
1015 /* Inline PyOS_FSPath() for better error messages. */
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001016 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001017
1018 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1019 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001020 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001021 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001022 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001023 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001024 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001025 goto error_exit;
1026 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001027 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001028 is_unicode = 1;
1029 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001030 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001031 is_bytes = 1;
1032 }
1033 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001034 PyErr_Format(PyExc_TypeError,
1035 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -08001036 "not %.200s", _PyType_Name(Py_TYPE(o)),
1037 _PyType_Name(Py_TYPE(res)));
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001038 Py_DECREF(res);
1039 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001040 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001041
1042 /* still owns a reference to the original object */
1043 Py_DECREF(o);
1044 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001045 }
1046
1047 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001048#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001049 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001050 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001051 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052 }
Victor Stinner59799a82013-11-13 14:17:30 +01001053 if (length > 32767) {
1054 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001055 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001056 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001057 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001058 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001059 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001060 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001061
1062 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001063 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001064 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001065 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001066#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001067 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001068 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001069 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001070#endif
1071 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001072 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001073 bytes = o;
1074 Py_INCREF(bytes);
1075 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001076 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001077 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001078 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001079 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1080 "%s%s%s should be %s, not %.200s",
1081 path->function_name ? path->function_name : "",
1082 path->function_name ? ": " : "",
1083 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001084 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1085 "integer or None" :
1086 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1087 path->nullable ? "string, bytes, os.PathLike or None" :
1088 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001089 _PyType_Name(Py_TYPE(o)))) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001090 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001091 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001092 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001093 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001094 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001095 }
1096 }
Steve Dowercc16be82016-09-08 10:35:16 -07001097 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001098 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001099 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001100 }
1101 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001102#ifdef MS_WINDOWS
1103 path->narrow = FALSE;
1104#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001105 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001106#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001107 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001108 }
1109 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001110 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001111 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1112 path->function_name ? path->function_name : "",
1113 path->function_name ? ": " : "",
1114 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001115 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1116 "integer or None" :
1117 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1118 path->nullable ? "string, bytes, os.PathLike or None" :
1119 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001120 _PyType_Name(Py_TYPE(o)));
Xiang Zhang04316c42017-01-08 23:26:57 +08001121 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001122 }
1123
Larry Hastings9cf065c2012-06-22 16:30:09 -07001124 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001125 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001126 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001127 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001128 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001129 }
1130
Steve Dowercc16be82016-09-08 10:35:16 -07001131#ifdef MS_WINDOWS
1132 wo = PyUnicode_DecodeFSDefaultAndSize(
1133 narrow,
1134 length
1135 );
1136 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001137 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001138 }
1139
Xiang Zhang04316c42017-01-08 23:26:57 +08001140 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001141 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001142 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001143 }
1144 if (length > 32767) {
1145 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001146 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001147 }
1148 if (wcslen(wide) != length) {
1149 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001150 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001151 }
1152 path->wide = wide;
1153 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001154 path->cleanup = wo;
1155 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001156#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001157 path->wide = NULL;
1158 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001159 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001160 /* Still a reference owned by path->object, don't have to
1161 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001162 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001163 }
1164 else {
1165 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001166 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001167#endif
1168 path->fd = -1;
1169
1170 success_exit:
1171 path->length = length;
1172 path->object = o;
1173 return Py_CLEANUP_SUPPORTED;
1174
1175 error_exit:
1176 Py_XDECREF(o);
1177 Py_XDECREF(bytes);
1178#ifdef MS_WINDOWS
1179 Py_XDECREF(wo);
1180#endif
1181 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001182}
1183
1184static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001185argument_unavailable_error(const char *function_name, const char *argument_name)
1186{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001187 PyErr_Format(PyExc_NotImplementedError,
1188 "%s%s%s unavailable on this platform",
1189 (function_name != NULL) ? function_name : "",
1190 (function_name != NULL) ? ": ": "",
1191 argument_name);
1192}
1193
1194static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001195dir_fd_unavailable(PyObject *o, void *p)
1196{
1197 int dir_fd;
1198 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001199 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001200 if (dir_fd != DEFAULT_DIR_FD) {
1201 argument_unavailable_error(NULL, "dir_fd");
1202 return 0;
1203 }
1204 *(int *)p = dir_fd;
1205 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001206}
1207
1208static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001209fd_specified(const char *function_name, int fd)
1210{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001211 if (fd == -1)
1212 return 0;
1213
1214 argument_unavailable_error(function_name, "fd");
1215 return 1;
1216}
1217
1218static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001219follow_symlinks_specified(const char *function_name, int follow_symlinks)
1220{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001221 if (follow_symlinks)
1222 return 0;
1223
1224 argument_unavailable_error(function_name, "follow_symlinks");
1225 return 1;
1226}
1227
1228static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001229path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1230{
Steve Dowercc16be82016-09-08 10:35:16 -07001231 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1232#ifndef MS_WINDOWS
1233 && !path->narrow
1234#endif
1235 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001236 PyErr_Format(PyExc_ValueError,
1237 "%s: can't specify dir_fd without matching path",
1238 function_name);
1239 return 1;
1240 }
1241 return 0;
1242}
1243
1244static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001245dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1246{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001247 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1248 PyErr_Format(PyExc_ValueError,
1249 "%s: can't specify both dir_fd and fd",
1250 function_name);
1251 return 1;
1252 }
1253 return 0;
1254}
1255
1256static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001257fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1258 int follow_symlinks)
1259{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001260 if ((fd > 0) && (!follow_symlinks)) {
1261 PyErr_Format(PyExc_ValueError,
1262 "%s: cannot use fd and follow_symlinks together",
1263 function_name);
1264 return 1;
1265 }
1266 return 0;
1267}
1268
1269static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001270dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1271 int follow_symlinks)
1272{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001273 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1274 PyErr_Format(PyExc_ValueError,
1275 "%s: cannot use dir_fd and follow_symlinks together",
1276 function_name);
1277 return 1;
1278 }
1279 return 0;
1280}
1281
Larry Hastings2f936352014-08-05 14:04:04 +10001282#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001283 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001284#else
Larry Hastings2f936352014-08-05 14:04:04 +10001285 typedef off_t Py_off_t;
1286#endif
1287
1288static int
1289Py_off_t_converter(PyObject *arg, void *addr)
1290{
1291#ifdef HAVE_LARGEFILE_SUPPORT
1292 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1293#else
1294 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001295#endif
1296 if (PyErr_Occurred())
1297 return 0;
1298 return 1;
1299}
Larry Hastings2f936352014-08-05 14:04:04 +10001300
1301static PyObject *
1302PyLong_FromPy_off_t(Py_off_t offset)
1303{
1304#ifdef HAVE_LARGEFILE_SUPPORT
1305 return PyLong_FromLongLong(offset);
1306#else
1307 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001308#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001309}
1310
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001311#ifdef HAVE_SIGSET_T
1312/* Convert an iterable of integers to a sigset.
1313 Return 1 on success, return 0 and raise an exception on error. */
1314int
1315_Py_Sigset_Converter(PyObject *obj, void *addr)
1316{
1317 sigset_t *mask = (sigset_t *)addr;
1318 PyObject *iterator, *item;
1319 long signum;
1320 int overflow;
1321
Rémi Lapeyref0900192019-05-04 01:30:53 +02001322 // The extra parens suppress the unreachable-code warning with clang on MacOS
1323 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001324 /* Probably only if mask == NULL. */
1325 PyErr_SetFromErrno(PyExc_OSError);
1326 return 0;
1327 }
1328
1329 iterator = PyObject_GetIter(obj);
1330 if (iterator == NULL) {
1331 return 0;
1332 }
1333
1334 while ((item = PyIter_Next(iterator)) != NULL) {
1335 signum = PyLong_AsLongAndOverflow(item, &overflow);
1336 Py_DECREF(item);
1337 if (signum <= 0 || signum >= NSIG) {
1338 if (overflow || signum != -1 || !PyErr_Occurred()) {
1339 PyErr_Format(PyExc_ValueError,
1340 "signal number %ld out of range", signum);
1341 }
1342 goto error;
1343 }
1344 if (sigaddset(mask, (int)signum)) {
1345 if (errno != EINVAL) {
1346 /* Probably impossible */
1347 PyErr_SetFromErrno(PyExc_OSError);
1348 goto error;
1349 }
1350 /* For backwards compatibility, allow idioms such as
1351 * `range(1, NSIG)` but warn about invalid signal numbers
1352 */
1353 const char msg[] =
1354 "invalid signal number %ld, please use valid_signals()";
1355 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1356 goto error;
1357 }
1358 }
1359 }
1360 if (!PyErr_Occurred()) {
1361 Py_DECREF(iterator);
1362 return 1;
1363 }
1364
1365error:
1366 Py_DECREF(iterator);
1367 return 0;
1368}
1369#endif /* HAVE_SIGSET_T */
1370
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001371#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001372
1373static int
Brian Curtind25aef52011-06-13 15:16:04 -05001374win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001375{
Martin Panter70214ad2016-08-04 02:38:59 +00001376 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1377 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001378 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001379
1380 if (0 == DeviceIoControl(
1381 reparse_point_handle,
1382 FSCTL_GET_REPARSE_POINT,
1383 NULL, 0, /* in buffer */
1384 target_buffer, sizeof(target_buffer),
1385 &n_bytes_returned,
1386 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001387 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001388
1389 if (reparse_tag)
1390 *reparse_tag = rdb->ReparseTag;
1391
Brian Curtind25aef52011-06-13 15:16:04 -05001392 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001393}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001394
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001395#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001396
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001397/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001398#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001399/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001400** environ directly, we must obtain it with _NSGetEnviron(). See also
1401** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001402*/
1403#include <crt_externs.h>
pxinwrf2d7ac72019-05-21 18:46:37 +08001404#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001405extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001406#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001407
Barry Warsaw53699e91996-12-10 23:23:01 +00001408static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001409convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001410{
Victor Stinner8c62be82010-05-06 00:08:46 +00001411 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001412#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001414#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001415 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001416#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001417
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 d = PyDict_New();
1419 if (d == NULL)
1420 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001421#ifdef MS_WINDOWS
1422 /* _wenviron must be initialized in this way if the program is started
1423 through main() instead of wmain(). */
1424 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001425 e = _wenviron;
Benoit Hudson723f71a2019-12-06 14:15:03 -05001426#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1427 /* environ is not accessible as an extern in a shared object on OSX; use
1428 _NSGetEnviron to resolve it. The value changes if you add environment
1429 variables between calls to Py_Initialize, so don't cache the value. */
1430 e = *_NSGetEnviron();
Victor Stinner8c62be82010-05-06 00:08:46 +00001431#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001432 e = environ;
1433#endif
1434 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001435 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001436 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001437 PyObject *k;
1438 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001439#ifdef MS_WINDOWS
1440 const wchar_t *p = wcschr(*e, L'=');
1441#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001442 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001443#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001444 if (p == NULL)
1445 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001446#ifdef MS_WINDOWS
1447 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1448#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001449 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001450#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001451 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001452 Py_DECREF(d);
1453 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001454 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001455#ifdef MS_WINDOWS
1456 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1457#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001458 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001459#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001460 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001461 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001462 Py_DECREF(d);
1463 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001464 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001465 if (PyDict_GetItemWithError(d, k) == NULL) {
1466 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1467 Py_DECREF(v);
1468 Py_DECREF(k);
1469 Py_DECREF(d);
1470 return NULL;
1471 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001472 }
1473 Py_DECREF(k);
1474 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001475 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001476 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001477}
1478
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001479/* Set a POSIX-specific error from errno, and return NULL */
1480
Barry Warsawd58d7641998-07-23 16:14:40 +00001481static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001482posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001483{
Victor Stinner8c62be82010-05-06 00:08:46 +00001484 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001485}
Mark Hammondef8b6542001-05-13 08:04:26 +00001486
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001487#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001488static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001489win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001490{
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 /* XXX We should pass the function name along in the future.
1492 (winreg.c also wants to pass the function name.)
1493 This would however require an additional param to the
1494 Windows error object, which is non-trivial.
1495 */
1496 errno = GetLastError();
1497 if (filename)
1498 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1499 else
1500 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001501}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001502
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001503static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001504win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001505{
1506 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001507 if (filename)
1508 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001509 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001510 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001511 filename);
1512 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001513 return PyErr_SetFromWindowsErr(err);
1514}
1515
1516static PyObject *
1517win32_error_object(const char* function, PyObject* filename)
1518{
1519 errno = GetLastError();
1520 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001521}
1522
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001523#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001524
Larry Hastings9cf065c2012-06-22 16:30:09 -07001525static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001526posix_path_object_error(PyObject *path)
1527{
1528 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1529}
1530
1531static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001532path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001533{
1534#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001535 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1536 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001537#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001538 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001539#endif
1540}
1541
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001542static PyObject *
1543path_object_error2(PyObject *path, PyObject *path2)
1544{
1545#ifdef MS_WINDOWS
1546 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1547 PyExc_OSError, 0, path, path2);
1548#else
1549 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1550#endif
1551}
1552
1553static PyObject *
1554path_error(path_t *path)
1555{
1556 return path_object_error(path->object);
1557}
Larry Hastings31826802013-10-19 00:09:25 -07001558
Larry Hastingsb0827312014-02-09 22:05:19 -08001559static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001560posix_path_error(path_t *path)
1561{
1562 return posix_path_object_error(path->object);
1563}
1564
1565static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001566path_error2(path_t *path, path_t *path2)
1567{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001568 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001569}
1570
1571
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001572/* POSIX generic methods */
1573
Larry Hastings2f936352014-08-05 14:04:04 +10001574static int
1575fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001576{
Victor Stinner8c62be82010-05-06 00:08:46 +00001577 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001578 int *pointer = (int *)p;
1579 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001580 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001581 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001582 *pointer = fd;
1583 return 1;
1584}
1585
1586static PyObject *
1587posix_fildes_fd(int fd, int (*func)(int))
1588{
1589 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001590 int async_err = 0;
1591
1592 do {
1593 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001594 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001595 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001596 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001597 Py_END_ALLOW_THREADS
1598 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1599 if (res != 0)
1600 return (!async_err) ? posix_error() : NULL;
1601 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001602}
Guido van Rossum21142a01999-01-08 21:05:37 +00001603
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001604
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001605#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001606/* This is a reimplementation of the C library's chdir function,
1607 but one that produces Win32 errors instead of DOS error codes.
1608 chdir is essentially a wrapper around SetCurrentDirectory; however,
1609 it also needs to set "magic" environment variables indicating
1610 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001611static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001612win32_wchdir(LPCWSTR path)
1613{
Victor Stinnered537822015-12-13 21:40:26 +01001614 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001615 int result;
1616 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001617
Victor Stinner8c62be82010-05-06 00:08:46 +00001618 if(!SetCurrentDirectoryW(path))
1619 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001620 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001621 if (!result)
1622 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001623 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001624 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001625 if (!new_path) {
1626 SetLastError(ERROR_OUTOFMEMORY);
1627 return FALSE;
1628 }
1629 result = GetCurrentDirectoryW(result, new_path);
1630 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001631 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001632 return FALSE;
1633 }
1634 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001635 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1636 wcsncmp(new_path, L"//", 2) == 0);
1637 if (!is_unc_like_path) {
1638 env[1] = new_path[0];
1639 result = SetEnvironmentVariableW(env, new_path);
1640 }
Victor Stinnered537822015-12-13 21:40:26 +01001641 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001642 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001643 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001644}
1645#endif
1646
Martin v. Löwis14694662006-02-03 12:54:16 +00001647#ifdef MS_WINDOWS
1648/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1649 - time stamps are restricted to second resolution
1650 - file modification times suffer from forth-and-back conversions between
1651 UTC and local time
1652 Therefore, we implement our own stat, based on the Win32 API directly.
1653*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001654#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001655#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001656#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001657
Victor Stinner6036e442015-03-08 01:58:04 +01001658static void
Steve Dowercc16be82016-09-08 10:35:16 -07001659find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1660 BY_HANDLE_FILE_INFORMATION *info,
1661 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001662{
1663 memset(info, 0, sizeof(*info));
1664 info->dwFileAttributes = pFileData->dwFileAttributes;
1665 info->ftCreationTime = pFileData->ftCreationTime;
1666 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1667 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1668 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1669 info->nFileSizeLow = pFileData->nFileSizeLow;
1670/* info->nNumberOfLinks = 1; */
1671 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1672 *reparse_tag = pFileData->dwReserved0;
1673 else
1674 *reparse_tag = 0;
1675}
1676
Guido van Rossumd8faa362007-04-27 19:54:29 +00001677static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001678attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001679{
Victor Stinner8c62be82010-05-06 00:08:46 +00001680 HANDLE hFindFile;
1681 WIN32_FIND_DATAW FileData;
1682 hFindFile = FindFirstFileW(pszFile, &FileData);
1683 if (hFindFile == INVALID_HANDLE_VALUE)
1684 return FALSE;
1685 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001686 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001687 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001688}
1689
Brian Curtind25aef52011-06-13 15:16:04 -05001690static int
Steve Dowercc16be82016-09-08 10:35:16 -07001691win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001692 BOOL traverse)
1693{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001694 HANDLE hFile;
1695 BY_HANDLE_FILE_INFORMATION fileInfo;
1696 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1697 DWORD fileType, error;
1698 BOOL isUnhandledTag = FALSE;
1699 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001700
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001701 DWORD access = FILE_READ_ATTRIBUTES;
1702 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1703 if (!traverse) {
1704 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1705 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001706
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001707 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001708 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001709 /* Either the path doesn't exist, or the caller lacks access. */
1710 error = GetLastError();
1711 switch (error) {
1712 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1713 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1714 /* Try reading the parent directory. */
1715 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1716 /* Cannot read the parent directory. */
1717 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001718 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001719 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001720 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1721 if (traverse ||
1722 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1723 /* The stat call has to traverse but cannot, so fail. */
1724 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001725 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001726 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001727 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001728 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001729
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001730 case ERROR_INVALID_PARAMETER:
1731 /* \\.\con requires read or write access. */
1732 hFile = CreateFileW(path, access | GENERIC_READ,
1733 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1734 OPEN_EXISTING, flags, NULL);
1735 if (hFile == INVALID_HANDLE_VALUE) {
1736 SetLastError(error);
1737 return -1;
1738 }
1739 break;
1740
1741 case ERROR_CANT_ACCESS_FILE:
1742 /* bpo37834: open unhandled reparse points if traverse fails. */
1743 if (traverse) {
1744 traverse = FALSE;
1745 isUnhandledTag = TRUE;
1746 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1747 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1748 }
1749 if (hFile == INVALID_HANDLE_VALUE) {
1750 SetLastError(error);
1751 return -1;
1752 }
1753 break;
1754
1755 default:
1756 return -1;
1757 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001758 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001759
1760 if (hFile != INVALID_HANDLE_VALUE) {
1761 /* Handle types other than files on disk. */
1762 fileType = GetFileType(hFile);
1763 if (fileType != FILE_TYPE_DISK) {
1764 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1765 retval = -1;
1766 goto cleanup;
1767 }
1768 DWORD fileAttributes = GetFileAttributesW(path);
1769 memset(result, 0, sizeof(*result));
1770 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1771 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1772 /* \\.\pipe\ or \\.\mailslot\ */
1773 result->st_mode = _S_IFDIR;
1774 } else if (fileType == FILE_TYPE_CHAR) {
1775 /* \\.\nul */
1776 result->st_mode = _S_IFCHR;
1777 } else if (fileType == FILE_TYPE_PIPE) {
1778 /* \\.\pipe\spam */
1779 result->st_mode = _S_IFIFO;
1780 }
1781 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1782 goto cleanup;
1783 }
1784
1785 /* Query the reparse tag, and traverse a non-link. */
1786 if (!traverse) {
1787 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1788 &tagInfo, sizeof(tagInfo))) {
1789 /* Allow devices that do not support FileAttributeTagInfo. */
1790 switch (GetLastError()) {
1791 case ERROR_INVALID_PARAMETER:
1792 case ERROR_INVALID_FUNCTION:
1793 case ERROR_NOT_SUPPORTED:
1794 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1795 tagInfo.ReparseTag = 0;
1796 break;
1797 default:
1798 retval = -1;
1799 goto cleanup;
1800 }
1801 } else if (tagInfo.FileAttributes &
1802 FILE_ATTRIBUTE_REPARSE_POINT) {
1803 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1804 if (isUnhandledTag) {
1805 /* Traversing previously failed for either this link
1806 or its target. */
1807 SetLastError(ERROR_CANT_ACCESS_FILE);
1808 retval = -1;
1809 goto cleanup;
1810 }
1811 /* Traverse a non-link, but not if traversing already failed
1812 for an unhandled tag. */
1813 } else if (!isUnhandledTag) {
1814 CloseHandle(hFile);
1815 return win32_xstat_impl(path, result, TRUE);
1816 }
1817 }
1818 }
1819
1820 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
1821 switch (GetLastError()) {
1822 case ERROR_INVALID_PARAMETER:
1823 case ERROR_INVALID_FUNCTION:
1824 case ERROR_NOT_SUPPORTED:
Steve Dower772ec0f2019-09-04 14:42:54 -07001825 /* Volumes and physical disks are block devices, e.g.
1826 \\.\C: and \\.\PhysicalDrive0. */
1827 memset(result, 0, sizeof(*result));
1828 result->st_mode = 0x6000; /* S_IFBLK */
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001829 goto cleanup;
1830 }
Steve Dower772ec0f2019-09-04 14:42:54 -07001831 retval = -1;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001832 goto cleanup;
1833 }
1834 }
1835
1836 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
1837
1838 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
1839 /* Fix the file execute permissions. This hack sets S_IEXEC if
1840 the filename has an extension that is commonly used by files
1841 that CreateProcessW can execute. A real implementation calls
1842 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
1843 AccessCheck to check for generic read, write, and execute
1844 access. */
1845 const wchar_t *fileExtension = wcsrchr(path, '.');
1846 if (fileExtension) {
1847 if (_wcsicmp(fileExtension, L".exe") == 0 ||
1848 _wcsicmp(fileExtension, L".bat") == 0 ||
1849 _wcsicmp(fileExtension, L".cmd") == 0 ||
1850 _wcsicmp(fileExtension, L".com") == 0) {
1851 result->st_mode |= 0111;
1852 }
1853 }
1854 }
1855
1856cleanup:
1857 if (hFile != INVALID_HANDLE_VALUE) {
Steve Dower772ec0f2019-09-04 14:42:54 -07001858 /* Preserve last error if we are failing */
1859 error = retval ? GetLastError() : 0;
1860 if (!CloseHandle(hFile)) {
1861 retval = -1;
1862 } else if (retval) {
1863 /* Restore last error */
1864 SetLastError(error);
1865 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001866 }
1867
1868 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001869}
1870
1871static int
Steve Dowercc16be82016-09-08 10:35:16 -07001872win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001873{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001874 /* Protocol violation: we explicitly clear errno, instead of
1875 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001876 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001877 errno = 0;
1878 return code;
1879}
Brian Curtind25aef52011-06-13 15:16:04 -05001880/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001881
1882 In Posix, stat automatically traverses symlinks and returns the stat
1883 structure for the target. In Windows, the equivalent GetFileAttributes by
1884 default does not traverse symlinks and instead returns attributes for
1885 the symlink.
1886
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001887 Instead, we will open the file (which *does* traverse symlinks by default)
1888 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00001889
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001890static int
Steve Dowercc16be82016-09-08 10:35:16 -07001891win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001892{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001893 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001894}
1895
Victor Stinner8c62be82010-05-06 00:08:46 +00001896static int
Steve Dowercc16be82016-09-08 10:35:16 -07001897win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001898{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001899 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001900}
1901
Martin v. Löwis14694662006-02-03 12:54:16 +00001902#endif /* MS_WINDOWS */
1903
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001904PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001905"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001906This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001907 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001908or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1909\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001910Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1911or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001912\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001913See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001914
1915static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001916 {"st_mode", "protection bits"},
1917 {"st_ino", "inode"},
1918 {"st_dev", "device"},
1919 {"st_nlink", "number of hard links"},
1920 {"st_uid", "user ID of owner"},
1921 {"st_gid", "group ID of owner"},
1922 {"st_size", "total size, in bytes"},
1923 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1924 {NULL, "integer time of last access"},
1925 {NULL, "integer time of last modification"},
1926 {NULL, "integer time of last change"},
1927 {"st_atime", "time of last access"},
1928 {"st_mtime", "time of last modification"},
1929 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001930 {"st_atime_ns", "time of last access in nanoseconds"},
1931 {"st_mtime_ns", "time of last modification in nanoseconds"},
1932 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001933#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001935#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001936#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001937 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001938#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001939#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001940 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001941#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001942#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001943 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001944#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001945#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001946 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001947#endif
1948#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001949 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001950#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001951#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1952 {"st_file_attributes", "Windows file attribute bits"},
1953#endif
jcea6c51d512018-01-28 14:00:08 +01001954#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1955 {"st_fstype", "Type of filesystem"},
1956#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001957#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
1958 {"st_reparse_tag", "Windows reparse tag"},
1959#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001960 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001961};
1962
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001963#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001964#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001965#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001966#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001967#endif
1968
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001969#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001970#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1971#else
1972#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1973#endif
1974
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001975#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001976#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1977#else
1978#define ST_RDEV_IDX ST_BLOCKS_IDX
1979#endif
1980
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001981#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1982#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1983#else
1984#define ST_FLAGS_IDX ST_RDEV_IDX
1985#endif
1986
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001987#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001988#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001989#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001990#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001991#endif
1992
1993#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1994#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1995#else
1996#define ST_BIRTHTIME_IDX ST_GEN_IDX
1997#endif
1998
Zachary Ware63f277b2014-06-19 09:46:37 -05001999#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2000#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
2001#else
2002#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2003#endif
2004
jcea6c51d512018-01-28 14:00:08 +01002005#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2006#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2007#else
2008#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2009#endif
2010
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002011#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2012#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2013#else
2014#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2015#endif
2016
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002017static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002018 "stat_result", /* name */
2019 stat_result__doc__, /* doc */
2020 stat_result_fields,
2021 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002022};
2023
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002024PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002025"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2026This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002027 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002028or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002029\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002030See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002031
2032static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002033 {"f_bsize", },
2034 {"f_frsize", },
2035 {"f_blocks", },
2036 {"f_bfree", },
2037 {"f_bavail", },
2038 {"f_files", },
2039 {"f_ffree", },
2040 {"f_favail", },
2041 {"f_flag", },
2042 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002043 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002044 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002045};
2046
2047static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002048 "statvfs_result", /* name */
2049 statvfs_result__doc__, /* doc */
2050 statvfs_result_fields,
2051 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002052};
2053
Ross Lagerwall7807c352011-03-17 20:20:30 +02002054#if defined(HAVE_WAITID) && !defined(__APPLE__)
2055PyDoc_STRVAR(waitid_result__doc__,
2056"waitid_result: Result from waitid.\n\n\
2057This object may be accessed either as a tuple of\n\
2058 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2059or via the attributes si_pid, si_uid, and so on.\n\
2060\n\
2061See os.waitid for more information.");
2062
2063static PyStructSequence_Field waitid_result_fields[] = {
2064 {"si_pid", },
2065 {"si_uid", },
2066 {"si_signo", },
2067 {"si_status", },
2068 {"si_code", },
2069 {0}
2070};
2071
2072static PyStructSequence_Desc waitid_result_desc = {
2073 "waitid_result", /* name */
2074 waitid_result__doc__, /* doc */
2075 waitid_result_fields,
2076 5
2077};
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002078#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002079static newfunc structseq_new;
2080
2081static PyObject *
2082statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2083{
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 PyStructSequence *result;
2085 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002086
Victor Stinner8c62be82010-05-06 00:08:46 +00002087 result = (PyStructSequence*)structseq_new(type, args, kwds);
2088 if (!result)
2089 return NULL;
2090 /* If we have been initialized from a tuple,
2091 st_?time might be set to None. Initialize it
2092 from the int slots. */
2093 for (i = 7; i <= 9; i++) {
2094 if (result->ob_item[i+3] == Py_None) {
2095 Py_DECREF(Py_None);
2096 Py_INCREF(result->ob_item[i]);
2097 result->ob_item[i+3] = result->ob_item[i];
2098 }
2099 }
2100 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002101}
2102
Eddie Elizondob3966632019-11-05 07:16:14 -08002103static int
2104_posix_clear(PyObject *module)
2105{
2106 Py_CLEAR(_posixstate(module)->billion);
Eddie Elizondob3966632019-11-05 07:16:14 -08002107 Py_CLEAR(_posixstate(module)->DirEntryType);
2108 Py_CLEAR(_posixstate(module)->ScandirIteratorType);
2109#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
2110 Py_CLEAR(_posixstate(module)->SchedParamType);
2111#endif
2112 Py_CLEAR(_posixstate(module)->StatResultType);
2113 Py_CLEAR(_posixstate(module)->StatVFSResultType);
2114 Py_CLEAR(_posixstate(module)->TerminalSizeType);
2115 Py_CLEAR(_posixstate(module)->TimesResultType);
2116 Py_CLEAR(_posixstate(module)->UnameResultType);
2117#if defined(HAVE_WAITID) && !defined(__APPLE__)
2118 Py_CLEAR(_posixstate(module)->WaitidResultType);
2119#endif
2120#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
2121 Py_CLEAR(_posixstate(module)->struct_rusage);
2122#endif
2123 Py_CLEAR(_posixstate(module)->st_mode);
2124 return 0;
2125}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002126
Eddie Elizondob3966632019-11-05 07:16:14 -08002127static int
2128_posix_traverse(PyObject *module, visitproc visit, void *arg)
2129{
2130 Py_VISIT(_posixstate(module)->billion);
Eddie Elizondob3966632019-11-05 07:16:14 -08002131 Py_VISIT(_posixstate(module)->DirEntryType);
2132 Py_VISIT(_posixstate(module)->ScandirIteratorType);
2133#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
2134 Py_VISIT(_posixstate(module)->SchedParamType);
2135#endif
2136 Py_VISIT(_posixstate(module)->StatResultType);
2137 Py_VISIT(_posixstate(module)->StatVFSResultType);
2138 Py_VISIT(_posixstate(module)->TerminalSizeType);
2139 Py_VISIT(_posixstate(module)->TimesResultType);
2140 Py_VISIT(_posixstate(module)->UnameResultType);
2141#if defined(HAVE_WAITID) && !defined(__APPLE__)
2142 Py_VISIT(_posixstate(module)->WaitidResultType);
2143#endif
2144#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
2145 Py_VISIT(_posixstate(module)->struct_rusage);
2146#endif
2147 Py_VISIT(_posixstate(module)->st_mode);
2148 return 0;
2149}
2150
2151static void
2152_posix_free(void *module)
2153{
2154 _posix_clear((PyObject *)module);
2155}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002156
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002157static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002158fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002159{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002160 PyObject *s = _PyLong_FromTime_t(sec);
2161 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2162 PyObject *s_in_ns = NULL;
2163 PyObject *ns_total = NULL;
2164 PyObject *float_s = NULL;
2165
2166 if (!(s && ns_fractional))
2167 goto exit;
2168
Eddie Elizondob3966632019-11-05 07:16:14 -08002169 s_in_ns = PyNumber_Multiply(s, _posixstate_global->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002170 if (!s_in_ns)
2171 goto exit;
2172
2173 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2174 if (!ns_total)
2175 goto exit;
2176
Victor Stinner01b5aab2017-10-24 02:02:00 -07002177 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2178 if (!float_s) {
2179 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002180 }
2181
2182 PyStructSequence_SET_ITEM(v, index, s);
2183 PyStructSequence_SET_ITEM(v, index+3, float_s);
2184 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2185 s = NULL;
2186 float_s = NULL;
2187 ns_total = NULL;
2188exit:
2189 Py_XDECREF(s);
2190 Py_XDECREF(ns_fractional);
2191 Py_XDECREF(s_in_ns);
2192 Py_XDECREF(ns_total);
2193 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002194}
2195
Tim Peters5aa91602002-01-30 05:46:57 +00002196/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002197 (used by posix_stat() and posix_fstat()) */
2198static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002199_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002200{
Victor Stinner8c62be82010-05-06 00:08:46 +00002201 unsigned long ansec, mnsec, cnsec;
Eddie Elizondob3966632019-11-05 07:16:14 -08002202 PyObject *StatResultType = _posixstate_global->StatResultType;
2203 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002204 if (v == NULL)
2205 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002206
Victor Stinner8c62be82010-05-06 00:08:46 +00002207 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002208 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002209 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002210#ifdef MS_WINDOWS
2211 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002212#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002213 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002214#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002215 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002216#if defined(MS_WINDOWS)
2217 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2218 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2219#else
2220 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2221 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2222#endif
xdegaye50e86032017-05-22 11:15:08 +02002223 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2224 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002225
Martin v. Löwis14694662006-02-03 12:54:16 +00002226#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002227 ansec = st->st_atim.tv_nsec;
2228 mnsec = st->st_mtim.tv_nsec;
2229 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002230#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002231 ansec = st->st_atimespec.tv_nsec;
2232 mnsec = st->st_mtimespec.tv_nsec;
2233 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002234#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002235 ansec = st->st_atime_nsec;
2236 mnsec = st->st_mtime_nsec;
2237 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002238#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002239 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002240#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002241 fill_time(v, 7, st->st_atime, ansec);
2242 fill_time(v, 8, st->st_mtime, mnsec);
2243 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002244
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002245#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002246 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2247 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002248#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002249#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002250 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2251 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002252#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002253#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002254 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2255 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002256#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002257#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002258 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2259 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002260#endif
2261#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002262 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002263 PyObject *val;
2264 unsigned long bsec,bnsec;
2265 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002266#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002267 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002268#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002269 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002270#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002271 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002272 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2273 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002274 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002275#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002276#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002277 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2278 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002279#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002280#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2281 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2282 PyLong_FromUnsignedLong(st->st_file_attributes));
2283#endif
jcea6c51d512018-01-28 14:00:08 +01002284#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2285 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2286 PyUnicode_FromString(st->st_fstype));
2287#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002288#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2289 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2290 PyLong_FromUnsignedLong(st->st_reparse_tag));
2291#endif
Fred Drake699f3522000-06-29 21:12:41 +00002292
Victor Stinner8c62be82010-05-06 00:08:46 +00002293 if (PyErr_Occurred()) {
2294 Py_DECREF(v);
2295 return NULL;
2296 }
Fred Drake699f3522000-06-29 21:12:41 +00002297
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002299}
2300
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002301/* POSIX methods */
2302
Guido van Rossum94f6f721999-01-06 18:42:14 +00002303
2304static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002305posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002306 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002307{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002308 STRUCT_STAT st;
2309 int result;
2310
2311#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2312 if (follow_symlinks_specified(function_name, follow_symlinks))
2313 return NULL;
2314#endif
2315
2316 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2317 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2318 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2319 return NULL;
2320
2321 Py_BEGIN_ALLOW_THREADS
2322 if (path->fd != -1)
2323 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002324#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002325 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002326 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002327 else
Steve Dowercc16be82016-09-08 10:35:16 -07002328 result = win32_lstat(path->wide, &st);
2329#else
2330 else
2331#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002332 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2333 result = LSTAT(path->narrow, &st);
2334 else
Steve Dowercc16be82016-09-08 10:35:16 -07002335#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002336#ifdef HAVE_FSTATAT
2337 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2338 result = fstatat(dir_fd, path->narrow, &st,
2339 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2340 else
Steve Dowercc16be82016-09-08 10:35:16 -07002341#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002342 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002343#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002344 Py_END_ALLOW_THREADS
2345
Victor Stinner292c8352012-10-30 02:17:38 +01002346 if (result != 0) {
2347 return path_error(path);
2348 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002349
2350 return _pystat_fromstructstat(&st);
2351}
2352
Larry Hastings2f936352014-08-05 14:04:04 +10002353/*[python input]
2354
2355for s in """
2356
2357FACCESSAT
2358FCHMODAT
2359FCHOWNAT
2360FSTATAT
2361LINKAT
2362MKDIRAT
2363MKFIFOAT
2364MKNODAT
2365OPENAT
2366READLINKAT
2367SYMLINKAT
2368UNLINKAT
2369
2370""".strip().split():
2371 s = s.strip()
2372 print("""
2373#ifdef HAVE_{s}
2374 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002375#else
Larry Hastings2f936352014-08-05 14:04:04 +10002376 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002377#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002378""".rstrip().format(s=s))
2379
2380for s in """
2381
2382FCHDIR
2383FCHMOD
2384FCHOWN
2385FDOPENDIR
2386FEXECVE
2387FPATHCONF
2388FSTATVFS
2389FTRUNCATE
2390
2391""".strip().split():
2392 s = s.strip()
2393 print("""
2394#ifdef HAVE_{s}
2395 #define PATH_HAVE_{s} 1
2396#else
2397 #define PATH_HAVE_{s} 0
2398#endif
2399
2400""".rstrip().format(s=s))
2401[python start generated code]*/
2402
2403#ifdef HAVE_FACCESSAT
2404 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2405#else
2406 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2407#endif
2408
2409#ifdef HAVE_FCHMODAT
2410 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2411#else
2412 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2413#endif
2414
2415#ifdef HAVE_FCHOWNAT
2416 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2417#else
2418 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2419#endif
2420
2421#ifdef HAVE_FSTATAT
2422 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2423#else
2424 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2425#endif
2426
2427#ifdef HAVE_LINKAT
2428 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2429#else
2430 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2431#endif
2432
2433#ifdef HAVE_MKDIRAT
2434 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2435#else
2436 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2437#endif
2438
2439#ifdef HAVE_MKFIFOAT
2440 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2441#else
2442 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2443#endif
2444
2445#ifdef HAVE_MKNODAT
2446 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2447#else
2448 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2449#endif
2450
2451#ifdef HAVE_OPENAT
2452 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2453#else
2454 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2455#endif
2456
2457#ifdef HAVE_READLINKAT
2458 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2459#else
2460 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2461#endif
2462
2463#ifdef HAVE_SYMLINKAT
2464 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2465#else
2466 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2467#endif
2468
2469#ifdef HAVE_UNLINKAT
2470 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2471#else
2472 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2473#endif
2474
2475#ifdef HAVE_FCHDIR
2476 #define PATH_HAVE_FCHDIR 1
2477#else
2478 #define PATH_HAVE_FCHDIR 0
2479#endif
2480
2481#ifdef HAVE_FCHMOD
2482 #define PATH_HAVE_FCHMOD 1
2483#else
2484 #define PATH_HAVE_FCHMOD 0
2485#endif
2486
2487#ifdef HAVE_FCHOWN
2488 #define PATH_HAVE_FCHOWN 1
2489#else
2490 #define PATH_HAVE_FCHOWN 0
2491#endif
2492
2493#ifdef HAVE_FDOPENDIR
2494 #define PATH_HAVE_FDOPENDIR 1
2495#else
2496 #define PATH_HAVE_FDOPENDIR 0
2497#endif
2498
2499#ifdef HAVE_FEXECVE
2500 #define PATH_HAVE_FEXECVE 1
2501#else
2502 #define PATH_HAVE_FEXECVE 0
2503#endif
2504
2505#ifdef HAVE_FPATHCONF
2506 #define PATH_HAVE_FPATHCONF 1
2507#else
2508 #define PATH_HAVE_FPATHCONF 0
2509#endif
2510
2511#ifdef HAVE_FSTATVFS
2512 #define PATH_HAVE_FSTATVFS 1
2513#else
2514 #define PATH_HAVE_FSTATVFS 0
2515#endif
2516
2517#ifdef HAVE_FTRUNCATE
2518 #define PATH_HAVE_FTRUNCATE 1
2519#else
2520 #define PATH_HAVE_FTRUNCATE 0
2521#endif
2522/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002523
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002524#ifdef MS_WINDOWS
2525 #undef PATH_HAVE_FTRUNCATE
2526 #define PATH_HAVE_FTRUNCATE 1
2527#endif
Larry Hastings31826802013-10-19 00:09:25 -07002528
Larry Hastings61272b72014-01-07 12:41:53 -08002529/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002530
2531class path_t_converter(CConverter):
2532
2533 type = "path_t"
2534 impl_by_reference = True
2535 parse_by_reference = True
2536
2537 converter = 'path_converter'
2538
2539 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002540 # right now path_t doesn't support default values.
2541 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002542 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002543 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002544
Larry Hastings2f936352014-08-05 14:04:04 +10002545 if self.c_default not in (None, 'Py_None'):
2546 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002547
2548 self.nullable = nullable
2549 self.allow_fd = allow_fd
2550
Larry Hastings7726ac92014-01-31 22:03:12 -08002551 def pre_render(self):
2552 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002553 if isinstance(value, str):
2554 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002555 return str(int(bool(value)))
2556
2557 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002558 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002559 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002560 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002561 strify(self.nullable),
2562 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002563 )
2564
2565 def cleanup(self):
2566 return "path_cleanup(&" + self.name + ");\n"
2567
2568
2569class dir_fd_converter(CConverter):
2570 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002571
Larry Hastings2f936352014-08-05 14:04:04 +10002572 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002573 if self.default in (unspecified, None):
2574 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002575 if isinstance(requires, str):
2576 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2577 else:
2578 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002579
Larry Hastings2f936352014-08-05 14:04:04 +10002580class fildes_converter(CConverter):
2581 type = 'int'
2582 converter = 'fildes_converter'
2583
2584class uid_t_converter(CConverter):
2585 type = "uid_t"
2586 converter = '_Py_Uid_Converter'
2587
2588class gid_t_converter(CConverter):
2589 type = "gid_t"
2590 converter = '_Py_Gid_Converter'
2591
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002592class dev_t_converter(CConverter):
2593 type = 'dev_t'
2594 converter = '_Py_Dev_Converter'
2595
2596class dev_t_return_converter(unsigned_long_return_converter):
2597 type = 'dev_t'
2598 conversion_fn = '_PyLong_FromDev'
2599 unsigned_cast = '(dev_t)'
2600
Larry Hastings2f936352014-08-05 14:04:04 +10002601class FSConverter_converter(CConverter):
2602 type = 'PyObject *'
2603 converter = 'PyUnicode_FSConverter'
2604 def converter_init(self):
2605 if self.default is not unspecified:
2606 fail("FSConverter_converter does not support default values")
2607 self.c_default = 'NULL'
2608
2609 def cleanup(self):
2610 return "Py_XDECREF(" + self.name + ");\n"
2611
2612class pid_t_converter(CConverter):
2613 type = 'pid_t'
2614 format_unit = '" _Py_PARSE_PID "'
2615
2616class idtype_t_converter(int_converter):
2617 type = 'idtype_t'
2618
2619class id_t_converter(CConverter):
2620 type = 'id_t'
2621 format_unit = '" _Py_PARSE_PID "'
2622
Benjamin Petersonca470632016-09-06 13:47:26 -07002623class intptr_t_converter(CConverter):
2624 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002625 format_unit = '" _Py_PARSE_INTPTR "'
2626
2627class Py_off_t_converter(CConverter):
2628 type = 'Py_off_t'
2629 converter = 'Py_off_t_converter'
2630
2631class Py_off_t_return_converter(long_return_converter):
2632 type = 'Py_off_t'
2633 conversion_fn = 'PyLong_FromPy_off_t'
2634
2635class path_confname_converter(CConverter):
2636 type="int"
2637 converter="conv_path_confname"
2638
2639class confstr_confname_converter(path_confname_converter):
2640 converter='conv_confstr_confname'
2641
2642class sysconf_confname_converter(path_confname_converter):
2643 converter="conv_sysconf_confname"
2644
2645class sched_param_converter(CConverter):
2646 type = 'struct sched_param'
2647 converter = 'convert_sched_param'
2648 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002649
Larry Hastings61272b72014-01-07 12:41:53 -08002650[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002651/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002652
Larry Hastings61272b72014-01-07 12:41:53 -08002653/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002654
Larry Hastings2a727912014-01-16 11:32:01 -08002655os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002656
2657 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002658 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002659 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002660
2661 *
2662
Larry Hastings2f936352014-08-05 14:04:04 +10002663 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002664 If not None, it should be a file descriptor open to a directory,
2665 and path should be a relative string; path will then be relative to
2666 that directory.
2667
2668 follow_symlinks: bool = True
2669 If False, and the last element of the path is a symbolic link,
2670 stat will examine the symbolic link itself instead of the file
2671 the link points to.
2672
2673Perform a stat system call on the given path.
2674
2675dir_fd and follow_symlinks may not be implemented
2676 on your platform. If they are unavailable, using them will raise a
2677 NotImplementedError.
2678
2679It's an error to use dir_fd or follow_symlinks when specifying path as
2680 an open file descriptor.
2681
Larry Hastings61272b72014-01-07 12:41:53 -08002682[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002683
Larry Hastings31826802013-10-19 00:09:25 -07002684static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002685os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002686/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002687{
2688 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2689}
2690
Larry Hastings2f936352014-08-05 14:04:04 +10002691
2692/*[clinic input]
2693os.lstat
2694
2695 path : path_t
2696
2697 *
2698
2699 dir_fd : dir_fd(requires='fstatat') = None
2700
2701Perform a stat system call on the given path, without following symbolic links.
2702
2703Like stat(), but do not follow symbolic links.
2704Equivalent to stat(path, follow_symlinks=False).
2705[clinic start generated code]*/
2706
Larry Hastings2f936352014-08-05 14:04:04 +10002707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002708os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2709/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002710{
2711 int follow_symlinks = 0;
2712 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2713}
Larry Hastings31826802013-10-19 00:09:25 -07002714
Larry Hastings2f936352014-08-05 14:04:04 +10002715
Larry Hastings61272b72014-01-07 12:41:53 -08002716/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002717os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002718
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002719 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002720 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002721
2722 mode: int
2723 Operating-system mode bitfield. Can be F_OK to test existence,
2724 or the inclusive-OR of R_OK, W_OK, and X_OK.
2725
2726 *
2727
Larry Hastings2f936352014-08-05 14:04:04 +10002728 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002729 If not None, it should be a file descriptor open to a directory,
2730 and path should be relative; path will then be relative to that
2731 directory.
2732
2733 effective_ids: bool = False
2734 If True, access will use the effective uid/gid instead of
2735 the real uid/gid.
2736
2737 follow_symlinks: bool = True
2738 If False, and the last element of the path is a symbolic link,
2739 access will examine the symbolic link itself instead of the file
2740 the link points to.
2741
2742Use the real uid/gid to test for access to a path.
2743
2744{parameters}
2745dir_fd, effective_ids, and follow_symlinks may not be implemented
2746 on your platform. If they are unavailable, using them will raise a
2747 NotImplementedError.
2748
2749Note that most operations will use the effective uid/gid, therefore this
2750 routine can be used in a suid/sgid environment to test if the invoking user
2751 has the specified access to the path.
2752
Larry Hastings61272b72014-01-07 12:41:53 -08002753[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002754
Larry Hastings2f936352014-08-05 14:04:04 +10002755static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002756os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002757 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002758/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002759{
Larry Hastings2f936352014-08-05 14:04:04 +10002760 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002761
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002762#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002763 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002764#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002765 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002766#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002767
Larry Hastings9cf065c2012-06-22 16:30:09 -07002768#ifndef HAVE_FACCESSAT
2769 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002770 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002771
2772 if (effective_ids) {
2773 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002774 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002775 }
2776#endif
2777
2778#ifdef MS_WINDOWS
2779 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002780 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002781 Py_END_ALLOW_THREADS
2782
2783 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002784 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002785 * * we didn't get a -1, and
2786 * * write access wasn't requested,
2787 * * or the file isn't read-only,
2788 * * or it's a directory.
2789 * (Directories cannot be read-only on Windows.)
2790 */
Larry Hastings2f936352014-08-05 14:04:04 +10002791 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002792 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002794 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795#else
2796
2797 Py_BEGIN_ALLOW_THREADS
2798#ifdef HAVE_FACCESSAT
2799 if ((dir_fd != DEFAULT_DIR_FD) ||
2800 effective_ids ||
2801 !follow_symlinks) {
2802 int flags = 0;
2803 if (!follow_symlinks)
2804 flags |= AT_SYMLINK_NOFOLLOW;
2805 if (effective_ids)
2806 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002807 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808 }
2809 else
2810#endif
Larry Hastings31826802013-10-19 00:09:25 -07002811 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002812 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002813 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002814#endif
2815
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002817}
2818
Guido van Rossumd371ff11999-01-25 16:12:23 +00002819#ifndef F_OK
2820#define F_OK 0
2821#endif
2822#ifndef R_OK
2823#define R_OK 4
2824#endif
2825#ifndef W_OK
2826#define W_OK 2
2827#endif
2828#ifndef X_OK
2829#define X_OK 1
2830#endif
2831
Larry Hastings31826802013-10-19 00:09:25 -07002832
Guido van Rossumd371ff11999-01-25 16:12:23 +00002833#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002834/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002835os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002836
2837 fd: int
2838 Integer file descriptor handle.
2839
2840 /
2841
2842Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002843[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002844
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002845static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002846os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002847/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002848{
Guido van Rossum94f6f721999-01-06 18:42:14 +00002849
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002850 long size = sysconf(_SC_TTY_NAME_MAX);
2851 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002852 return posix_error();
2853 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002854 char *buffer = (char *)PyMem_RawMalloc(size);
2855 if (buffer == NULL) {
2856 return PyErr_NoMemory();
2857 }
2858 int ret = ttyname_r(fd, buffer, size);
2859 if (ret != 0) {
2860 PyMem_RawFree(buffer);
2861 errno = ret;
2862 return posix_error();
2863 }
2864 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
2865 PyMem_RawFree(buffer);
2866 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002867}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002868#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002869
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002870#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002871/*[clinic input]
2872os.ctermid
2873
2874Return the name of the controlling terminal for this process.
2875[clinic start generated code]*/
2876
Larry Hastings2f936352014-08-05 14:04:04 +10002877static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002878os_ctermid_impl(PyObject *module)
2879/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002880{
Victor Stinner8c62be82010-05-06 00:08:46 +00002881 char *ret;
2882 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002883
Greg Wardb48bc172000-03-01 21:51:56 +00002884#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002885 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002886#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002887 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002888#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002889 if (ret == NULL)
2890 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002891 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002892}
Larry Hastings2f936352014-08-05 14:04:04 +10002893#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002894
Larry Hastings2f936352014-08-05 14:04:04 +10002895
2896/*[clinic input]
2897os.chdir
2898
2899 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2900
2901Change the current working directory to the specified path.
2902
2903path may always be specified as a string.
2904On some platforms, path may also be specified as an open file descriptor.
2905 If this functionality is unavailable, using it raises an exception.
2906[clinic start generated code]*/
2907
Larry Hastings2f936352014-08-05 14:04:04 +10002908static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002909os_chdir_impl(PyObject *module, path_t *path)
2910/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002911{
2912 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002913
Saiyang Gou7514f4f2020-02-12 23:47:42 -08002914 if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
2915 return NULL;
2916 }
2917
Larry Hastings9cf065c2012-06-22 16:30:09 -07002918 Py_BEGIN_ALLOW_THREADS
2919#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002920 /* on unix, success = 0, on windows, success = !0 */
2921 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002922#else
2923#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002924 if (path->fd != -1)
2925 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002926 else
2927#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002928 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002929#endif
2930 Py_END_ALLOW_THREADS
2931
2932 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002933 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002934 }
2935
Larry Hastings2f936352014-08-05 14:04:04 +10002936 Py_RETURN_NONE;
2937}
2938
2939
2940#ifdef HAVE_FCHDIR
2941/*[clinic input]
2942os.fchdir
2943
2944 fd: fildes
2945
2946Change to the directory of the given file descriptor.
2947
2948fd must be opened on a directory, not a file.
2949Equivalent to os.chdir(fd).
2950
2951[clinic start generated code]*/
2952
Fred Drake4d1e64b2002-04-15 19:40:07 +00002953static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002954os_fchdir_impl(PyObject *module, int fd)
2955/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002956{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08002957 if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
2958 return NULL;
2959 }
Larry Hastings2f936352014-08-05 14:04:04 +10002960 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002961}
2962#endif /* HAVE_FCHDIR */
2963
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002964
Larry Hastings2f936352014-08-05 14:04:04 +10002965/*[clinic input]
2966os.chmod
2967
2968 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002969 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002970 On some platforms, path may also be specified as an open file descriptor.
2971 If this functionality is unavailable, using it raises an exception.
2972
2973 mode: int
2974 Operating-system mode bitfield.
2975
2976 *
2977
2978 dir_fd : dir_fd(requires='fchmodat') = None
2979 If not None, it should be a file descriptor open to a directory,
2980 and path should be relative; path will then be relative to that
2981 directory.
2982
2983 follow_symlinks: bool = True
2984 If False, and the last element of the path is a symbolic link,
2985 chmod will modify the symbolic link itself instead of the file
2986 the link points to.
2987
2988Change the access permissions of a file.
2989
2990It is an error to use dir_fd or follow_symlinks when specifying path as
2991 an open file descriptor.
2992dir_fd and follow_symlinks may not be implemented on your platform.
2993 If they are unavailable, using them will raise a NotImplementedError.
2994
2995[clinic start generated code]*/
2996
Larry Hastings2f936352014-08-05 14:04:04 +10002997static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002998os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002999 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003000/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003001{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003002 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003003
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003004#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003005 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003006#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003007
Larry Hastings9cf065c2012-06-22 16:30:09 -07003008#ifdef HAVE_FCHMODAT
3009 int fchmodat_nofollow_unsupported = 0;
3010#endif
3011
Larry Hastings9cf065c2012-06-22 16:30:09 -07003012#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3013 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003014 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003015#endif
3016
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003017 if (PySys_Audit("os.chmod", "Oii", path->object, mode,
3018 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3019 return NULL;
3020 }
3021
Larry Hastings9cf065c2012-06-22 16:30:09 -07003022#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003023 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003024 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003025 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003026 result = 0;
3027 else {
3028 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003029 attr &= ~FILE_ATTRIBUTE_READONLY;
3030 else
3031 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003032 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003033 }
3034 Py_END_ALLOW_THREADS
3035
3036 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003037 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003038 }
3039#else /* MS_WINDOWS */
3040 Py_BEGIN_ALLOW_THREADS
3041#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003042 if (path->fd != -1)
3043 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003044 else
3045#endif
3046#ifdef HAVE_LCHMOD
3047 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003048 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003049 else
3050#endif
3051#ifdef HAVE_FCHMODAT
3052 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
3053 /*
3054 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3055 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003056 * and then says it isn't implemented yet.
3057 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003058 *
3059 * Once it is supported, os.chmod will automatically
3060 * support dir_fd and follow_symlinks=False. (Hopefully.)
3061 * Until then, we need to be careful what exception we raise.
3062 */
Larry Hastings2f936352014-08-05 14:04:04 +10003063 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003064 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3065 /*
3066 * But wait! We can't throw the exception without allowing threads,
3067 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3068 */
3069 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003070 result &&
3071 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3072 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003073 }
3074 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003075#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003076 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003077 Py_END_ALLOW_THREADS
3078
3079 if (result) {
3080#ifdef HAVE_FCHMODAT
3081 if (fchmodat_nofollow_unsupported) {
3082 if (dir_fd != DEFAULT_DIR_FD)
3083 dir_fd_and_follow_symlinks_invalid("chmod",
3084 dir_fd, follow_symlinks);
3085 else
3086 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003087 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003088 }
3089 else
3090#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003091 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003092 }
3093#endif
3094
Larry Hastings2f936352014-08-05 14:04:04 +10003095 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003096}
3097
Larry Hastings9cf065c2012-06-22 16:30:09 -07003098
Christian Heimes4e30a842007-11-30 22:12:06 +00003099#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003100/*[clinic input]
3101os.fchmod
3102
3103 fd: int
3104 mode: int
3105
3106Change the access permissions of the file given by file descriptor fd.
3107
3108Equivalent to os.chmod(fd, mode).
3109[clinic start generated code]*/
3110
Larry Hastings2f936352014-08-05 14:04:04 +10003111static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003112os_fchmod_impl(PyObject *module, int fd, int mode)
3113/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003114{
3115 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003116 int async_err = 0;
3117
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003118 if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
3119 return NULL;
3120 }
3121
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003122 do {
3123 Py_BEGIN_ALLOW_THREADS
3124 res = fchmod(fd, mode);
3125 Py_END_ALLOW_THREADS
3126 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3127 if (res != 0)
3128 return (!async_err) ? posix_error() : NULL;
3129
Victor Stinner8c62be82010-05-06 00:08:46 +00003130 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003131}
3132#endif /* HAVE_FCHMOD */
3133
Larry Hastings2f936352014-08-05 14:04:04 +10003134
Christian Heimes4e30a842007-11-30 22:12:06 +00003135#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003136/*[clinic input]
3137os.lchmod
3138
3139 path: path_t
3140 mode: int
3141
3142Change the access permissions of a file, without following symbolic links.
3143
3144If path is a symlink, this affects the link itself rather than the target.
3145Equivalent to chmod(path, mode, follow_symlinks=False)."
3146[clinic start generated code]*/
3147
Larry Hastings2f936352014-08-05 14:04:04 +10003148static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003149os_lchmod_impl(PyObject *module, path_t *path, int mode)
3150/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003151{
Victor Stinner8c62be82010-05-06 00:08:46 +00003152 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003153 if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3154 return NULL;
3155 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003157 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003158 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003159 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003160 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003161 return NULL;
3162 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003163 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003164}
3165#endif /* HAVE_LCHMOD */
3166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003167
Thomas Wouterscf297e42007-02-23 15:07:44 +00003168#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003169/*[clinic input]
3170os.chflags
3171
3172 path: path_t
3173 flags: unsigned_long(bitwise=True)
3174 follow_symlinks: bool=True
3175
3176Set file flags.
3177
3178If follow_symlinks is False, and the last element of the path is a symbolic
3179 link, chflags will change flags on the symbolic link itself instead of the
3180 file the link points to.
3181follow_symlinks may not be implemented on your platform. If it is
3182unavailable, using it will raise a NotImplementedError.
3183
3184[clinic start generated code]*/
3185
Larry Hastings2f936352014-08-05 14:04:04 +10003186static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003187os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003188 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003189/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003190{
3191 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192
3193#ifndef HAVE_LCHFLAGS
3194 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003195 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003196#endif
3197
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003198 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3199 return NULL;
3200 }
3201
Victor Stinner8c62be82010-05-06 00:08:46 +00003202 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003203#ifdef HAVE_LCHFLAGS
3204 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003205 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003206 else
3207#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003208 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003209 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003210
Larry Hastings2f936352014-08-05 14:04:04 +10003211 if (result)
3212 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003213
Larry Hastings2f936352014-08-05 14:04:04 +10003214 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003215}
3216#endif /* HAVE_CHFLAGS */
3217
Larry Hastings2f936352014-08-05 14:04:04 +10003218
Thomas Wouterscf297e42007-02-23 15:07:44 +00003219#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003220/*[clinic input]
3221os.lchflags
3222
3223 path: path_t
3224 flags: unsigned_long(bitwise=True)
3225
3226Set file flags.
3227
3228This function will not follow symbolic links.
3229Equivalent to chflags(path, flags, follow_symlinks=False).
3230[clinic start generated code]*/
3231
Larry Hastings2f936352014-08-05 14:04:04 +10003232static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003233os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3234/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003235{
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003237 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3238 return NULL;
3239 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003241 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003242 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003243 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003244 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003245 }
Victor Stinner292c8352012-10-30 02:17:38 +01003246 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003247}
3248#endif /* HAVE_LCHFLAGS */
3249
Larry Hastings2f936352014-08-05 14:04:04 +10003250
Martin v. Löwis244edc82001-10-04 22:44:26 +00003251#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003252/*[clinic input]
3253os.chroot
3254 path: path_t
3255
3256Change root directory to path.
3257
3258[clinic start generated code]*/
3259
Larry Hastings2f936352014-08-05 14:04:04 +10003260static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003261os_chroot_impl(PyObject *module, path_t *path)
3262/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003263{
3264 int res;
3265 Py_BEGIN_ALLOW_THREADS
3266 res = chroot(path->narrow);
3267 Py_END_ALLOW_THREADS
3268 if (res < 0)
3269 return path_error(path);
3270 Py_RETURN_NONE;
3271}
3272#endif /* HAVE_CHROOT */
3273
Martin v. Löwis244edc82001-10-04 22:44:26 +00003274
Guido van Rossum21142a01999-01-08 21:05:37 +00003275#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003276/*[clinic input]
3277os.fsync
3278
3279 fd: fildes
3280
3281Force write of fd to disk.
3282[clinic start generated code]*/
3283
Larry Hastings2f936352014-08-05 14:04:04 +10003284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003285os_fsync_impl(PyObject *module, int fd)
3286/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003287{
3288 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003289}
3290#endif /* HAVE_FSYNC */
3291
Larry Hastings2f936352014-08-05 14:04:04 +10003292
Ross Lagerwall7807c352011-03-17 20:20:30 +02003293#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003294/*[clinic input]
3295os.sync
3296
3297Force write of everything to disk.
3298[clinic start generated code]*/
3299
Larry Hastings2f936352014-08-05 14:04:04 +10003300static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003301os_sync_impl(PyObject *module)
3302/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003303{
3304 Py_BEGIN_ALLOW_THREADS
3305 sync();
3306 Py_END_ALLOW_THREADS
3307 Py_RETURN_NONE;
3308}
Larry Hastings2f936352014-08-05 14:04:04 +10003309#endif /* HAVE_SYNC */
3310
Ross Lagerwall7807c352011-03-17 20:20:30 +02003311
Guido van Rossum21142a01999-01-08 21:05:37 +00003312#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003313#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003314extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3315#endif
3316
Larry Hastings2f936352014-08-05 14:04:04 +10003317/*[clinic input]
3318os.fdatasync
3319
3320 fd: fildes
3321
3322Force write of fd to disk without forcing update of metadata.
3323[clinic start generated code]*/
3324
Larry Hastings2f936352014-08-05 14:04:04 +10003325static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003326os_fdatasync_impl(PyObject *module, int fd)
3327/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003328{
3329 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003330}
3331#endif /* HAVE_FDATASYNC */
3332
3333
Fredrik Lundh10723342000-07-10 16:38:09 +00003334#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003335/*[clinic input]
3336os.chown
3337
3338 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003339 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003340
3341 uid: uid_t
3342
3343 gid: gid_t
3344
3345 *
3346
3347 dir_fd : dir_fd(requires='fchownat') = None
3348 If not None, it should be a file descriptor open to a directory,
3349 and path should be relative; path will then be relative to that
3350 directory.
3351
3352 follow_symlinks: bool = True
3353 If False, and the last element of the path is a symbolic link,
3354 stat will examine the symbolic link itself instead of the file
3355 the link points to.
3356
3357Change the owner and group id of path to the numeric uid and gid.\
3358
3359path may always be specified as a string.
3360On some platforms, path may also be specified as an open file descriptor.
3361 If this functionality is unavailable, using it raises an exception.
3362If dir_fd is not None, it should be a file descriptor open to a directory,
3363 and path should be relative; path will then be relative to that directory.
3364If follow_symlinks is False, and the last element of the path is a symbolic
3365 link, chown will modify the symbolic link itself instead of the file the
3366 link points to.
3367It is an error to use dir_fd or follow_symlinks when specifying path as
3368 an open file descriptor.
3369dir_fd and follow_symlinks may not be implemented on your platform.
3370 If they are unavailable, using them will raise a NotImplementedError.
3371
3372[clinic start generated code]*/
3373
Larry Hastings2f936352014-08-05 14:04:04 +10003374static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003375os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003376 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003377/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003378{
3379 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003380
3381#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3382 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003383 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003384#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003385 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3386 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3387 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388
3389#ifdef __APPLE__
3390 /*
3391 * This is for Mac OS X 10.3, which doesn't have lchown.
3392 * (But we still have an lchown symbol because of weak-linking.)
3393 * It doesn't have fchownat either. So there's no possibility
3394 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003395 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003396 if ((!follow_symlinks) && (lchown == NULL)) {
3397 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003398 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003399 }
3400#endif
3401
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003402 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
3403 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3404 return NULL;
3405 }
3406
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003409 if (path->fd != -1)
3410 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411 else
3412#endif
3413#ifdef HAVE_LCHOWN
3414 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003415 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416 else
3417#endif
3418#ifdef HAVE_FCHOWNAT
3419 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003420 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003421 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3422 else
3423#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003424 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003425 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426
Larry Hastings2f936352014-08-05 14:04:04 +10003427 if (result)
3428 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003429
Larry Hastings2f936352014-08-05 14:04:04 +10003430 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003431}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003432#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003433
Larry Hastings2f936352014-08-05 14:04:04 +10003434
Christian Heimes4e30a842007-11-30 22:12:06 +00003435#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003436/*[clinic input]
3437os.fchown
3438
3439 fd: int
3440 uid: uid_t
3441 gid: gid_t
3442
3443Change the owner and group id of the file specified by file descriptor.
3444
3445Equivalent to os.chown(fd, uid, gid).
3446
3447[clinic start generated code]*/
3448
Larry Hastings2f936352014-08-05 14:04:04 +10003449static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003450os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3451/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003452{
Victor Stinner8c62be82010-05-06 00:08:46 +00003453 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003454 int async_err = 0;
3455
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003456 if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
3457 return NULL;
3458 }
3459
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003460 do {
3461 Py_BEGIN_ALLOW_THREADS
3462 res = fchown(fd, uid, gid);
3463 Py_END_ALLOW_THREADS
3464 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3465 if (res != 0)
3466 return (!async_err) ? posix_error() : NULL;
3467
Victor Stinner8c62be82010-05-06 00:08:46 +00003468 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003469}
3470#endif /* HAVE_FCHOWN */
3471
Larry Hastings2f936352014-08-05 14:04:04 +10003472
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003473#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003474/*[clinic input]
3475os.lchown
3476
3477 path : path_t
3478 uid: uid_t
3479 gid: gid_t
3480
3481Change the owner and group id of path to the numeric uid and gid.
3482
3483This function will not follow symbolic links.
3484Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3485[clinic start generated code]*/
3486
Larry Hastings2f936352014-08-05 14:04:04 +10003487static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003488os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3489/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003490{
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003492 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
3493 return NULL;
3494 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003495 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003496 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003497 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003498 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003499 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003500 }
Larry Hastings2f936352014-08-05 14:04:04 +10003501 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003502}
3503#endif /* HAVE_LCHOWN */
3504
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003505
Barry Warsaw53699e91996-12-10 23:23:01 +00003506static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003507posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003508{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003509#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003510 wchar_t wbuf[MAXPATHLEN];
3511 wchar_t *wbuf2 = wbuf;
3512 DWORD len;
3513
3514 Py_BEGIN_ALLOW_THREADS
3515 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3516 /* If the buffer is large enough, len does not include the
3517 terminating \0. If the buffer is too small, len includes
3518 the space needed for the terminator. */
3519 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003520 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003521 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 }
Victor Stinner689830e2019-06-26 17:31:12 +02003523 else {
3524 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003525 }
Victor Stinner689830e2019-06-26 17:31:12 +02003526 if (wbuf2) {
3527 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 }
Victor Stinner689830e2019-06-26 17:31:12 +02003529 }
3530 Py_END_ALLOW_THREADS
3531
3532 if (!wbuf2) {
3533 PyErr_NoMemory();
3534 return NULL;
3535 }
3536 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003537 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003538 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003539 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003541
Victor Stinner689830e2019-06-26 17:31:12 +02003542 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3543 if (wbuf2 != wbuf) {
3544 PyMem_RawFree(wbuf2);
3545 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003546
Victor Stinner689830e2019-06-26 17:31:12 +02003547 if (use_bytes) {
3548 if (resobj == NULL) {
3549 return NULL;
3550 }
3551 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3552 }
3553
3554 return resobj;
3555#else
3556 const size_t chunk = 1024;
3557
3558 char *buf = NULL;
3559 char *cwd = NULL;
3560 size_t buflen = 0;
3561
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003563 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003564 char *newbuf;
3565 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3566 buflen += chunk;
3567 newbuf = PyMem_RawRealloc(buf, buflen);
3568 }
3569 else {
3570 newbuf = NULL;
3571 }
3572 if (newbuf == NULL) {
3573 PyMem_RawFree(buf);
3574 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003575 break;
3576 }
Victor Stinner689830e2019-06-26 17:31:12 +02003577 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003578
Victor Stinner4403d7d2015-04-25 00:16:10 +02003579 cwd = getcwd(buf, buflen);
3580 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003581 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003582
Victor Stinner689830e2019-06-26 17:31:12 +02003583 if (buf == NULL) {
3584 return PyErr_NoMemory();
3585 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003586 if (cwd == NULL) {
3587 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003588 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003589 }
3590
Victor Stinner689830e2019-06-26 17:31:12 +02003591 PyObject *obj;
3592 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003593 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003594 }
3595 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003596 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003597 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003598 PyMem_RawFree(buf);
3599
3600 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003601#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003602}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003603
Larry Hastings2f936352014-08-05 14:04:04 +10003604
3605/*[clinic input]
3606os.getcwd
3607
3608Return a unicode string representing the current working directory.
3609[clinic start generated code]*/
3610
Larry Hastings2f936352014-08-05 14:04:04 +10003611static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003612os_getcwd_impl(PyObject *module)
3613/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003614{
3615 return posix_getcwd(0);
3616}
3617
Larry Hastings2f936352014-08-05 14:04:04 +10003618
3619/*[clinic input]
3620os.getcwdb
3621
3622Return a bytes string representing the current working directory.
3623[clinic start generated code]*/
3624
Larry Hastings2f936352014-08-05 14:04:04 +10003625static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003626os_getcwdb_impl(PyObject *module)
3627/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003628{
3629 return posix_getcwd(1);
3630}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003631
Larry Hastings2f936352014-08-05 14:04:04 +10003632
Larry Hastings9cf065c2012-06-22 16:30:09 -07003633#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3634#define HAVE_LINK 1
3635#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003636
Guido van Rossumb6775db1994-08-01 11:34:53 +00003637#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003638/*[clinic input]
3639
3640os.link
3641
3642 src : path_t
3643 dst : path_t
3644 *
3645 src_dir_fd : dir_fd = None
3646 dst_dir_fd : dir_fd = None
3647 follow_symlinks: bool = True
3648
3649Create a hard link to a file.
3650
3651If either src_dir_fd or dst_dir_fd is not None, it should be a file
3652 descriptor open to a directory, and the respective path string (src or dst)
3653 should be relative; the path will then be relative to that directory.
3654If follow_symlinks is False, and the last element of src is a symbolic
3655 link, link will create a link to the symbolic link itself instead of the
3656 file the link points to.
3657src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3658 platform. If they are unavailable, using them will raise a
3659 NotImplementedError.
3660[clinic start generated code]*/
3661
Larry Hastings2f936352014-08-05 14:04:04 +10003662static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003663os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003664 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003665/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003666{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003667#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003668 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003669#else
3670 int result;
3671#endif
3672
Larry Hastings9cf065c2012-06-22 16:30:09 -07003673#ifndef HAVE_LINKAT
3674 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3675 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003676 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003677 }
3678#endif
3679
Steve Dowercc16be82016-09-08 10:35:16 -07003680#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003681 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003682 PyErr_SetString(PyExc_NotImplementedError,
3683 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003684 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003685 }
Steve Dowercc16be82016-09-08 10:35:16 -07003686#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003687
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003688 if (PySys_Audit("os.link", "OOii", src->object, dst->object,
3689 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
3690 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
3691 return NULL;
3692 }
3693
Brian Curtin1b9df392010-11-24 20:24:31 +00003694#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003695 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003696 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003697 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003698
Larry Hastings2f936352014-08-05 14:04:04 +10003699 if (!result)
3700 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003701#else
3702 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003703#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003704 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3705 (dst_dir_fd != DEFAULT_DIR_FD) ||
3706 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003707 result = linkat(src_dir_fd, src->narrow,
3708 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003709 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3710 else
Steve Dowercc16be82016-09-08 10:35:16 -07003711#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003712 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003713 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003714
Larry Hastings2f936352014-08-05 14:04:04 +10003715 if (result)
3716 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003717#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003718
Larry Hastings2f936352014-08-05 14:04:04 +10003719 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003720}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003721#endif
3722
Brian Curtin1b9df392010-11-24 20:24:31 +00003723
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003724#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003725static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003726_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003727{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 PyObject *v;
3729 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3730 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003731 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003732 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003733 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003734 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003735
Steve Dowercc16be82016-09-08 10:35:16 -07003736 WIN32_FIND_DATAW wFileData;
3737 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003738
Steve Dowercc16be82016-09-08 10:35:16 -07003739 if (!path->wide) { /* Default arg: "." */
3740 po_wchars = L".";
3741 len = 1;
3742 } else {
3743 po_wchars = path->wide;
3744 len = wcslen(path->wide);
3745 }
3746 /* The +5 is so we can append "\\*.*\0" */
3747 wnamebuf = PyMem_New(wchar_t, len + 5);
3748 if (!wnamebuf) {
3749 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003750 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003751 }
Steve Dowercc16be82016-09-08 10:35:16 -07003752 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003753 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003754 wchar_t wch = wnamebuf[len-1];
3755 if (wch != SEP && wch != ALTSEP && wch != L':')
3756 wnamebuf[len++] = SEP;
3757 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003758 }
Steve Dowercc16be82016-09-08 10:35:16 -07003759 if ((list = PyList_New(0)) == NULL) {
3760 goto exit;
3761 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003762 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003763 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003764 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003765 if (hFindFile == INVALID_HANDLE_VALUE) {
3766 int error = GetLastError();
3767 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003768 goto exit;
3769 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003770 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003771 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003772 }
3773 do {
3774 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003775 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3776 wcscmp(wFileData.cFileName, L"..") != 0) {
3777 v = PyUnicode_FromWideChar(wFileData.cFileName,
3778 wcslen(wFileData.cFileName));
3779 if (path->narrow && v) {
3780 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3781 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003782 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003783 Py_DECREF(list);
3784 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003785 break;
3786 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003787 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003789 Py_DECREF(list);
3790 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003791 break;
3792 }
3793 Py_DECREF(v);
3794 }
3795 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003796 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003797 Py_END_ALLOW_THREADS
3798 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3799 it got to the end of the directory. */
3800 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003801 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003802 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003803 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003804 }
3805 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003806
Larry Hastings9cf065c2012-06-22 16:30:09 -07003807exit:
3808 if (hFindFile != INVALID_HANDLE_VALUE) {
3809 if (FindClose(hFindFile) == FALSE) {
3810 if (list != NULL) {
3811 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003812 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003813 }
3814 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003815 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003816 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003817
Larry Hastings9cf065c2012-06-22 16:30:09 -07003818 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003819} /* end of _listdir_windows_no_opendir */
3820
3821#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3822
3823static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003824_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003825{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003826 PyObject *v;
3827 DIR *dirp = NULL;
3828 struct dirent *ep;
3829 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003830#ifdef HAVE_FDOPENDIR
3831 int fd = -1;
3832#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003833
Victor Stinner8c62be82010-05-06 00:08:46 +00003834 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003835#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003836 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003837 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003838 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003839 if (fd == -1)
3840 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003841
Larry Hastingsfdaea062012-06-25 04:42:23 -07003842 return_str = 1;
3843
Larry Hastings9cf065c2012-06-22 16:30:09 -07003844 Py_BEGIN_ALLOW_THREADS
3845 dirp = fdopendir(fd);
3846 Py_END_ALLOW_THREADS
3847 }
3848 else
3849#endif
3850 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003851 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003852 if (path->narrow) {
3853 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003854 /* only return bytes if they specified a bytes-like object */
3855 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003856 }
3857 else {
3858 name = ".";
3859 return_str = 1;
3860 }
3861
Larry Hastings9cf065c2012-06-22 16:30:09 -07003862 Py_BEGIN_ALLOW_THREADS
3863 dirp = opendir(name);
3864 Py_END_ALLOW_THREADS
3865 }
3866
3867 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003868 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003869#ifdef HAVE_FDOPENDIR
3870 if (fd != -1) {
3871 Py_BEGIN_ALLOW_THREADS
3872 close(fd);
3873 Py_END_ALLOW_THREADS
3874 }
3875#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003876 goto exit;
3877 }
3878 if ((list = PyList_New(0)) == NULL) {
3879 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003880 }
3881 for (;;) {
3882 errno = 0;
3883 Py_BEGIN_ALLOW_THREADS
3884 ep = readdir(dirp);
3885 Py_END_ALLOW_THREADS
3886 if (ep == NULL) {
3887 if (errno == 0) {
3888 break;
3889 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003890 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003891 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003892 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003893 }
3894 }
3895 if (ep->d_name[0] == '.' &&
3896 (NAMLEN(ep) == 1 ||
3897 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3898 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003899 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003900 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3901 else
3902 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003904 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003905 break;
3906 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003907 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003908 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003909 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003910 break;
3911 }
3912 Py_DECREF(v);
3913 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003914
Larry Hastings9cf065c2012-06-22 16:30:09 -07003915exit:
3916 if (dirp != NULL) {
3917 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003918#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003919 if (fd > -1)
3920 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003921#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003922 closedir(dirp);
3923 Py_END_ALLOW_THREADS
3924 }
3925
Larry Hastings9cf065c2012-06-22 16:30:09 -07003926 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003927} /* end of _posix_listdir */
3928#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003929
Larry Hastings2f936352014-08-05 14:04:04 +10003930
3931/*[clinic input]
3932os.listdir
3933
3934 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3935
3936Return a list containing the names of the files in the directory.
3937
BNMetricsb9427072018-11-02 15:20:19 +00003938path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003939 the filenames returned will also be bytes; in all other circumstances
3940 the filenames returned will be str.
3941If path is None, uses the path='.'.
3942On some platforms, path may also be specified as an open file descriptor;\
3943 the file descriptor must refer to a directory.
3944 If this functionality is unavailable, using it raises NotImplementedError.
3945
3946The list is in arbitrary order. It does not include the special
3947entries '.' and '..' even if they are present in the directory.
3948
3949
3950[clinic start generated code]*/
3951
Larry Hastings2f936352014-08-05 14:04:04 +10003952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003953os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003954/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003955{
Steve Dower60419a72019-06-24 08:42:54 -07003956 if (PySys_Audit("os.listdir", "O",
3957 path->object ? path->object : Py_None) < 0) {
3958 return NULL;
3959 }
Larry Hastings2f936352014-08-05 14:04:04 +10003960#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3961 return _listdir_windows_no_opendir(path, NULL);
3962#else
3963 return _posix_listdir(path, NULL);
3964#endif
3965}
3966
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003967#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003968/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003969/*[clinic input]
3970os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003971
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003972 path: path_t
3973 /
3974
3975[clinic start generated code]*/
3976
3977static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003978os__getfullpathname_impl(PyObject *module, path_t *path)
3979/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003980{
Victor Stinner3939c322019-06-25 15:02:43 +02003981 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003982
Victor Stinner3939c322019-06-25 15:02:43 +02003983 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
3984 if (_Py_abspath(path->wide, &abspath) < 0) {
3985 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003986 }
Victor Stinner3939c322019-06-25 15:02:43 +02003987 if (abspath == NULL) {
3988 return PyErr_NoMemory();
3989 }
3990
3991 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
3992 PyMem_RawFree(abspath);
3993 if (str == NULL) {
3994 return NULL;
3995 }
3996 if (path->narrow) {
3997 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
3998 }
3999 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10004000}
Brian Curtind40e6f72010-07-08 21:39:08 +00004001
Brian Curtind25aef52011-06-13 15:16:04 -05004002
Larry Hastings2f936352014-08-05 14:04:04 +10004003/*[clinic input]
4004os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004005
Steve Dower23ad6d02018-02-22 10:39:10 -08004006 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004007 /
4008
4009A helper function for samepath on windows.
4010[clinic start generated code]*/
4011
Larry Hastings2f936352014-08-05 14:04:04 +10004012static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004013os__getfinalpathname_impl(PyObject *module, path_t *path)
4014/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004015{
4016 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004017 wchar_t buf[MAXPATHLEN], *target_path = buf;
4018 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00004019 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004020 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004021
Steve Dower23ad6d02018-02-22 10:39:10 -08004022 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004023 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08004024 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004025 0, /* desired access */
4026 0, /* share mode */
4027 NULL, /* security attributes */
4028 OPEN_EXISTING,
4029 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4030 FILE_FLAG_BACKUP_SEMANTICS,
4031 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004032 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004033
Steve Dower23ad6d02018-02-22 10:39:10 -08004034 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004035 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004036 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004037
4038 /* We have a good handle to the target, use it to determine the
4039 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004040 while (1) {
4041 Py_BEGIN_ALLOW_THREADS
4042 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4043 buf_size, VOLUME_NAME_DOS);
4044 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004045
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004046 if (!result_length) {
4047 result = win32_error_object("GetFinalPathNameByHandleW",
4048 path->object);
4049 goto cleanup;
4050 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004051
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004052 if (result_length < buf_size) {
4053 break;
4054 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004055
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004056 wchar_t *tmp;
4057 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4058 result_length * sizeof(*tmp));
4059 if (!tmp) {
4060 result = PyErr_NoMemory();
4061 goto cleanup;
4062 }
4063
4064 buf_size = result_length;
4065 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004066 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004067
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004068 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004069 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004070 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004071 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004072
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004073cleanup:
4074 if (target_path != buf) {
4075 PyMem_Free(target_path);
4076 }
4077 CloseHandle(hFile);
4078 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004079}
Brian Curtin62857742010-09-06 17:07:27 +00004080
Tim Golden6b528062013-08-01 12:44:00 +01004081
Larry Hastings2f936352014-08-05 14:04:04 +10004082/*[clinic input]
4083os._getvolumepathname
4084
Steve Dower23ad6d02018-02-22 10:39:10 -08004085 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004086
4087A helper function for ismount on Win32.
4088[clinic start generated code]*/
4089
Larry Hastings2f936352014-08-05 14:04:04 +10004090static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004091os__getvolumepathname_impl(PyObject *module, path_t *path)
4092/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004093{
4094 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004095 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004096 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004097 BOOL ret;
4098
Tim Golden6b528062013-08-01 12:44:00 +01004099 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004100 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004101
Victor Stinner850a18e2017-10-24 16:53:32 -07004102 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004103 PyErr_SetString(PyExc_OverflowError, "path too long");
4104 return NULL;
4105 }
4106
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004107 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004108 if (mountpath == NULL)
4109 return PyErr_NoMemory();
4110
4111 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004112 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004113 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004114 Py_END_ALLOW_THREADS
4115
4116 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004117 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004118 goto exit;
4119 }
4120 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004121 if (path->narrow)
4122 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004123
4124exit:
4125 PyMem_Free(mountpath);
4126 return result;
4127}
Tim Golden6b528062013-08-01 12:44:00 +01004128
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004129#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004130
Larry Hastings2f936352014-08-05 14:04:04 +10004131
4132/*[clinic input]
4133os.mkdir
4134
4135 path : path_t
4136
4137 mode: int = 0o777
4138
4139 *
4140
4141 dir_fd : dir_fd(requires='mkdirat') = None
4142
4143# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4144
4145Create a directory.
4146
4147If dir_fd is not None, it should be a file descriptor open to a directory,
4148 and path should be relative; path will then be relative to that directory.
4149dir_fd may not be implemented on your platform.
4150 If it is unavailable, using it will raise a NotImplementedError.
4151
4152The mode argument is ignored on Windows.
4153[clinic start generated code]*/
4154
Larry Hastings2f936352014-08-05 14:04:04 +10004155static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004156os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4157/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004158{
4159 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004160
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004161 if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
4162 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4163 return NULL;
4164 }
4165
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004166#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004167 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004168 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004169 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004170
Larry Hastings2f936352014-08-05 14:04:04 +10004171 if (!result)
4172 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004173#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004174 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004175#if HAVE_MKDIRAT
4176 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004177 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004178 else
4179#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004180#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004181 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004182#else
Larry Hastings2f936352014-08-05 14:04:04 +10004183 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004184#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004185 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004186 if (result < 0)
4187 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004188#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004189 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004190}
4191
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004192
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004193/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4194#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004195#include <sys/resource.h>
4196#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004197
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004198
4199#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004200/*[clinic input]
4201os.nice
4202
4203 increment: int
4204 /
4205
4206Add increment to the priority of process and return the new priority.
4207[clinic start generated code]*/
4208
Larry Hastings2f936352014-08-05 14:04:04 +10004209static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004210os_nice_impl(PyObject *module, int increment)
4211/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004212{
4213 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004214
Victor Stinner8c62be82010-05-06 00:08:46 +00004215 /* There are two flavours of 'nice': one that returns the new
4216 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004217 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004218 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004219
Victor Stinner8c62be82010-05-06 00:08:46 +00004220 If we are of the nice family that returns the new priority, we
4221 need to clear errno before the call, and check if errno is filled
4222 before calling posix_error() on a returnvalue of -1, because the
4223 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004224
Victor Stinner8c62be82010-05-06 00:08:46 +00004225 errno = 0;
4226 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004227#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004228 if (value == 0)
4229 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004230#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004231 if (value == -1 && errno != 0)
4232 /* either nice() or getpriority() returned an error */
4233 return posix_error();
4234 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004235}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004236#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004237
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004238
4239#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004240/*[clinic input]
4241os.getpriority
4242
4243 which: int
4244 who: int
4245
4246Return program scheduling priority.
4247[clinic start generated code]*/
4248
Larry Hastings2f936352014-08-05 14:04:04 +10004249static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004250os_getpriority_impl(PyObject *module, int which, int who)
4251/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004252{
4253 int retval;
4254
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004255 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004256 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004257 if (errno != 0)
4258 return posix_error();
4259 return PyLong_FromLong((long)retval);
4260}
4261#endif /* HAVE_GETPRIORITY */
4262
4263
4264#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004265/*[clinic input]
4266os.setpriority
4267
4268 which: int
4269 who: int
4270 priority: int
4271
4272Set program scheduling priority.
4273[clinic start generated code]*/
4274
Larry Hastings2f936352014-08-05 14:04:04 +10004275static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004276os_setpriority_impl(PyObject *module, int which, int who, int priority)
4277/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004278{
4279 int retval;
4280
4281 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004282 if (retval == -1)
4283 return posix_error();
4284 Py_RETURN_NONE;
4285}
4286#endif /* HAVE_SETPRIORITY */
4287
4288
Barry Warsaw53699e91996-12-10 23:23:01 +00004289static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004290internal_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 +00004291{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004292 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004293 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004294
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004295#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004296 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004297 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004298#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004299 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004300#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004301
Larry Hastings9cf065c2012-06-22 16:30:09 -07004302 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4303 (dst_dir_fd != DEFAULT_DIR_FD);
4304#ifndef HAVE_RENAMEAT
4305 if (dir_fd_specified) {
4306 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004307 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004308 }
4309#endif
4310
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004311 if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
4312 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
4313 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
4314 return NULL;
4315 }
4316
Larry Hastings9cf065c2012-06-22 16:30:09 -07004317#ifdef MS_WINDOWS
4318 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004319 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004320 Py_END_ALLOW_THREADS
4321
Larry Hastings2f936352014-08-05 14:04:04 +10004322 if (!result)
4323 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004324
4325#else
Steve Dowercc16be82016-09-08 10:35:16 -07004326 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4327 PyErr_Format(PyExc_ValueError,
4328 "%s: src and dst must be the same type", function_name);
4329 return NULL;
4330 }
4331
Larry Hastings9cf065c2012-06-22 16:30:09 -07004332 Py_BEGIN_ALLOW_THREADS
4333#ifdef HAVE_RENAMEAT
4334 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004335 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004336 else
4337#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004338 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004339 Py_END_ALLOW_THREADS
4340
Larry Hastings2f936352014-08-05 14:04:04 +10004341 if (result)
4342 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004343#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004344 Py_RETURN_NONE;
4345}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004346
Larry Hastings2f936352014-08-05 14:04:04 +10004347
4348/*[clinic input]
4349os.rename
4350
4351 src : path_t
4352 dst : path_t
4353 *
4354 src_dir_fd : dir_fd = None
4355 dst_dir_fd : dir_fd = None
4356
4357Rename a file or directory.
4358
4359If either src_dir_fd or dst_dir_fd is not None, it should be a file
4360 descriptor open to a directory, and the respective path string (src or dst)
4361 should be relative; the path will then be relative to that directory.
4362src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4363 If they are unavailable, using them will raise a NotImplementedError.
4364[clinic start generated code]*/
4365
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004366static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004367os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004368 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004369/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004370{
Larry Hastings2f936352014-08-05 14:04:04 +10004371 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004372}
4373
Larry Hastings2f936352014-08-05 14:04:04 +10004374
4375/*[clinic input]
4376os.replace = os.rename
4377
4378Rename a file or directory, overwriting the destination.
4379
4380If either src_dir_fd or dst_dir_fd is not None, it should be a file
4381 descriptor open to a directory, and the respective path string (src or dst)
4382 should be relative; the path will then be relative to that directory.
4383src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004384 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004385[clinic start generated code]*/
4386
Larry Hastings2f936352014-08-05 14:04:04 +10004387static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004388os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4389 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004390/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004391{
4392 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4393}
4394
4395
4396/*[clinic input]
4397os.rmdir
4398
4399 path: path_t
4400 *
4401 dir_fd: dir_fd(requires='unlinkat') = None
4402
4403Remove a directory.
4404
4405If dir_fd is not None, it should be a file descriptor open to a directory,
4406 and path should be relative; path will then be relative to that directory.
4407dir_fd may not be implemented on your platform.
4408 If it is unavailable, using it will raise a NotImplementedError.
4409[clinic start generated code]*/
4410
Larry Hastings2f936352014-08-05 14:04:04 +10004411static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004412os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4413/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004414{
4415 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004416
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004417 if (PySys_Audit("os.rmdir", "Oi", path->object,
4418 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4419 return NULL;
4420 }
4421
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004422 Py_BEGIN_ALLOW_THREADS
4423#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004424 /* Windows, success=1, UNIX, success=0 */
4425 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004426#else
4427#ifdef HAVE_UNLINKAT
4428 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004429 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004430 else
4431#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004432 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004433#endif
4434 Py_END_ALLOW_THREADS
4435
Larry Hastings2f936352014-08-05 14:04:04 +10004436 if (result)
4437 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004438
Larry Hastings2f936352014-08-05 14:04:04 +10004439 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004440}
4441
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004442
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004443#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004444#ifdef MS_WINDOWS
4445/*[clinic input]
4446os.system -> long
4447
4448 command: Py_UNICODE
4449
4450Execute the command in a subshell.
4451[clinic start generated code]*/
4452
Larry Hastings2f936352014-08-05 14:04:04 +10004453static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004454os_system_impl(PyObject *module, const Py_UNICODE *command)
4455/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004456{
4457 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004458
Steve Dowerfbe3c762019-10-18 00:52:15 -07004459 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004460 return -1;
4461 }
4462
Victor Stinner8c62be82010-05-06 00:08:46 +00004463 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004464 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004465 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004466 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004467 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004468 return result;
4469}
4470#else /* MS_WINDOWS */
4471/*[clinic input]
4472os.system -> long
4473
4474 command: FSConverter
4475
4476Execute the command in a subshell.
4477[clinic start generated code]*/
4478
Larry Hastings2f936352014-08-05 14:04:04 +10004479static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004480os_system_impl(PyObject *module, PyObject *command)
4481/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004482{
4483 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004484 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004485
Steve Dowerfbe3c762019-10-18 00:52:15 -07004486 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004487 return -1;
4488 }
4489
Larry Hastings2f936352014-08-05 14:04:04 +10004490 Py_BEGIN_ALLOW_THREADS
4491 result = system(bytes);
4492 Py_END_ALLOW_THREADS
4493 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004494}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004495#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004496#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004498
Larry Hastings2f936352014-08-05 14:04:04 +10004499/*[clinic input]
4500os.umask
4501
4502 mask: int
4503 /
4504
4505Set the current numeric umask and return the previous umask.
4506[clinic start generated code]*/
4507
Larry Hastings2f936352014-08-05 14:04:04 +10004508static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004509os_umask_impl(PyObject *module, int mask)
4510/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004511{
4512 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004513 if (i < 0)
4514 return posix_error();
4515 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004516}
4517
Brian Curtind40e6f72010-07-08 21:39:08 +00004518#ifdef MS_WINDOWS
4519
4520/* override the default DeleteFileW behavior so that directory
4521symlinks can be removed with this function, the same as with
4522Unix symlinks */
4523BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4524{
4525 WIN32_FILE_ATTRIBUTE_DATA info;
4526 WIN32_FIND_DATAW find_data;
4527 HANDLE find_data_handle;
4528 int is_directory = 0;
4529 int is_link = 0;
4530
4531 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4532 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004533
Brian Curtind40e6f72010-07-08 21:39:08 +00004534 /* Get WIN32_FIND_DATA structure for the path to determine if
4535 it is a symlink */
4536 if(is_directory &&
4537 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4538 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4539
4540 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004541 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4542 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4543 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4544 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004545 FindClose(find_data_handle);
4546 }
4547 }
4548 }
4549
4550 if (is_directory && is_link)
4551 return RemoveDirectoryW(lpFileName);
4552
4553 return DeleteFileW(lpFileName);
4554}
4555#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004556
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004557
Larry Hastings2f936352014-08-05 14:04:04 +10004558/*[clinic input]
4559os.unlink
4560
4561 path: path_t
4562 *
4563 dir_fd: dir_fd(requires='unlinkat')=None
4564
4565Remove a file (same as remove()).
4566
4567If dir_fd is not None, it should be a file descriptor open to a directory,
4568 and path should be relative; path will then be relative to that directory.
4569dir_fd may not be implemented on your platform.
4570 If it is unavailable, using it will raise a NotImplementedError.
4571
4572[clinic start generated code]*/
4573
Larry Hastings2f936352014-08-05 14:04:04 +10004574static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004575os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4576/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004577{
4578 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004579
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004580 if (PySys_Audit("os.remove", "Oi", path->object,
4581 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4582 return NULL;
4583 }
4584
Larry Hastings9cf065c2012-06-22 16:30:09 -07004585 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004586 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004587#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004588 /* Windows, success=1, UNIX, success=0 */
4589 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591#ifdef HAVE_UNLINKAT
4592 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004593 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004594 else
4595#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004596 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004597#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004598 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004599 Py_END_ALLOW_THREADS
4600
Larry Hastings2f936352014-08-05 14:04:04 +10004601 if (result)
4602 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004603
Larry Hastings2f936352014-08-05 14:04:04 +10004604 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004605}
4606
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004607
Larry Hastings2f936352014-08-05 14:04:04 +10004608/*[clinic input]
4609os.remove = os.unlink
4610
4611Remove a file (same as unlink()).
4612
4613If dir_fd is not None, it should be a file descriptor open to a directory,
4614 and path should be relative; path will then be relative to that directory.
4615dir_fd may not be implemented on your platform.
4616 If it is unavailable, using it will raise a NotImplementedError.
4617[clinic start generated code]*/
4618
Larry Hastings2f936352014-08-05 14:04:04 +10004619static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004620os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4621/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004622{
4623 return os_unlink_impl(module, path, dir_fd);
4624}
4625
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004626
Larry Hastings605a62d2012-06-24 04:33:36 -07004627static PyStructSequence_Field uname_result_fields[] = {
4628 {"sysname", "operating system name"},
4629 {"nodename", "name of machine on network (implementation-defined)"},
4630 {"release", "operating system release"},
4631 {"version", "operating system version"},
4632 {"machine", "hardware identifier"},
4633 {NULL}
4634};
4635
4636PyDoc_STRVAR(uname_result__doc__,
4637"uname_result: Result from os.uname().\n\n\
4638This object may be accessed either as a tuple of\n\
4639 (sysname, nodename, release, version, machine),\n\
4640or via the attributes sysname, nodename, release, version, and machine.\n\
4641\n\
4642See os.uname for more information.");
4643
4644static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08004645 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07004646 uname_result__doc__, /* doc */
4647 uname_result_fields,
4648 5
4649};
4650
Larry Hastings605a62d2012-06-24 04:33:36 -07004651#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004652/*[clinic input]
4653os.uname
4654
4655Return an object identifying the current operating system.
4656
4657The object behaves like a named tuple with the following fields:
4658 (sysname, nodename, release, version, machine)
4659
4660[clinic start generated code]*/
4661
Larry Hastings2f936352014-08-05 14:04:04 +10004662static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004663os_uname_impl(PyObject *module)
4664/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004665{
Victor Stinner8c62be82010-05-06 00:08:46 +00004666 struct utsname u;
4667 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004668 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004669
Victor Stinner8c62be82010-05-06 00:08:46 +00004670 Py_BEGIN_ALLOW_THREADS
4671 res = uname(&u);
4672 Py_END_ALLOW_THREADS
4673 if (res < 0)
4674 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004675
Eddie Elizondob3966632019-11-05 07:16:14 -08004676 PyObject *UnameResultType = _posixstate(module)->UnameResultType;
4677 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004678 if (value == NULL)
4679 return NULL;
4680
4681#define SET(i, field) \
4682 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004683 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004684 if (!o) { \
4685 Py_DECREF(value); \
4686 return NULL; \
4687 } \
4688 PyStructSequence_SET_ITEM(value, i, o); \
4689 } \
4690
4691 SET(0, u.sysname);
4692 SET(1, u.nodename);
4693 SET(2, u.release);
4694 SET(3, u.version);
4695 SET(4, u.machine);
4696
4697#undef SET
4698
4699 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004700}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004701#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004702
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004703
Larry Hastings9cf065c2012-06-22 16:30:09 -07004704
4705typedef struct {
4706 int now;
4707 time_t atime_s;
4708 long atime_ns;
4709 time_t mtime_s;
4710 long mtime_ns;
4711} utime_t;
4712
4713/*
Victor Stinner484df002014-10-09 13:52:31 +02004714 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715 * they also intentionally leak the declaration of a pointer named "time"
4716 */
4717#define UTIME_TO_TIMESPEC \
4718 struct timespec ts[2]; \
4719 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004720 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004721 time = NULL; \
4722 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004723 ts[0].tv_sec = ut->atime_s; \
4724 ts[0].tv_nsec = ut->atime_ns; \
4725 ts[1].tv_sec = ut->mtime_s; \
4726 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727 time = ts; \
4728 } \
4729
4730#define UTIME_TO_TIMEVAL \
4731 struct timeval tv[2]; \
4732 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004733 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004734 time = NULL; \
4735 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004736 tv[0].tv_sec = ut->atime_s; \
4737 tv[0].tv_usec = ut->atime_ns / 1000; \
4738 tv[1].tv_sec = ut->mtime_s; \
4739 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004740 time = tv; \
4741 } \
4742
4743#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004744 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004746 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747 time = NULL; \
4748 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004749 u.actime = ut->atime_s; \
4750 u.modtime = ut->mtime_s; \
4751 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004752 }
4753
4754#define UTIME_TO_TIME_T \
4755 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004756 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004757 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 time = NULL; \
4759 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004760 timet[0] = ut->atime_s; \
4761 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004762 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 } \
4764
4765
Victor Stinner528a9ab2015-09-03 21:30:26 +02004766#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004767
4768static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004769utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770{
4771#ifdef HAVE_UTIMENSAT
4772 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4773 UTIME_TO_TIMESPEC;
4774 return utimensat(dir_fd, path, time, flags);
4775#elif defined(HAVE_FUTIMESAT)
4776 UTIME_TO_TIMEVAL;
4777 /*
4778 * follow_symlinks will never be false here;
4779 * we only allow !follow_symlinks and dir_fd together
4780 * if we have utimensat()
4781 */
4782 assert(follow_symlinks);
4783 return futimesat(dir_fd, path, time);
4784#endif
4785}
4786
Larry Hastings2f936352014-08-05 14:04:04 +10004787 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4788#else
4789 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004790#endif
4791
Victor Stinner528a9ab2015-09-03 21:30:26 +02004792#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004793
4794static int
Victor Stinner484df002014-10-09 13:52:31 +02004795utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004796{
4797#ifdef HAVE_FUTIMENS
4798 UTIME_TO_TIMESPEC;
4799 return futimens(fd, time);
4800#else
4801 UTIME_TO_TIMEVAL;
4802 return futimes(fd, time);
4803#endif
4804}
4805
Larry Hastings2f936352014-08-05 14:04:04 +10004806 #define PATH_UTIME_HAVE_FD 1
4807#else
4808 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809#endif
4810
Victor Stinner5ebae872015-09-22 01:29:33 +02004811#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4812# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4813#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004814
Victor Stinner4552ced2015-09-21 22:37:15 +02004815#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004816
4817static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004818utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004819{
4820#ifdef HAVE_UTIMENSAT
4821 UTIME_TO_TIMESPEC;
4822 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4823#else
4824 UTIME_TO_TIMEVAL;
4825 return lutimes(path, time);
4826#endif
4827}
4828
4829#endif
4830
4831#ifndef MS_WINDOWS
4832
4833static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004834utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004835{
4836#ifdef HAVE_UTIMENSAT
4837 UTIME_TO_TIMESPEC;
4838 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4839#elif defined(HAVE_UTIMES)
4840 UTIME_TO_TIMEVAL;
4841 return utimes(path, time);
4842#elif defined(HAVE_UTIME_H)
4843 UTIME_TO_UTIMBUF;
4844 return utime(path, time);
4845#else
4846 UTIME_TO_TIME_T;
4847 return utime(path, time);
4848#endif
4849}
4850
4851#endif
4852
Larry Hastings76ad59b2012-05-03 00:30:07 -07004853static int
4854split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4855{
4856 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004857 PyObject *divmod;
Eddie Elizondob3966632019-11-05 07:16:14 -08004858 divmod = PyNumber_Divmod(py_long, _posixstate_global->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07004859 if (!divmod)
4860 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004861 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4862 PyErr_Format(PyExc_TypeError,
4863 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08004864 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004865 goto exit;
4866 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004867 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4868 if ((*s == -1) && PyErr_Occurred())
4869 goto exit;
4870 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004871 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004872 goto exit;
4873
4874 result = 1;
4875exit:
4876 Py_XDECREF(divmod);
4877 return result;
4878}
4879
Larry Hastings2f936352014-08-05 14:04:04 +10004880
4881/*[clinic input]
4882os.utime
4883
4884 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004885 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10004886 *
4887 ns: object = NULL
4888 dir_fd: dir_fd(requires='futimensat') = None
4889 follow_symlinks: bool=True
4890
Martin Panter0ff89092015-09-09 01:56:53 +00004891# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004892
4893Set the access and modified time of path.
4894
4895path may always be specified as a string.
4896On some platforms, path may also be specified as an open file descriptor.
4897 If this functionality is unavailable, using it raises an exception.
4898
4899If times is not None, it must be a tuple (atime, mtime);
4900 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004901If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004902 atime_ns and mtime_ns should be expressed as integer nanoseconds
4903 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004904If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004905Specifying tuples for both times and ns is an error.
4906
4907If dir_fd is not None, it should be a file descriptor open to a directory,
4908 and path should be relative; path will then be relative to that directory.
4909If follow_symlinks is False, and the last element of the path is a symbolic
4910 link, utime will modify the symbolic link itself instead of the file the
4911 link points to.
4912It is an error to use dir_fd or follow_symlinks when specifying path
4913 as an open file descriptor.
4914dir_fd and follow_symlinks may not be available on your platform.
4915 If they are unavailable, using them will raise a NotImplementedError.
4916
4917[clinic start generated code]*/
4918
Larry Hastings2f936352014-08-05 14:04:04 +10004919static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004920os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4921 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004922/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004923{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004924#ifdef MS_WINDOWS
4925 HANDLE hFile;
4926 FILETIME atime, mtime;
4927#else
4928 int result;
4929#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004930
Larry Hastings2f936352014-08-05 14:04:04 +10004931 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004932
Christian Heimesb3c87242013-08-01 00:08:16 +02004933 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004934
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004935 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004936 PyErr_SetString(PyExc_ValueError,
4937 "utime: you may specify either 'times'"
4938 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004939 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004940 }
4941
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004942 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004943 time_t a_sec, m_sec;
4944 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004945 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004946 PyErr_SetString(PyExc_TypeError,
4947 "utime: 'times' must be either"
4948 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004949 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004950 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004951 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004952 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004953 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004954 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004955 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004956 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004957 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004958 utime.atime_s = a_sec;
4959 utime.atime_ns = a_nsec;
4960 utime.mtime_s = m_sec;
4961 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004962 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004963 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004964 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004965 PyErr_SetString(PyExc_TypeError,
4966 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004967 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004968 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004969 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004970 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004971 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004972 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004973 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004974 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004975 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004976 }
4977 else {
4978 /* times and ns are both None/unspecified. use "now". */
4979 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004980 }
4981
Victor Stinner4552ced2015-09-21 22:37:15 +02004982#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004983 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004984 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004986
Larry Hastings2f936352014-08-05 14:04:04 +10004987 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4988 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4989 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004990 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004991
Larry Hastings9cf065c2012-06-22 16:30:09 -07004992#if !defined(HAVE_UTIMENSAT)
4993 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004994 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004995 "utime: cannot use dir_fd and follow_symlinks "
4996 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004997 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004998 }
4999#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005000
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005001 if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
5002 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
5003 return NULL;
5004 }
5005
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005006#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005007 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005008 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5009 NULL, OPEN_EXISTING,
5010 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005011 Py_END_ALLOW_THREADS
5012 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10005013 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005014 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005015 }
5016
Larry Hastings9cf065c2012-06-22 16:30:09 -07005017 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005018 GetSystemTimeAsFileTime(&mtime);
5019 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005020 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005021 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08005022 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5023 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 }
5025 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5026 /* Avoid putting the file name into the error here,
5027 as that may confuse the user into believing that
5028 something is wrong with the file, when it also
5029 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005030 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005031 CloseHandle(hFile);
5032 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005033 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005034 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005035#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005036 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005037
Victor Stinner4552ced2015-09-21 22:37:15 +02005038#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005039 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10005040 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005041 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005042#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005043
Victor Stinner528a9ab2015-09-03 21:30:26 +02005044#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005045 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10005046 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005047 else
5048#endif
5049
Victor Stinner528a9ab2015-09-03 21:30:26 +02005050#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005051 if (path->fd != -1)
5052 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005053 else
5054#endif
5055
Larry Hastings2f936352014-08-05 14:04:04 +10005056 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005057
5058 Py_END_ALLOW_THREADS
5059
5060 if (result < 0) {
5061 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005062 posix_error();
5063 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005065
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005066#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005067
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005068 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005069}
5070
Guido van Rossum3b066191991-06-04 19:40:25 +00005071/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005072
Larry Hastings2f936352014-08-05 14:04:04 +10005073
5074/*[clinic input]
5075os._exit
5076
5077 status: int
5078
5079Exit to the system with specified status, without normal exit processing.
5080[clinic start generated code]*/
5081
Larry Hastings2f936352014-08-05 14:04:04 +10005082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005083os__exit_impl(PyObject *module, int status)
5084/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005085{
5086 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005087 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005088}
5089
Steve Dowercc16be82016-09-08 10:35:16 -07005090#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5091#define EXECV_CHAR wchar_t
5092#else
5093#define EXECV_CHAR char
5094#endif
5095
pxinwrf2d7ac72019-05-21 18:46:37 +08005096#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005097static void
Steve Dowercc16be82016-09-08 10:35:16 -07005098free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005099{
Victor Stinner8c62be82010-05-06 00:08:46 +00005100 Py_ssize_t i;
5101 for (i = 0; i < count; i++)
5102 PyMem_Free(array[i]);
5103 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005104}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005105
Berker Peksag81816462016-09-15 20:19:47 +03005106static int
5107fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005108{
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005110 PyObject *ub;
5111 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005112#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005113 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005114 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005115 *out = PyUnicode_AsWideCharString(ub, &size);
5116 if (*out)
5117 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005118#else
Berker Peksag81816462016-09-15 20:19:47 +03005119 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005120 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005121 size = PyBytes_GET_SIZE(ub);
5122 *out = PyMem_Malloc(size + 1);
5123 if (*out) {
5124 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5125 result = 1;
5126 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005127 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005128#endif
Berker Peksag81816462016-09-15 20:19:47 +03005129 Py_DECREF(ub);
5130 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005131}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005132#endif
5133
pxinwrf2d7ac72019-05-21 18:46:37 +08005134#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005135static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005136parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5137{
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 Py_ssize_t i, pos, envc;
5139 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005140 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005141 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005142
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 i = PyMapping_Size(env);
5144 if (i < 0)
5145 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005146 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005147 if (envlist == NULL) {
5148 PyErr_NoMemory();
5149 return NULL;
5150 }
5151 envc = 0;
5152 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005153 if (!keys)
5154 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005156 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005157 goto error;
5158 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5159 PyErr_Format(PyExc_TypeError,
5160 "env.keys() or env.values() is not a list");
5161 goto error;
5162 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005163
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 for (pos = 0; pos < i; pos++) {
5165 key = PyList_GetItem(keys, pos);
5166 val = PyList_GetItem(vals, pos);
5167 if (!key || !val)
5168 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005169
Berker Peksag81816462016-09-15 20:19:47 +03005170#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5171 if (!PyUnicode_FSDecoder(key, &key2))
5172 goto error;
5173 if (!PyUnicode_FSDecoder(val, &val2)) {
5174 Py_DECREF(key2);
5175 goto error;
5176 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005177 /* Search from index 1 because on Windows starting '=' is allowed for
5178 defining hidden environment variables. */
5179 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5180 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5181 {
5182 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005183 Py_DECREF(key2);
5184 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005185 goto error;
5186 }
Berker Peksag81816462016-09-15 20:19:47 +03005187 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5188#else
5189 if (!PyUnicode_FSConverter(key, &key2))
5190 goto error;
5191 if (!PyUnicode_FSConverter(val, &val2)) {
5192 Py_DECREF(key2);
5193 goto error;
5194 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005195 if (PyBytes_GET_SIZE(key2) == 0 ||
5196 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5197 {
5198 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005199 Py_DECREF(key2);
5200 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005201 goto error;
5202 }
Berker Peksag81816462016-09-15 20:19:47 +03005203 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5204 PyBytes_AS_STRING(val2));
5205#endif
5206 Py_DECREF(key2);
5207 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005208 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005209 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005210
5211 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5212 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005213 goto error;
5214 }
Berker Peksag81816462016-09-15 20:19:47 +03005215
Steve Dowercc16be82016-09-08 10:35:16 -07005216 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005217 }
5218 Py_DECREF(vals);
5219 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005220
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 envlist[envc] = 0;
5222 *envc_ptr = envc;
5223 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005224
5225error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 Py_XDECREF(keys);
5227 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005228 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005229 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005230}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005231
Steve Dowercc16be82016-09-08 10:35:16 -07005232static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005233parse_arglist(PyObject* argv, Py_ssize_t *argc)
5234{
5235 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005236 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005237 if (argvlist == NULL) {
5238 PyErr_NoMemory();
5239 return NULL;
5240 }
5241 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005242 PyObject* item = PySequence_ITEM(argv, i);
5243 if (item == NULL)
5244 goto fail;
5245 if (!fsconvert_strdup(item, &argvlist[i])) {
5246 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005247 goto fail;
5248 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005249 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005250 }
5251 argvlist[*argc] = NULL;
5252 return argvlist;
5253fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005254 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005255 free_string_array(argvlist, *argc);
5256 return NULL;
5257}
Steve Dowercc16be82016-09-08 10:35:16 -07005258
Ross Lagerwall7807c352011-03-17 20:20:30 +02005259#endif
5260
Larry Hastings2f936352014-08-05 14:04:04 +10005261
Ross Lagerwall7807c352011-03-17 20:20:30 +02005262#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005263/*[clinic input]
5264os.execv
5265
Steve Dowercc16be82016-09-08 10:35:16 -07005266 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005267 Path of executable file.
5268 argv: object
5269 Tuple or list of strings.
5270 /
5271
5272Execute an executable path with arguments, replacing current process.
5273[clinic start generated code]*/
5274
Larry Hastings2f936352014-08-05 14:04:04 +10005275static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005276os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5277/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005278{
Steve Dowercc16be82016-09-08 10:35:16 -07005279 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005280 Py_ssize_t argc;
5281
5282 /* execv has two arguments: (path, argv), where
5283 argv is a list or tuple of strings. */
5284
Ross Lagerwall7807c352011-03-17 20:20:30 +02005285 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5286 PyErr_SetString(PyExc_TypeError,
5287 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005288 return NULL;
5289 }
5290 argc = PySequence_Size(argv);
5291 if (argc < 1) {
5292 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005293 return NULL;
5294 }
5295
5296 argvlist = parse_arglist(argv, &argc);
5297 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005298 return NULL;
5299 }
Steve Dowerbce26262016-11-19 19:17:26 -08005300 if (!argvlist[0][0]) {
5301 PyErr_SetString(PyExc_ValueError,
5302 "execv() arg 2 first element cannot be empty");
5303 free_string_array(argvlist, argc);
5304 return NULL;
5305 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005306
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005307 if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005308 free_string_array(argvlist, argc);
5309 return NULL;
5310 }
5311
Steve Dowerbce26262016-11-19 19:17:26 -08005312 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005313#ifdef HAVE_WEXECV
5314 _wexecv(path->wide, argvlist);
5315#else
5316 execv(path->narrow, argvlist);
5317#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005318 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005319
5320 /* If we get here it's definitely an error */
5321
5322 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005323 return posix_error();
5324}
5325
Larry Hastings2f936352014-08-05 14:04:04 +10005326
5327/*[clinic input]
5328os.execve
5329
5330 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5331 Path of executable file.
5332 argv: object
5333 Tuple or list of strings.
5334 env: object
5335 Dictionary of strings mapping to strings.
5336
5337Execute an executable path with arguments, replacing current process.
5338[clinic start generated code]*/
5339
Larry Hastings2f936352014-08-05 14:04:04 +10005340static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005341os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5342/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005343{
Steve Dowercc16be82016-09-08 10:35:16 -07005344 EXECV_CHAR **argvlist = NULL;
5345 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005346 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005347
Victor Stinner8c62be82010-05-06 00:08:46 +00005348 /* execve has three arguments: (path, argv, env), where
5349 argv is a list or tuple of strings and env is a dictionary
5350 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005351
Ross Lagerwall7807c352011-03-17 20:20:30 +02005352 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005353 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005354 "execve: argv must be a tuple or list");
Saiyang Gou95f60012020-02-04 16:15:00 -08005355 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005356 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005357 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005358 if (argc < 1) {
5359 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5360 return NULL;
5361 }
5362
Victor Stinner8c62be82010-05-06 00:08:46 +00005363 if (!PyMapping_Check(env)) {
5364 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005365 "execve: environment must be a mapping object");
Saiyang Gou95f60012020-02-04 16:15:00 -08005366 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005367 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005368
Ross Lagerwall7807c352011-03-17 20:20:30 +02005369 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005370 if (argvlist == NULL) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005371 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005372 }
Steve Dowerbce26262016-11-19 19:17:26 -08005373 if (!argvlist[0][0]) {
5374 PyErr_SetString(PyExc_ValueError,
5375 "execve: argv first element cannot be empty");
Saiyang Gou95f60012020-02-04 16:15:00 -08005376 goto fail_0;
Steve Dowerbce26262016-11-19 19:17:26 -08005377 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005378
Victor Stinner8c62be82010-05-06 00:08:46 +00005379 envlist = parse_envlist(env, &envc);
5380 if (envlist == NULL)
Saiyang Gou95f60012020-02-04 16:15:00 -08005381 goto fail_0;
5382
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005383 if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005384 goto fail_1;
5385 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005386
Steve Dowerbce26262016-11-19 19:17:26 -08005387 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005388#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005389 if (path->fd > -1)
5390 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005391 else
5392#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005393#ifdef HAVE_WEXECV
5394 _wexecve(path->wide, argvlist, envlist);
5395#else
Larry Hastings2f936352014-08-05 14:04:04 +10005396 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005397#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005398 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005399
5400 /* If we get here it's definitely an error */
5401
Alexey Izbyshev83460312018-10-20 03:28:22 +03005402 posix_path_error(path);
Saiyang Gou95f60012020-02-04 16:15:00 -08005403 fail_1:
Steve Dowercc16be82016-09-08 10:35:16 -07005404 free_string_array(envlist, envc);
Saiyang Gou95f60012020-02-04 16:15:00 -08005405 fail_0:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005406 if (argvlist)
5407 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005408 return NULL;
5409}
Steve Dowercc16be82016-09-08 10:35:16 -07005410
Larry Hastings9cf065c2012-06-22 16:30:09 -07005411#endif /* HAVE_EXECV */
5412
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005413#ifdef HAVE_POSIX_SPAWN
5414
5415enum posix_spawn_file_actions_identifier {
5416 POSIX_SPAWN_OPEN,
5417 POSIX_SPAWN_CLOSE,
5418 POSIX_SPAWN_DUP2
5419};
5420
William Orr81574b82018-10-01 22:19:56 -07005421#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005422static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005423convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005424#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005425
5426static int
Victor Stinner325e4ba2019-02-01 15:47:24 +01005427parse_posix_spawn_flags(const char *func_name, PyObject *setpgroup,
5428 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005429 PyObject *setsigdef, PyObject *scheduler,
5430 posix_spawnattr_t *attrp)
5431{
5432 long all_flags = 0;
5433
5434 errno = posix_spawnattr_init(attrp);
5435 if (errno) {
5436 posix_error();
5437 return -1;
5438 }
5439
5440 if (setpgroup) {
5441 pid_t pgid = PyLong_AsPid(setpgroup);
5442 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5443 goto fail;
5444 }
5445 errno = posix_spawnattr_setpgroup(attrp, pgid);
5446 if (errno) {
5447 posix_error();
5448 goto fail;
5449 }
5450 all_flags |= POSIX_SPAWN_SETPGROUP;
5451 }
5452
5453 if (resetids) {
5454 all_flags |= POSIX_SPAWN_RESETIDS;
5455 }
5456
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005457 if (setsid) {
5458#ifdef POSIX_SPAWN_SETSID
5459 all_flags |= POSIX_SPAWN_SETSID;
5460#elif defined(POSIX_SPAWN_SETSID_NP)
5461 all_flags |= POSIX_SPAWN_SETSID_NP;
5462#else
5463 argument_unavailable_error(func_name, "setsid");
5464 return -1;
5465#endif
5466 }
5467
Pablo Galindo254a4662018-09-07 16:44:24 +01005468 if (setsigmask) {
5469 sigset_t set;
5470 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5471 goto fail;
5472 }
5473 errno = posix_spawnattr_setsigmask(attrp, &set);
5474 if (errno) {
5475 posix_error();
5476 goto fail;
5477 }
5478 all_flags |= POSIX_SPAWN_SETSIGMASK;
5479 }
5480
5481 if (setsigdef) {
5482 sigset_t set;
5483 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5484 goto fail;
5485 }
5486 errno = posix_spawnattr_setsigdefault(attrp, &set);
5487 if (errno) {
5488 posix_error();
5489 goto fail;
5490 }
5491 all_flags |= POSIX_SPAWN_SETSIGDEF;
5492 }
5493
5494 if (scheduler) {
5495#ifdef POSIX_SPAWN_SETSCHEDULER
5496 PyObject *py_schedpolicy;
5497 struct sched_param schedparam;
5498
5499 if (!PyArg_ParseTuple(scheduler, "OO&"
5500 ";A scheduler tuple must have two elements",
5501 &py_schedpolicy, convert_sched_param, &schedparam)) {
5502 goto fail;
5503 }
5504 if (py_schedpolicy != Py_None) {
5505 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5506
5507 if (schedpolicy == -1 && PyErr_Occurred()) {
5508 goto fail;
5509 }
5510 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5511 if (errno) {
5512 posix_error();
5513 goto fail;
5514 }
5515 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5516 }
5517 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5518 if (errno) {
5519 posix_error();
5520 goto fail;
5521 }
5522 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5523#else
5524 PyErr_SetString(PyExc_NotImplementedError,
5525 "The scheduler option is not supported in this system.");
5526 goto fail;
5527#endif
5528 }
5529
5530 errno = posix_spawnattr_setflags(attrp, all_flags);
5531 if (errno) {
5532 posix_error();
5533 goto fail;
5534 }
5535
5536 return 0;
5537
5538fail:
5539 (void)posix_spawnattr_destroy(attrp);
5540 return -1;
5541}
5542
5543static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005544parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005545 posix_spawn_file_actions_t *file_actionsp,
5546 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005547{
5548 PyObject *seq;
5549 PyObject *file_action = NULL;
5550 PyObject *tag_obj;
5551
5552 seq = PySequence_Fast(file_actions,
5553 "file_actions must be a sequence or None");
5554 if (seq == NULL) {
5555 return -1;
5556 }
5557
5558 errno = posix_spawn_file_actions_init(file_actionsp);
5559 if (errno) {
5560 posix_error();
5561 Py_DECREF(seq);
5562 return -1;
5563 }
5564
Zackery Spytzd52a83a2019-06-26 14:54:20 -06005565 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03005566 file_action = PySequence_Fast_GET_ITEM(seq, i);
5567 Py_INCREF(file_action);
5568 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5569 PyErr_SetString(PyExc_TypeError,
5570 "Each file_actions element must be a non-empty tuple");
5571 goto fail;
5572 }
5573 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5574 if (tag == -1 && PyErr_Occurred()) {
5575 goto fail;
5576 }
5577
5578 /* Populate the file_actions object */
5579 switch (tag) {
5580 case POSIX_SPAWN_OPEN: {
5581 int fd, oflag;
5582 PyObject *path;
5583 unsigned long mode;
5584 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5585 ";A open file_action tuple must have 5 elements",
5586 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5587 &oflag, &mode))
5588 {
5589 goto fail;
5590 }
Pablo Galindocb970732018-06-19 09:19:50 +01005591 if (PyList_Append(temp_buffer, path)) {
5592 Py_DECREF(path);
5593 goto fail;
5594 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005595 errno = posix_spawn_file_actions_addopen(file_actionsp,
5596 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005597 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005598 if (errno) {
5599 posix_error();
5600 goto fail;
5601 }
5602 break;
5603 }
5604 case POSIX_SPAWN_CLOSE: {
5605 int fd;
5606 if (!PyArg_ParseTuple(file_action, "Oi"
5607 ";A close file_action tuple must have 2 elements",
5608 &tag_obj, &fd))
5609 {
5610 goto fail;
5611 }
5612 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5613 if (errno) {
5614 posix_error();
5615 goto fail;
5616 }
5617 break;
5618 }
5619 case POSIX_SPAWN_DUP2: {
5620 int fd1, fd2;
5621 if (!PyArg_ParseTuple(file_action, "Oii"
5622 ";A dup2 file_action tuple must have 3 elements",
5623 &tag_obj, &fd1, &fd2))
5624 {
5625 goto fail;
5626 }
5627 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5628 fd1, fd2);
5629 if (errno) {
5630 posix_error();
5631 goto fail;
5632 }
5633 break;
5634 }
5635 default: {
5636 PyErr_SetString(PyExc_TypeError,
5637 "Unknown file_actions identifier");
5638 goto fail;
5639 }
5640 }
5641 Py_DECREF(file_action);
5642 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005643
Serhiy Storchakaef347532018-05-01 16:45:04 +03005644 Py_DECREF(seq);
5645 return 0;
5646
5647fail:
5648 Py_DECREF(seq);
5649 Py_DECREF(file_action);
5650 (void)posix_spawn_file_actions_destroy(file_actionsp);
5651 return -1;
5652}
5653
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005654
5655static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005656py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5657 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005658 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005659 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005660{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005661 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005662 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005663 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005664 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005665 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005666 posix_spawnattr_t attr;
5667 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005668 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005669 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005670 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005671 pid_t pid;
5672 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005673
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005674 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005675 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005676 like posix.environ. */
5677
Serhiy Storchakaef347532018-05-01 16:45:04 +03005678 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005679 PyErr_Format(PyExc_TypeError,
5680 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005681 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005682 }
5683 argc = PySequence_Size(argv);
5684 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005685 PyErr_Format(PyExc_ValueError,
5686 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005687 return NULL;
5688 }
5689
5690 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005691 PyErr_Format(PyExc_TypeError,
5692 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005693 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005694 }
5695
5696 argvlist = parse_arglist(argv, &argc);
5697 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005698 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005699 }
5700 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005701 PyErr_Format(PyExc_ValueError,
5702 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005703 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005704 }
5705
5706 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005707 if (envlist == NULL) {
5708 goto exit;
5709 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005710
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005711 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005712 /* There is a bug in old versions of glibc that makes some of the
5713 * helper functions for manipulating file actions not copy the provided
5714 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5715 * copy the value of path for some old versions of glibc (<2.20).
5716 * The use of temp_buffer here is a workaround that keeps the
5717 * python objects that own the buffers alive until posix_spawn gets called.
5718 * Check https://bugs.python.org/issue33630 and
5719 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5720 temp_buffer = PyList_New(0);
5721 if (!temp_buffer) {
5722 goto exit;
5723 }
5724 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005725 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005726 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005727 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005728 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005729
Victor Stinner325e4ba2019-02-01 15:47:24 +01005730 if (parse_posix_spawn_flags(func_name, setpgroup, resetids, setsid,
5731 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005732 goto exit;
5733 }
5734 attrp = &attr;
5735
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005736 if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005737 goto exit;
5738 }
5739
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005740 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005741#ifdef HAVE_POSIX_SPAWNP
5742 if (use_posix_spawnp) {
5743 err_code = posix_spawnp(&pid, path->narrow,
5744 file_actionsp, attrp, argvlist, envlist);
5745 }
5746 else
5747#endif /* HAVE_POSIX_SPAWNP */
5748 {
5749 err_code = posix_spawn(&pid, path->narrow,
5750 file_actionsp, attrp, argvlist, envlist);
5751 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005752 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005753
Serhiy Storchakaef347532018-05-01 16:45:04 +03005754 if (err_code) {
5755 errno = err_code;
5756 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005757 goto exit;
5758 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005759#ifdef _Py_MEMORY_SANITIZER
5760 __msan_unpoison(&pid, sizeof(pid));
5761#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005762 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005763
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005764exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005765 if (file_actionsp) {
5766 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005767 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005768 if (attrp) {
5769 (void)posix_spawnattr_destroy(attrp);
5770 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005771 if (envlist) {
5772 free_string_array(envlist, envc);
5773 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005774 if (argvlist) {
5775 free_string_array(argvlist, argc);
5776 }
Pablo Galindocb970732018-06-19 09:19:50 +01005777 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005778 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005779}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005780
5781
5782/*[clinic input]
5783
5784os.posix_spawn
5785 path: path_t
5786 Path of executable file.
5787 argv: object
5788 Tuple or list of strings.
5789 env: object
5790 Dictionary of strings mapping to strings.
5791 /
5792 *
5793 file_actions: object(c_default='NULL') = ()
5794 A sequence of file action tuples.
5795 setpgroup: object = NULL
5796 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5797 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005798 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5799 setsid: bool(accept={int}) = False
5800 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005801 setsigmask: object(c_default='NULL') = ()
5802 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5803 setsigdef: object(c_default='NULL') = ()
5804 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5805 scheduler: object = NULL
5806 A tuple with the scheduler policy (optional) and parameters.
5807
5808Execute the program specified by path in a new process.
5809[clinic start generated code]*/
5810
5811static PyObject *
5812os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5813 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005814 PyObject *setpgroup, int resetids, int setsid,
5815 PyObject *setsigmask, PyObject *setsigdef,
5816 PyObject *scheduler)
5817/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005818{
5819 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005820 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005821 scheduler);
5822}
5823 #endif /* HAVE_POSIX_SPAWN */
5824
5825
5826
5827#ifdef HAVE_POSIX_SPAWNP
5828/*[clinic input]
5829
5830os.posix_spawnp
5831 path: path_t
5832 Path of executable file.
5833 argv: object
5834 Tuple or list of strings.
5835 env: object
5836 Dictionary of strings mapping to strings.
5837 /
5838 *
5839 file_actions: object(c_default='NULL') = ()
5840 A sequence of file action tuples.
5841 setpgroup: object = NULL
5842 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5843 resetids: bool(accept={int}) = False
5844 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005845 setsid: bool(accept={int}) = False
5846 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005847 setsigmask: object(c_default='NULL') = ()
5848 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5849 setsigdef: object(c_default='NULL') = ()
5850 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5851 scheduler: object = NULL
5852 A tuple with the scheduler policy (optional) and parameters.
5853
5854Execute the program specified by path in a new process.
5855[clinic start generated code]*/
5856
5857static PyObject *
5858os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5859 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005860 PyObject *setpgroup, int resetids, int setsid,
5861 PyObject *setsigmask, PyObject *setsigdef,
5862 PyObject *scheduler)
5863/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005864{
5865 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005866 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005867 scheduler);
5868}
5869#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005870
pxinwrf2d7ac72019-05-21 18:46:37 +08005871#ifdef HAVE_RTPSPAWN
5872static intptr_t
5873_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5874 const char *envp[])
5875{
5876 RTP_ID rtpid;
5877 int status;
5878 pid_t res;
5879 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005880
pxinwrf2d7ac72019-05-21 18:46:37 +08005881 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5882 uStackSize=0 cannot be used, the default stack size is too small for
5883 Python. */
5884 if (envp) {
5885 rtpid = rtpSpawn(rtpFileName, argv, envp,
5886 100, 0x1000000, 0, VX_FP_TASK);
5887 }
5888 else {
5889 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5890 100, 0x1000000, 0, VX_FP_TASK);
5891 }
5892 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5893 do {
5894 res = waitpid((pid_t)rtpid, &status, 0);
5895 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5896
5897 if (res < 0)
5898 return RTP_ID_ERROR;
5899 return ((intptr_t)status);
5900 }
5901 return ((intptr_t)rtpid);
5902}
5903#endif
5904
5905#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10005906/*[clinic input]
5907os.spawnv
5908
5909 mode: int
5910 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005911 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005912 Path of executable file.
5913 argv: object
5914 Tuple or list of strings.
5915 /
5916
5917Execute the program specified by path in a new process.
5918[clinic start generated code]*/
5919
Larry Hastings2f936352014-08-05 14:04:04 +10005920static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005921os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5922/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005923{
Steve Dowercc16be82016-09-08 10:35:16 -07005924 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005925 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005926 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005927 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005928 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005929
Victor Stinner8c62be82010-05-06 00:08:46 +00005930 /* spawnv has three arguments: (mode, path, argv), where
5931 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005932
Victor Stinner8c62be82010-05-06 00:08:46 +00005933 if (PyList_Check(argv)) {
5934 argc = PyList_Size(argv);
5935 getitem = PyList_GetItem;
5936 }
5937 else if (PyTuple_Check(argv)) {
5938 argc = PyTuple_Size(argv);
5939 getitem = PyTuple_GetItem;
5940 }
5941 else {
5942 PyErr_SetString(PyExc_TypeError,
5943 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005944 return NULL;
5945 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005946 if (argc == 0) {
5947 PyErr_SetString(PyExc_ValueError,
5948 "spawnv() arg 2 cannot be empty");
5949 return NULL;
5950 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005951
Steve Dowercc16be82016-09-08 10:35:16 -07005952 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005953 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005954 return PyErr_NoMemory();
5955 }
5956 for (i = 0; i < argc; i++) {
5957 if (!fsconvert_strdup((*getitem)(argv, i),
5958 &argvlist[i])) {
5959 free_string_array(argvlist, i);
5960 PyErr_SetString(
5961 PyExc_TypeError,
5962 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 return NULL;
5964 }
Steve Dower93ff8722016-11-19 19:03:54 -08005965 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005966 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005967 PyErr_SetString(
5968 PyExc_ValueError,
5969 "spawnv() arg 2 first element cannot be empty");
5970 return NULL;
5971 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005972 }
5973 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005974
pxinwrf2d7ac72019-05-21 18:46:37 +08005975#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005976 if (mode == _OLD_P_OVERLAY)
5977 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005978#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005979
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005980 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
Saiyang Gou95f60012020-02-04 16:15:00 -08005981 Py_None) < 0) {
5982 free_string_array(argvlist, argc);
5983 return NULL;
5984 }
5985
Victor Stinner8c62be82010-05-06 00:08:46 +00005986 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005987 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005988#ifdef HAVE_WSPAWNV
5989 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005990#elif defined(HAVE_RTPSPAWN)
5991 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07005992#else
5993 spawnval = _spawnv(mode, path->narrow, argvlist);
5994#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005995 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005996 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005997
Victor Stinner8c62be82010-05-06 00:08:46 +00005998 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005999
Victor Stinner8c62be82010-05-06 00:08:46 +00006000 if (spawnval == -1)
6001 return posix_error();
6002 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006003 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006004}
6005
Larry Hastings2f936352014-08-05 14:04:04 +10006006/*[clinic input]
6007os.spawnve
6008
6009 mode: int
6010 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006011 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006012 Path of executable file.
6013 argv: object
6014 Tuple or list of strings.
6015 env: object
6016 Dictionary of strings mapping to strings.
6017 /
6018
6019Execute the program specified by path in a new process.
6020[clinic start generated code]*/
6021
Larry Hastings2f936352014-08-05 14:04:04 +10006022static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006023os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006024 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07006025/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006026{
Steve Dowercc16be82016-09-08 10:35:16 -07006027 EXECV_CHAR **argvlist;
6028 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006029 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006030 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006031 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006032 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006033 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006034
Victor Stinner8c62be82010-05-06 00:08:46 +00006035 /* spawnve has four arguments: (mode, path, argv, env), where
6036 argv is a list or tuple of strings and env is a dictionary
6037 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006038
Victor Stinner8c62be82010-05-06 00:08:46 +00006039 if (PyList_Check(argv)) {
6040 argc = PyList_Size(argv);
6041 getitem = PyList_GetItem;
6042 }
6043 else if (PyTuple_Check(argv)) {
6044 argc = PyTuple_Size(argv);
6045 getitem = PyTuple_GetItem;
6046 }
6047 else {
6048 PyErr_SetString(PyExc_TypeError,
6049 "spawnve() arg 2 must be a tuple or list");
6050 goto fail_0;
6051 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006052 if (argc == 0) {
6053 PyErr_SetString(PyExc_ValueError,
6054 "spawnve() arg 2 cannot be empty");
6055 goto fail_0;
6056 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006057 if (!PyMapping_Check(env)) {
6058 PyErr_SetString(PyExc_TypeError,
6059 "spawnve() arg 3 must be a mapping object");
6060 goto fail_0;
6061 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006062
Steve Dowercc16be82016-09-08 10:35:16 -07006063 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006064 if (argvlist == NULL) {
6065 PyErr_NoMemory();
6066 goto fail_0;
6067 }
6068 for (i = 0; i < argc; i++) {
6069 if (!fsconvert_strdup((*getitem)(argv, i),
6070 &argvlist[i]))
6071 {
6072 lastarg = i;
6073 goto fail_1;
6074 }
Steve Dowerbce26262016-11-19 19:17:26 -08006075 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006076 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006077 PyErr_SetString(
6078 PyExc_ValueError,
6079 "spawnv() arg 2 first element cannot be empty");
6080 goto fail_1;
6081 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006082 }
6083 lastarg = argc;
6084 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006085
Victor Stinner8c62be82010-05-06 00:08:46 +00006086 envlist = parse_envlist(env, &envc);
6087 if (envlist == NULL)
6088 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006089
pxinwrf2d7ac72019-05-21 18:46:37 +08006090#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006091 if (mode == _OLD_P_OVERLAY)
6092 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006093#endif
Tim Peters25059d32001-12-07 20:35:43 +00006094
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006095 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006096 goto fail_2;
6097 }
6098
Victor Stinner8c62be82010-05-06 00:08:46 +00006099 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006100 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006101#ifdef HAVE_WSPAWNV
6102 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006103#elif defined(HAVE_RTPSPAWN)
6104 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6105 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006106#else
6107 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6108#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006109 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006110 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006111
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 if (spawnval == -1)
6113 (void) posix_error();
6114 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006115 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006116
Saiyang Gou95f60012020-02-04 16:15:00 -08006117 fail_2:
Victor Stinner8c62be82010-05-06 00:08:46 +00006118 while (--envc >= 0)
6119 PyMem_DEL(envlist[envc]);
6120 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006121 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006122 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006123 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006124 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006125}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006126
Guido van Rossuma1065681999-01-25 23:20:23 +00006127#endif /* HAVE_SPAWNV */
6128
6129
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006130#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006131
6132/* Helper function to validate arguments.
6133 Returns 0 on success. non-zero on failure with a TypeError raised.
6134 If obj is non-NULL it must be callable. */
6135static int
6136check_null_or_callable(PyObject *obj, const char* obj_name)
6137{
6138 if (obj && !PyCallable_Check(obj)) {
6139 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006140 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006141 return -1;
6142 }
6143 return 0;
6144}
6145
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006146/*[clinic input]
6147os.register_at_fork
6148
Gregory P. Smith163468a2017-05-29 10:03:41 -07006149 *
6150 before: object=NULL
6151 A callable to be called in the parent before the fork() syscall.
6152 after_in_child: object=NULL
6153 A callable to be called in the child after fork().
6154 after_in_parent: object=NULL
6155 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006156
Gregory P. Smith163468a2017-05-29 10:03:41 -07006157Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006158
Gregory P. Smith163468a2017-05-29 10:03:41 -07006159'before' callbacks are called in reverse order.
6160'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006161
6162[clinic start generated code]*/
6163
6164static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006165os_register_at_fork_impl(PyObject *module, PyObject *before,
6166 PyObject *after_in_child, PyObject *after_in_parent)
6167/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006168{
6169 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006170
Gregory P. Smith163468a2017-05-29 10:03:41 -07006171 if (!before && !after_in_child && !after_in_parent) {
6172 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6173 return NULL;
6174 }
6175 if (check_null_or_callable(before, "before") ||
6176 check_null_or_callable(after_in_child, "after_in_child") ||
6177 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006178 return NULL;
6179 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02006180 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006181
Gregory P. Smith163468a2017-05-29 10:03:41 -07006182 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006183 return NULL;
6184 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006185 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006186 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006187 }
6188 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6189 return NULL;
6190 }
6191 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006192}
6193#endif /* HAVE_FORK */
6194
6195
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006196#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006197/*[clinic input]
6198os.fork1
6199
6200Fork a child process with a single multiplexed (i.e., not bound) thread.
6201
6202Return 0 to child process and PID of child to parent process.
6203[clinic start generated code]*/
6204
Larry Hastings2f936352014-08-05 14:04:04 +10006205static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006206os_fork1_impl(PyObject *module)
6207/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006208{
Victor Stinner8c62be82010-05-06 00:08:46 +00006209 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006210
Eric Snow59032962018-09-14 14:17:20 -07006211 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6212 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6213 return NULL;
6214 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006215 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006216 pid = fork1();
6217 if (pid == 0) {
6218 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006219 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 } else {
6221 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006222 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006223 }
6224 if (pid == -1)
6225 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006226 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006227}
Larry Hastings2f936352014-08-05 14:04:04 +10006228#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006229
6230
Guido van Rossumad0ee831995-03-01 10:34:45 +00006231#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006232/*[clinic input]
6233os.fork
6234
6235Fork a child process.
6236
6237Return 0 to child process and PID of child to parent process.
6238[clinic start generated code]*/
6239
Larry Hastings2f936352014-08-05 14:04:04 +10006240static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006241os_fork_impl(PyObject *module)
6242/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006243{
Victor Stinner8c62be82010-05-06 00:08:46 +00006244 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006245
Eric Snow59032962018-09-14 14:17:20 -07006246 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6247 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6248 return NULL;
6249 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006250 if (PySys_Audit("os.fork", NULL) < 0) {
6251 return NULL;
6252 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006253 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 pid = fork();
6255 if (pid == 0) {
6256 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006257 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 } else {
6259 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006260 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006261 }
6262 if (pid == -1)
6263 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006264 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006265}
Larry Hastings2f936352014-08-05 14:04:04 +10006266#endif /* HAVE_FORK */
6267
Guido van Rossum85e3b011991-06-03 12:42:10 +00006268
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006269#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006270#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006271/*[clinic input]
6272os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006273
Larry Hastings2f936352014-08-05 14:04:04 +10006274 policy: int
6275
6276Get the maximum scheduling priority for policy.
6277[clinic start generated code]*/
6278
Larry Hastings2f936352014-08-05 14:04:04 +10006279static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006280os_sched_get_priority_max_impl(PyObject *module, int policy)
6281/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006282{
6283 int max;
6284
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006285 max = sched_get_priority_max(policy);
6286 if (max < 0)
6287 return posix_error();
6288 return PyLong_FromLong(max);
6289}
6290
Larry Hastings2f936352014-08-05 14:04:04 +10006291
6292/*[clinic input]
6293os.sched_get_priority_min
6294
6295 policy: int
6296
6297Get the minimum scheduling priority for policy.
6298[clinic start generated code]*/
6299
Larry Hastings2f936352014-08-05 14:04:04 +10006300static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006301os_sched_get_priority_min_impl(PyObject *module, int policy)
6302/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006303{
6304 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006305 if (min < 0)
6306 return posix_error();
6307 return PyLong_FromLong(min);
6308}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006309#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6310
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006311
Larry Hastings2f936352014-08-05 14:04:04 +10006312#ifdef HAVE_SCHED_SETSCHEDULER
6313/*[clinic input]
6314os.sched_getscheduler
6315 pid: pid_t
6316 /
6317
Min ho Kimc4cacc82019-07-31 08:16:13 +10006318Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006319
6320Passing 0 for pid returns the scheduling policy for the calling process.
6321[clinic start generated code]*/
6322
Larry Hastings2f936352014-08-05 14:04:04 +10006323static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006324os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006325/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006326{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006327 int policy;
6328
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006329 policy = sched_getscheduler(pid);
6330 if (policy < 0)
6331 return posix_error();
6332 return PyLong_FromLong(policy);
6333}
Larry Hastings2f936352014-08-05 14:04:04 +10006334#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006335
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006336
William Orr81574b82018-10-01 22:19:56 -07006337#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006338/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006339class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006340
6341@classmethod
6342os.sched_param.__new__
6343
6344 sched_priority: object
6345 A scheduling parameter.
6346
Eddie Elizondob3966632019-11-05 07:16:14 -08006347Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006348[clinic start generated code]*/
6349
Larry Hastings2f936352014-08-05 14:04:04 +10006350static PyObject *
6351os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006352/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006353{
6354 PyObject *res;
6355
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006356 res = PyStructSequence_New(type);
6357 if (!res)
6358 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006359 Py_INCREF(sched_priority);
6360 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006361 return res;
6362}
6363
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006364PyDoc_VAR(os_sched_param__doc__);
6365
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006366static PyStructSequence_Field sched_param_fields[] = {
6367 {"sched_priority", "the scheduling priority"},
6368 {0}
6369};
6370
6371static PyStructSequence_Desc sched_param_desc = {
6372 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006373 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006374 sched_param_fields,
6375 1
6376};
6377
6378static int
6379convert_sched_param(PyObject *param, struct sched_param *res)
6380{
6381 long priority;
6382
Andy Lester55728702020-03-06 16:53:17 -06006383 if (!Py_IS_TYPE(param, (PyTypeObject *)_posixstate_global->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006384 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6385 return 0;
6386 }
6387 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6388 if (priority == -1 && PyErr_Occurred())
6389 return 0;
6390 if (priority > INT_MAX || priority < INT_MIN) {
6391 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6392 return 0;
6393 }
6394 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6395 return 1;
6396}
William Orr81574b82018-10-01 22:19:56 -07006397#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006398
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006399
6400#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006401/*[clinic input]
6402os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006403
Larry Hastings2f936352014-08-05 14:04:04 +10006404 pid: pid_t
6405 policy: int
6406 param: sched_param
6407 /
6408
6409Set the scheduling policy for the process identified by pid.
6410
6411If pid is 0, the calling process is changed.
6412param is an instance of sched_param.
6413[clinic start generated code]*/
6414
Larry Hastings2f936352014-08-05 14:04:04 +10006415static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006416os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006417 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006418/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006419{
Jesus Cea9c822272011-09-10 01:40:52 +02006420 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006421 ** sched_setscheduler() returns 0 in Linux, but the previous
6422 ** scheduling policy under Solaris/Illumos, and others.
6423 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006424 */
Larry Hastings2f936352014-08-05 14:04:04 +10006425 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006426 return posix_error();
6427 Py_RETURN_NONE;
6428}
Larry Hastings2f936352014-08-05 14:04:04 +10006429#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006430
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006431
6432#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006433/*[clinic input]
6434os.sched_getparam
6435 pid: pid_t
6436 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006437
Larry Hastings2f936352014-08-05 14:04:04 +10006438Returns scheduling parameters for the process identified by pid.
6439
6440If pid is 0, returns parameters for the calling process.
6441Return value is an instance of sched_param.
6442[clinic start generated code]*/
6443
Larry Hastings2f936352014-08-05 14:04:04 +10006444static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006445os_sched_getparam_impl(PyObject *module, pid_t pid)
6446/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006447{
6448 struct sched_param param;
6449 PyObject *result;
6450 PyObject *priority;
6451
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006452 if (sched_getparam(pid, &param))
6453 return posix_error();
Eddie Elizondob3966632019-11-05 07:16:14 -08006454 PyObject *SchedParamType = _posixstate_global->SchedParamType;
6455 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006456 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006457 return NULL;
6458 priority = PyLong_FromLong(param.sched_priority);
6459 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006460 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006461 return NULL;
6462 }
Larry Hastings2f936352014-08-05 14:04:04 +10006463 PyStructSequence_SET_ITEM(result, 0, priority);
6464 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006465}
6466
Larry Hastings2f936352014-08-05 14:04:04 +10006467
6468/*[clinic input]
6469os.sched_setparam
6470 pid: pid_t
6471 param: sched_param
6472 /
6473
6474Set scheduling parameters for the process identified by pid.
6475
6476If pid is 0, sets parameters for the calling process.
6477param should be an instance of sched_param.
6478[clinic start generated code]*/
6479
Larry Hastings2f936352014-08-05 14:04:04 +10006480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006481os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006482 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006483/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006484{
6485 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006486 return posix_error();
6487 Py_RETURN_NONE;
6488}
Larry Hastings2f936352014-08-05 14:04:04 +10006489#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006490
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006491
6492#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006493/*[clinic input]
6494os.sched_rr_get_interval -> double
6495 pid: pid_t
6496 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006497
Larry Hastings2f936352014-08-05 14:04:04 +10006498Return the round-robin quantum for the process identified by pid, in seconds.
6499
6500Value returned is a float.
6501[clinic start generated code]*/
6502
Larry Hastings2f936352014-08-05 14:04:04 +10006503static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006504os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6505/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006506{
6507 struct timespec interval;
6508 if (sched_rr_get_interval(pid, &interval)) {
6509 posix_error();
6510 return -1.0;
6511 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006512#ifdef _Py_MEMORY_SANITIZER
6513 __msan_unpoison(&interval, sizeof(interval));
6514#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006515 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6516}
6517#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006518
Larry Hastings2f936352014-08-05 14:04:04 +10006519
6520/*[clinic input]
6521os.sched_yield
6522
6523Voluntarily relinquish the CPU.
6524[clinic start generated code]*/
6525
Larry Hastings2f936352014-08-05 14:04:04 +10006526static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006527os_sched_yield_impl(PyObject *module)
6528/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006529{
6530 if (sched_yield())
6531 return posix_error();
6532 Py_RETURN_NONE;
6533}
6534
Benjamin Peterson2740af82011-08-02 17:41:34 -05006535#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006536/* The minimum number of CPUs allocated in a cpu_set_t */
6537static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006538
Larry Hastings2f936352014-08-05 14:04:04 +10006539/*[clinic input]
6540os.sched_setaffinity
6541 pid: pid_t
6542 mask : object
6543 /
6544
6545Set the CPU affinity of the process identified by pid to mask.
6546
6547mask should be an iterable of integers identifying CPUs.
6548[clinic start generated code]*/
6549
Larry Hastings2f936352014-08-05 14:04:04 +10006550static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006551os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6552/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006553{
Antoine Pitrou84869872012-08-04 16:16:35 +02006554 int ncpus;
6555 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006556 cpu_set_t *cpu_set = NULL;
6557 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006558
Larry Hastings2f936352014-08-05 14:04:04 +10006559 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006560 if (iterator == NULL)
6561 return NULL;
6562
6563 ncpus = NCPUS_START;
6564 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006565 cpu_set = CPU_ALLOC(ncpus);
6566 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006567 PyErr_NoMemory();
6568 goto error;
6569 }
Larry Hastings2f936352014-08-05 14:04:04 +10006570 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006571
6572 while ((item = PyIter_Next(iterator))) {
6573 long cpu;
6574 if (!PyLong_Check(item)) {
6575 PyErr_Format(PyExc_TypeError,
6576 "expected an iterator of ints, "
6577 "but iterator yielded %R",
6578 Py_TYPE(item));
6579 Py_DECREF(item);
6580 goto error;
6581 }
6582 cpu = PyLong_AsLong(item);
6583 Py_DECREF(item);
6584 if (cpu < 0) {
6585 if (!PyErr_Occurred())
6586 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6587 goto error;
6588 }
6589 if (cpu > INT_MAX - 1) {
6590 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6591 goto error;
6592 }
6593 if (cpu >= ncpus) {
6594 /* Grow CPU mask to fit the CPU number */
6595 int newncpus = ncpus;
6596 cpu_set_t *newmask;
6597 size_t newsetsize;
6598 while (newncpus <= cpu) {
6599 if (newncpus > INT_MAX / 2)
6600 newncpus = cpu + 1;
6601 else
6602 newncpus = newncpus * 2;
6603 }
6604 newmask = CPU_ALLOC(newncpus);
6605 if (newmask == NULL) {
6606 PyErr_NoMemory();
6607 goto error;
6608 }
6609 newsetsize = CPU_ALLOC_SIZE(newncpus);
6610 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006611 memcpy(newmask, cpu_set, setsize);
6612 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006613 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006614 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006615 ncpus = newncpus;
6616 }
Larry Hastings2f936352014-08-05 14:04:04 +10006617 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006618 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07006619 if (PyErr_Occurred()) {
6620 goto error;
6621 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006622 Py_CLEAR(iterator);
6623
Larry Hastings2f936352014-08-05 14:04:04 +10006624 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006625 posix_error();
6626 goto error;
6627 }
Larry Hastings2f936352014-08-05 14:04:04 +10006628 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006629 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006630
6631error:
Larry Hastings2f936352014-08-05 14:04:04 +10006632 if (cpu_set)
6633 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006634 Py_XDECREF(iterator);
6635 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006636}
6637
Larry Hastings2f936352014-08-05 14:04:04 +10006638
6639/*[clinic input]
6640os.sched_getaffinity
6641 pid: pid_t
6642 /
6643
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006644Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006645
6646The affinity is returned as a set of CPU identifiers.
6647[clinic start generated code]*/
6648
Larry Hastings2f936352014-08-05 14:04:04 +10006649static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006650os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006651/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006652{
Antoine Pitrou84869872012-08-04 16:16:35 +02006653 int cpu, ncpus, count;
6654 size_t setsize;
6655 cpu_set_t *mask = NULL;
6656 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006657
Antoine Pitrou84869872012-08-04 16:16:35 +02006658 ncpus = NCPUS_START;
6659 while (1) {
6660 setsize = CPU_ALLOC_SIZE(ncpus);
6661 mask = CPU_ALLOC(ncpus);
6662 if (mask == NULL)
6663 return PyErr_NoMemory();
6664 if (sched_getaffinity(pid, setsize, mask) == 0)
6665 break;
6666 CPU_FREE(mask);
6667 if (errno != EINVAL)
6668 return posix_error();
6669 if (ncpus > INT_MAX / 2) {
6670 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6671 "a large enough CPU set");
6672 return NULL;
6673 }
6674 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006675 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006676
6677 res = PySet_New(NULL);
6678 if (res == NULL)
6679 goto error;
6680 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6681 if (CPU_ISSET_S(cpu, setsize, mask)) {
6682 PyObject *cpu_num = PyLong_FromLong(cpu);
6683 --count;
6684 if (cpu_num == NULL)
6685 goto error;
6686 if (PySet_Add(res, cpu_num)) {
6687 Py_DECREF(cpu_num);
6688 goto error;
6689 }
6690 Py_DECREF(cpu_num);
6691 }
6692 }
6693 CPU_FREE(mask);
6694 return res;
6695
6696error:
6697 if (mask)
6698 CPU_FREE(mask);
6699 Py_XDECREF(res);
6700 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006701}
6702
Benjamin Peterson2740af82011-08-02 17:41:34 -05006703#endif /* HAVE_SCHED_SETAFFINITY */
6704
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006705#endif /* HAVE_SCHED_H */
6706
Larry Hastings2f936352014-08-05 14:04:04 +10006707
Neal Norwitzb59798b2003-03-21 01:43:31 +00006708/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006709/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6710#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006711#define DEV_PTY_FILE "/dev/ptc"
6712#define HAVE_DEV_PTMX
6713#else
6714#define DEV_PTY_FILE "/dev/ptmx"
6715#endif
6716
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006717#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006718#ifdef HAVE_PTY_H
6719#include <pty.h>
6720#else
6721#ifdef HAVE_LIBUTIL_H
6722#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006723#else
6724#ifdef HAVE_UTIL_H
6725#include <util.h>
6726#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006727#endif /* HAVE_LIBUTIL_H */
6728#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006729#ifdef HAVE_STROPTS_H
6730#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006731#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006732#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006733
Larry Hastings2f936352014-08-05 14:04:04 +10006734
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006735#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006736/*[clinic input]
6737os.openpty
6738
6739Open a pseudo-terminal.
6740
6741Return a tuple of (master_fd, slave_fd) containing open file descriptors
6742for both the master and slave ends.
6743[clinic start generated code]*/
6744
Larry Hastings2f936352014-08-05 14:04:04 +10006745static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006746os_openpty_impl(PyObject *module)
6747/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006748{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006749 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006750#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006751 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006752#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006753#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006754 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006755#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006756 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006757#endif
6758#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006759
Thomas Wouters70c21a12000-07-14 14:28:33 +00006760#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006762 goto posix_error;
6763
6764 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6765 goto error;
6766 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6767 goto error;
6768
Neal Norwitzb59798b2003-03-21 01:43:31 +00006769#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006770 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6771 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006772 goto posix_error;
6773 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6774 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006775
Victor Stinnerdaf45552013-08-28 00:53:59 +02006776 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006778 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006779
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006780#else
Victor Stinner000de532013-11-25 23:19:58 +01006781 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006783 goto posix_error;
6784
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006786
Victor Stinner8c62be82010-05-06 00:08:46 +00006787 /* change permission of slave */
6788 if (grantpt(master_fd) < 0) {
6789 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006790 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006792
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 /* unlock slave */
6794 if (unlockpt(master_fd) < 0) {
6795 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006796 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006798
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006800
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 slave_name = ptsname(master_fd); /* get name of slave */
6802 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006803 goto posix_error;
6804
6805 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006806 if (slave_fd == -1)
6807 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006808
6809 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6810 goto posix_error;
6811
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006812#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006813 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6814 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006815#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006816 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006817#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006818#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006819#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006820
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006822
Victor Stinnerdaf45552013-08-28 00:53:59 +02006823posix_error:
6824 posix_error();
6825error:
6826 if (master_fd != -1)
6827 close(master_fd);
6828 if (slave_fd != -1)
6829 close(slave_fd);
6830 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006831}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006832#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006833
Larry Hastings2f936352014-08-05 14:04:04 +10006834
Fred Drake8cef4cf2000-06-28 16:40:38 +00006835#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006836/*[clinic input]
6837os.forkpty
6838
6839Fork a new process with a new pseudo-terminal as controlling tty.
6840
6841Returns a tuple of (pid, master_fd).
6842Like fork(), return pid of 0 to the child process,
6843and pid of child to the parent process.
6844To both, return fd of newly opened pseudo-terminal.
6845[clinic start generated code]*/
6846
Larry Hastings2f936352014-08-05 14:04:04 +10006847static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006848os_forkpty_impl(PyObject *module)
6849/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006850{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006851 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006852 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006853
Eric Snow59032962018-09-14 14:17:20 -07006854 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6855 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6856 return NULL;
6857 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006858 if (PySys_Audit("os.forkpty", NULL) < 0) {
6859 return NULL;
6860 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006861 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 pid = forkpty(&master_fd, NULL, NULL, NULL);
6863 if (pid == 0) {
6864 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006865 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 } else {
6867 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006868 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 }
6870 if (pid == -1)
6871 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006873}
Larry Hastings2f936352014-08-05 14:04:04 +10006874#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006875
Ross Lagerwall7807c352011-03-17 20:20:30 +02006876
Guido van Rossumad0ee831995-03-01 10:34:45 +00006877#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006878/*[clinic input]
6879os.getegid
6880
6881Return the current process's effective group id.
6882[clinic start generated code]*/
6883
Larry Hastings2f936352014-08-05 14:04:04 +10006884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006885os_getegid_impl(PyObject *module)
6886/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006887{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006888 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006889}
Larry Hastings2f936352014-08-05 14:04:04 +10006890#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006891
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006892
Guido van Rossumad0ee831995-03-01 10:34:45 +00006893#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006894/*[clinic input]
6895os.geteuid
6896
6897Return the current process's effective user id.
6898[clinic start generated code]*/
6899
Larry Hastings2f936352014-08-05 14:04:04 +10006900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006901os_geteuid_impl(PyObject *module)
6902/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006903{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006904 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006905}
Larry Hastings2f936352014-08-05 14:04:04 +10006906#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006908
Guido van Rossumad0ee831995-03-01 10:34:45 +00006909#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006910/*[clinic input]
6911os.getgid
6912
6913Return the current process's group id.
6914[clinic start generated code]*/
6915
Larry Hastings2f936352014-08-05 14:04:04 +10006916static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006917os_getgid_impl(PyObject *module)
6918/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006919{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006920 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006921}
Larry Hastings2f936352014-08-05 14:04:04 +10006922#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006924
Berker Peksag39404992016-09-15 20:45:16 +03006925#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006926/*[clinic input]
6927os.getpid
6928
6929Return the current process id.
6930[clinic start generated code]*/
6931
Larry Hastings2f936352014-08-05 14:04:04 +10006932static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006933os_getpid_impl(PyObject *module)
6934/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006935{
Victor Stinner8c62be82010-05-06 00:08:46 +00006936 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006937}
Berker Peksag39404992016-09-15 20:45:16 +03006938#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006939
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006940#ifdef NGROUPS_MAX
6941#define MAX_GROUPS NGROUPS_MAX
6942#else
6943 /* defined to be 16 on Solaris7, so this should be a small number */
6944#define MAX_GROUPS 64
6945#endif
6946
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006947#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006948
6949/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006950PyDoc_STRVAR(posix_getgrouplist__doc__,
6951"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6952Returns a list of groups to which a user belongs.\n\n\
6953 user: username to lookup\n\
6954 group: base group id of the user");
6955
6956static PyObject *
6957posix_getgrouplist(PyObject *self, PyObject *args)
6958{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006959 const char *user;
6960 int i, ngroups;
6961 PyObject *list;
6962#ifdef __APPLE__
6963 int *groups, basegid;
6964#else
6965 gid_t *groups, basegid;
6966#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006967
6968 /*
6969 * NGROUPS_MAX is defined by POSIX.1 as the maximum
6970 * number of supplimental groups a users can belong to.
6971 * We have to increment it by one because
6972 * getgrouplist() returns both the supplemental groups
6973 * and the primary group, i.e. all of the groups the
6974 * user belongs to.
6975 */
6976 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006977
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006978#ifdef __APPLE__
6979 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006980 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006981#else
6982 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6983 _Py_Gid_Converter, &basegid))
6984 return NULL;
6985#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006986
6987#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006988 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006989#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006990 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006991#endif
6992 if (groups == NULL)
6993 return PyErr_NoMemory();
6994
6995 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6996 PyMem_Del(groups);
6997 return posix_error();
6998 }
6999
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007000#ifdef _Py_MEMORY_SANITIZER
7001 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7002 __msan_unpoison(&ngroups, sizeof(ngroups));
7003 __msan_unpoison(groups, ngroups*sizeof(*groups));
7004#endif
7005
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007006 list = PyList_New(ngroups);
7007 if (list == NULL) {
7008 PyMem_Del(groups);
7009 return NULL;
7010 }
7011
7012 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007013#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007014 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007015#else
7016 PyObject *o = _PyLong_FromGid(groups[i]);
7017#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007018 if (o == NULL) {
7019 Py_DECREF(list);
7020 PyMem_Del(groups);
7021 return NULL;
7022 }
7023 PyList_SET_ITEM(list, i, o);
7024 }
7025
7026 PyMem_Del(groups);
7027
7028 return list;
7029}
Larry Hastings2f936352014-08-05 14:04:04 +10007030#endif /* HAVE_GETGROUPLIST */
7031
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007032
Fred Drakec9680921999-12-13 16:37:25 +00007033#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007034/*[clinic input]
7035os.getgroups
7036
7037Return list of supplemental group IDs for the process.
7038[clinic start generated code]*/
7039
Larry Hastings2f936352014-08-05 14:04:04 +10007040static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007041os_getgroups_impl(PyObject *module)
7042/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007043{
7044 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007046
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007047 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007048 * This is a helper variable to store the intermediate result when
7049 * that happens.
7050 *
7051 * To keep the code readable the OSX behaviour is unconditional,
7052 * according to the POSIX spec this should be safe on all unix-y
7053 * systems.
7054 */
7055 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007056 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007057
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007058#ifdef __APPLE__
7059 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7060 * there are more groups than can fit in grouplist. Therefore, on OS X
7061 * always first call getgroups with length 0 to get the actual number
7062 * of groups.
7063 */
7064 n = getgroups(0, NULL);
7065 if (n < 0) {
7066 return posix_error();
7067 } else if (n <= MAX_GROUPS) {
7068 /* groups will fit in existing array */
7069 alt_grouplist = grouplist;
7070 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007071 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007072 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007073 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007074 }
7075 }
7076
7077 n = getgroups(n, alt_grouplist);
7078 if (n == -1) {
7079 if (alt_grouplist != grouplist) {
7080 PyMem_Free(alt_grouplist);
7081 }
7082 return posix_error();
7083 }
7084#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007085 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007086 if (n < 0) {
7087 if (errno == EINVAL) {
7088 n = getgroups(0, NULL);
7089 if (n == -1) {
7090 return posix_error();
7091 }
7092 if (n == 0) {
7093 /* Avoid malloc(0) */
7094 alt_grouplist = grouplist;
7095 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007096 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007097 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007098 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007099 }
7100 n = getgroups(n, alt_grouplist);
7101 if (n == -1) {
7102 PyMem_Free(alt_grouplist);
7103 return posix_error();
7104 }
7105 }
7106 } else {
7107 return posix_error();
7108 }
7109 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007110#endif
7111
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007112 result = PyList_New(n);
7113 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 int i;
7115 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007116 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007118 Py_DECREF(result);
7119 result = NULL;
7120 break;
Fred Drakec9680921999-12-13 16:37:25 +00007121 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007122 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007123 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007124 }
7125
7126 if (alt_grouplist != grouplist) {
7127 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007128 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007129
Fred Drakec9680921999-12-13 16:37:25 +00007130 return result;
7131}
Larry Hastings2f936352014-08-05 14:04:04 +10007132#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007133
Antoine Pitroub7572f02009-12-02 20:46:48 +00007134#ifdef HAVE_INITGROUPS
7135PyDoc_STRVAR(posix_initgroups__doc__,
7136"initgroups(username, gid) -> None\n\n\
7137Call the system initgroups() to initialize the group access list with all of\n\
7138the groups of which the specified username is a member, plus the specified\n\
7139group id.");
7140
Larry Hastings2f936352014-08-05 14:04:04 +10007141/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007142static PyObject *
7143posix_initgroups(PyObject *self, PyObject *args)
7144{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00007145 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007146 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00007147 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007148#ifdef __APPLE__
7149 int gid;
7150#else
7151 gid_t gid;
7152#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007153
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007154#ifdef __APPLE__
7155 if (!PyArg_ParseTuple(args, "O&i:initgroups",
7156 PyUnicode_FSConverter, &oname,
7157 &gid))
7158#else
7159 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
7160 PyUnicode_FSConverter, &oname,
7161 _Py_Gid_Converter, &gid))
7162#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007163 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00007164 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007165
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007166 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00007167 Py_DECREF(oname);
7168 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007169 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007170
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007171 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007172}
Larry Hastings2f936352014-08-05 14:04:04 +10007173#endif /* HAVE_INITGROUPS */
7174
Antoine Pitroub7572f02009-12-02 20:46:48 +00007175
Martin v. Löwis606edc12002-06-13 21:09:11 +00007176#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007177/*[clinic input]
7178os.getpgid
7179
7180 pid: pid_t
7181
7182Call the system call getpgid(), and return the result.
7183[clinic start generated code]*/
7184
Larry Hastings2f936352014-08-05 14:04:04 +10007185static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007186os_getpgid_impl(PyObject *module, pid_t pid)
7187/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007188{
7189 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007190 if (pgid < 0)
7191 return posix_error();
7192 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007193}
7194#endif /* HAVE_GETPGID */
7195
7196
Guido van Rossumb6775db1994-08-01 11:34:53 +00007197#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007198/*[clinic input]
7199os.getpgrp
7200
7201Return the current process group id.
7202[clinic start generated code]*/
7203
Larry Hastings2f936352014-08-05 14:04:04 +10007204static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007205os_getpgrp_impl(PyObject *module)
7206/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007207{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007208#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007209 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007210#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007211 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007212#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007213}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007214#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007216
Guido van Rossumb6775db1994-08-01 11:34:53 +00007217#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007218/*[clinic input]
7219os.setpgrp
7220
7221Make the current process the leader of its process group.
7222[clinic start generated code]*/
7223
Larry Hastings2f936352014-08-05 14:04:04 +10007224static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007225os_setpgrp_impl(PyObject *module)
7226/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007227{
Guido van Rossum64933891994-10-20 21:56:42 +00007228#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007229 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007230#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007231 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007232#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007233 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007234 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007235}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007236#endif /* HAVE_SETPGRP */
7237
Guido van Rossumad0ee831995-03-01 10:34:45 +00007238#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007239
7240#ifdef MS_WINDOWS
7241#include <tlhelp32.h>
7242
7243static PyObject*
7244win32_getppid()
7245{
7246 HANDLE snapshot;
7247 pid_t mypid;
7248 PyObject* result = NULL;
7249 BOOL have_record;
7250 PROCESSENTRY32 pe;
7251
7252 mypid = getpid(); /* This function never fails */
7253
7254 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7255 if (snapshot == INVALID_HANDLE_VALUE)
7256 return PyErr_SetFromWindowsErr(GetLastError());
7257
7258 pe.dwSize = sizeof(pe);
7259 have_record = Process32First(snapshot, &pe);
7260 while (have_record) {
7261 if (mypid == (pid_t)pe.th32ProcessID) {
7262 /* We could cache the ulong value in a static variable. */
7263 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7264 break;
7265 }
7266
7267 have_record = Process32Next(snapshot, &pe);
7268 }
7269
7270 /* If our loop exits and our pid was not found (result will be NULL)
7271 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7272 * error anyway, so let's raise it. */
7273 if (!result)
7274 result = PyErr_SetFromWindowsErr(GetLastError());
7275
7276 CloseHandle(snapshot);
7277
7278 return result;
7279}
7280#endif /*MS_WINDOWS*/
7281
Larry Hastings2f936352014-08-05 14:04:04 +10007282
7283/*[clinic input]
7284os.getppid
7285
7286Return the parent's process id.
7287
7288If the parent process has already exited, Windows machines will still
7289return its id; others systems will return the id of the 'init' process (1).
7290[clinic start generated code]*/
7291
Larry Hastings2f936352014-08-05 14:04:04 +10007292static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007293os_getppid_impl(PyObject *module)
7294/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007295{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007296#ifdef MS_WINDOWS
7297 return win32_getppid();
7298#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007299 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007300#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007301}
7302#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007303
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007304
Fred Drake12c6e2d1999-12-14 21:25:03 +00007305#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007306/*[clinic input]
7307os.getlogin
7308
7309Return the actual login name.
7310[clinic start generated code]*/
7311
Larry Hastings2f936352014-08-05 14:04:04 +10007312static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007313os_getlogin_impl(PyObject *module)
7314/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007315{
Victor Stinner8c62be82010-05-06 00:08:46 +00007316 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007317#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007318 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007319 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007320
7321 if (GetUserNameW(user_name, &num_chars)) {
7322 /* num_chars is the number of unicode chars plus null terminator */
7323 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007324 }
7325 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007326 result = PyErr_SetFromWindowsErr(GetLastError());
7327#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007328 char *name;
7329 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007330
Victor Stinner8c62be82010-05-06 00:08:46 +00007331 errno = 0;
7332 name = getlogin();
7333 if (name == NULL) {
7334 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007335 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007336 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007337 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007338 }
7339 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007340 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007341 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007342#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007343 return result;
7344}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007345#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007346
Larry Hastings2f936352014-08-05 14:04:04 +10007347
Guido van Rossumad0ee831995-03-01 10:34:45 +00007348#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007349/*[clinic input]
7350os.getuid
7351
7352Return the current process's user id.
7353[clinic start generated code]*/
7354
Larry Hastings2f936352014-08-05 14:04:04 +10007355static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007356os_getuid_impl(PyObject *module)
7357/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007358{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007359 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007360}
Larry Hastings2f936352014-08-05 14:04:04 +10007361#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007362
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007363
Brian Curtineb24d742010-04-12 17:16:38 +00007364#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007365#define HAVE_KILL
7366#endif /* MS_WINDOWS */
7367
7368#ifdef HAVE_KILL
7369/*[clinic input]
7370os.kill
7371
7372 pid: pid_t
7373 signal: Py_ssize_t
7374 /
7375
7376Kill a process with a signal.
7377[clinic start generated code]*/
7378
Larry Hastings2f936352014-08-05 14:04:04 +10007379static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007380os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7381/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007382{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007383 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7384 return NULL;
7385 }
7386#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007387 if (kill(pid, (int)signal) == -1)
7388 return posix_error();
7389 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007390#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007391 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007392 DWORD sig = (DWORD)signal;
7393 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007394 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007395
Victor Stinner8c62be82010-05-06 00:08:46 +00007396 /* Console processes which share a common console can be sent CTRL+C or
7397 CTRL+BREAK events, provided they handle said events. */
7398 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007399 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007400 err = GetLastError();
7401 PyErr_SetFromWindowsErr(err);
7402 }
7403 else
7404 Py_RETURN_NONE;
7405 }
Brian Curtineb24d742010-04-12 17:16:38 +00007406
Victor Stinner8c62be82010-05-06 00:08:46 +00007407 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7408 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007409 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007410 if (handle == NULL) {
7411 err = GetLastError();
7412 return PyErr_SetFromWindowsErr(err);
7413 }
Brian Curtineb24d742010-04-12 17:16:38 +00007414
Victor Stinner8c62be82010-05-06 00:08:46 +00007415 if (TerminateProcess(handle, sig) == 0) {
7416 err = GetLastError();
7417 result = PyErr_SetFromWindowsErr(err);
7418 } else {
7419 Py_INCREF(Py_None);
7420 result = Py_None;
7421 }
Brian Curtineb24d742010-04-12 17:16:38 +00007422
Victor Stinner8c62be82010-05-06 00:08:46 +00007423 CloseHandle(handle);
7424 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007425#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007426}
Larry Hastings2f936352014-08-05 14:04:04 +10007427#endif /* HAVE_KILL */
7428
7429
7430#ifdef HAVE_KILLPG
7431/*[clinic input]
7432os.killpg
7433
7434 pgid: pid_t
7435 signal: int
7436 /
7437
7438Kill a process group with a signal.
7439[clinic start generated code]*/
7440
Larry Hastings2f936352014-08-05 14:04:04 +10007441static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007442os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7443/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007444{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007445 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7446 return NULL;
7447 }
Larry Hastings2f936352014-08-05 14:04:04 +10007448 /* XXX some man pages make the `pgid` parameter an int, others
7449 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7450 take the same type. Moreover, pid_t is always at least as wide as
7451 int (else compilation of this module fails), which is safe. */
7452 if (killpg(pgid, signal) == -1)
7453 return posix_error();
7454 Py_RETURN_NONE;
7455}
7456#endif /* HAVE_KILLPG */
7457
Brian Curtineb24d742010-04-12 17:16:38 +00007458
Guido van Rossumc0125471996-06-28 18:55:32 +00007459#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007460#ifdef HAVE_SYS_LOCK_H
7461#include <sys/lock.h>
7462#endif
7463
Larry Hastings2f936352014-08-05 14:04:04 +10007464/*[clinic input]
7465os.plock
7466 op: int
7467 /
7468
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007469Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007470[clinic start generated code]*/
7471
Larry Hastings2f936352014-08-05 14:04:04 +10007472static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007473os_plock_impl(PyObject *module, int op)
7474/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007475{
Victor Stinner8c62be82010-05-06 00:08:46 +00007476 if (plock(op) == -1)
7477 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007478 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007479}
Larry Hastings2f936352014-08-05 14:04:04 +10007480#endif /* HAVE_PLOCK */
7481
Guido van Rossumc0125471996-06-28 18:55:32 +00007482
Guido van Rossumb6775db1994-08-01 11:34:53 +00007483#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007484/*[clinic input]
7485os.setuid
7486
7487 uid: uid_t
7488 /
7489
7490Set the current process's user id.
7491[clinic start generated code]*/
7492
Larry Hastings2f936352014-08-05 14:04:04 +10007493static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007494os_setuid_impl(PyObject *module, uid_t uid)
7495/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007496{
Victor Stinner8c62be82010-05-06 00:08:46 +00007497 if (setuid(uid) < 0)
7498 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007499 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007500}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007501#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007502
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007503
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007504#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007505/*[clinic input]
7506os.seteuid
7507
7508 euid: uid_t
7509 /
7510
7511Set the current process's effective user id.
7512[clinic start generated code]*/
7513
Larry Hastings2f936352014-08-05 14:04:04 +10007514static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007515os_seteuid_impl(PyObject *module, uid_t euid)
7516/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007517{
7518 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007519 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007520 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007521}
7522#endif /* HAVE_SETEUID */
7523
Larry Hastings2f936352014-08-05 14:04:04 +10007524
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007525#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007526/*[clinic input]
7527os.setegid
7528
7529 egid: gid_t
7530 /
7531
7532Set the current process's effective group id.
7533[clinic start generated code]*/
7534
Larry Hastings2f936352014-08-05 14:04:04 +10007535static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007536os_setegid_impl(PyObject *module, gid_t egid)
7537/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007538{
7539 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007540 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007541 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007542}
7543#endif /* HAVE_SETEGID */
7544
Larry Hastings2f936352014-08-05 14:04:04 +10007545
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007546#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007547/*[clinic input]
7548os.setreuid
7549
7550 ruid: uid_t
7551 euid: uid_t
7552 /
7553
7554Set the current process's real and effective user ids.
7555[clinic start generated code]*/
7556
Larry Hastings2f936352014-08-05 14:04:04 +10007557static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007558os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7559/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007560{
Victor Stinner8c62be82010-05-06 00:08:46 +00007561 if (setreuid(ruid, euid) < 0) {
7562 return posix_error();
7563 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007564 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007565 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007566}
7567#endif /* HAVE_SETREUID */
7568
Larry Hastings2f936352014-08-05 14:04:04 +10007569
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007570#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007571/*[clinic input]
7572os.setregid
7573
7574 rgid: gid_t
7575 egid: gid_t
7576 /
7577
7578Set the current process's real and effective group ids.
7579[clinic start generated code]*/
7580
Larry Hastings2f936352014-08-05 14:04:04 +10007581static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007582os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7583/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007584{
7585 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007586 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007587 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007588}
7589#endif /* HAVE_SETREGID */
7590
Larry Hastings2f936352014-08-05 14:04:04 +10007591
Guido van Rossumb6775db1994-08-01 11:34:53 +00007592#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007593/*[clinic input]
7594os.setgid
7595 gid: gid_t
7596 /
7597
7598Set the current process's group id.
7599[clinic start generated code]*/
7600
Larry Hastings2f936352014-08-05 14:04:04 +10007601static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007602os_setgid_impl(PyObject *module, gid_t gid)
7603/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007604{
Victor Stinner8c62be82010-05-06 00:08:46 +00007605 if (setgid(gid) < 0)
7606 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007607 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007608}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007609#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007610
Larry Hastings2f936352014-08-05 14:04:04 +10007611
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007612#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007613/*[clinic input]
7614os.setgroups
7615
7616 groups: object
7617 /
7618
7619Set the groups of the current process to list.
7620[clinic start generated code]*/
7621
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007623os_setgroups(PyObject *module, PyObject *groups)
7624/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007625{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007626 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007627 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007628
Victor Stinner8c62be82010-05-06 00:08:46 +00007629 if (!PySequence_Check(groups)) {
7630 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7631 return NULL;
7632 }
7633 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007634 if (len < 0) {
7635 return NULL;
7636 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007637 if (len > MAX_GROUPS) {
7638 PyErr_SetString(PyExc_ValueError, "too many groups");
7639 return NULL;
7640 }
7641 for(i = 0; i < len; i++) {
7642 PyObject *elem;
7643 elem = PySequence_GetItem(groups, i);
7644 if (!elem)
7645 return NULL;
7646 if (!PyLong_Check(elem)) {
7647 PyErr_SetString(PyExc_TypeError,
7648 "groups must be integers");
7649 Py_DECREF(elem);
7650 return NULL;
7651 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007652 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007653 Py_DECREF(elem);
7654 return NULL;
7655 }
7656 }
7657 Py_DECREF(elem);
7658 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007659
Victor Stinner8c62be82010-05-06 00:08:46 +00007660 if (setgroups(len, grouplist) < 0)
7661 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007662 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007663}
7664#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007665
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007666#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7667static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007668wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007669{
Victor Stinner8c62be82010-05-06 00:08:46 +00007670 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08007671 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007672
Victor Stinner8c62be82010-05-06 00:08:46 +00007673 if (pid == -1)
7674 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007675
Zackery Spytz682107c2019-09-09 09:48:32 -06007676 // If wait succeeded but no child was ready to report status, ru will not
7677 // have been populated.
7678 if (pid == 0) {
7679 memset(ru, 0, sizeof(*ru));
7680 }
7681
Eddie Elizondob3966632019-11-05 07:16:14 -08007682 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7683 if (m == NULL)
7684 return NULL;
7685 struct_rusage = PyObject_GetAttr(m, _posixstate_global->struct_rusage);
7686 Py_DECREF(m);
7687 if (struct_rusage == NULL)
7688 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007689
Victor Stinner8c62be82010-05-06 00:08:46 +00007690 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7691 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08007692 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007693 if (!result)
7694 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007695
7696#ifndef doubletime
7697#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7698#endif
7699
Victor Stinner8c62be82010-05-06 00:08:46 +00007700 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007701 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007702 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007703 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007704#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007705 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7706 SET_INT(result, 2, ru->ru_maxrss);
7707 SET_INT(result, 3, ru->ru_ixrss);
7708 SET_INT(result, 4, ru->ru_idrss);
7709 SET_INT(result, 5, ru->ru_isrss);
7710 SET_INT(result, 6, ru->ru_minflt);
7711 SET_INT(result, 7, ru->ru_majflt);
7712 SET_INT(result, 8, ru->ru_nswap);
7713 SET_INT(result, 9, ru->ru_inblock);
7714 SET_INT(result, 10, ru->ru_oublock);
7715 SET_INT(result, 11, ru->ru_msgsnd);
7716 SET_INT(result, 12, ru->ru_msgrcv);
7717 SET_INT(result, 13, ru->ru_nsignals);
7718 SET_INT(result, 14, ru->ru_nvcsw);
7719 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007720#undef SET_INT
7721
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 if (PyErr_Occurred()) {
7723 Py_DECREF(result);
7724 return NULL;
7725 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007726
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007728}
7729#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7730
Larry Hastings2f936352014-08-05 14:04:04 +10007731
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007732#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007733/*[clinic input]
7734os.wait3
7735
7736 options: int
7737Wait for completion of a child process.
7738
7739Returns a tuple of information about the child process:
7740 (pid, status, rusage)
7741[clinic start generated code]*/
7742
Larry Hastings2f936352014-08-05 14:04:04 +10007743static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007744os_wait3_impl(PyObject *module, int options)
7745/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007746{
Victor Stinner8c62be82010-05-06 00:08:46 +00007747 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007748 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007749 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 WAIT_TYPE status;
7751 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007752
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007753 do {
7754 Py_BEGIN_ALLOW_THREADS
7755 pid = wait3(&status, options, &ru);
7756 Py_END_ALLOW_THREADS
7757 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7758 if (pid < 0)
7759 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007760
Victor Stinner4195b5c2012-02-08 23:03:19 +01007761 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007762}
7763#endif /* HAVE_WAIT3 */
7764
Larry Hastings2f936352014-08-05 14:04:04 +10007765
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007766#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007767/*[clinic input]
7768
7769os.wait4
7770
7771 pid: pid_t
7772 options: int
7773
7774Wait for completion of a specific child process.
7775
7776Returns a tuple of information about the child process:
7777 (pid, status, rusage)
7778[clinic start generated code]*/
7779
Larry Hastings2f936352014-08-05 14:04:04 +10007780static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007781os_wait4_impl(PyObject *module, pid_t pid, int options)
7782/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007783{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007784 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007785 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007786 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007787 WAIT_TYPE status;
7788 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007789
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007790 do {
7791 Py_BEGIN_ALLOW_THREADS
7792 res = wait4(pid, &status, options, &ru);
7793 Py_END_ALLOW_THREADS
7794 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7795 if (res < 0)
7796 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007797
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007798 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007799}
7800#endif /* HAVE_WAIT4 */
7801
Larry Hastings2f936352014-08-05 14:04:04 +10007802
Ross Lagerwall7807c352011-03-17 20:20:30 +02007803#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007804/*[clinic input]
7805os.waitid
7806
7807 idtype: idtype_t
7808 Must be one of be P_PID, P_PGID or P_ALL.
7809 id: id_t
7810 The id to wait on.
7811 options: int
7812 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7813 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7814 /
7815
7816Returns the result of waiting for a process or processes.
7817
7818Returns either waitid_result or None if WNOHANG is specified and there are
7819no children in a waitable state.
7820[clinic start generated code]*/
7821
Larry Hastings2f936352014-08-05 14:04:04 +10007822static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007823os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7824/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007825{
7826 PyObject *result;
7827 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007828 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007829 siginfo_t si;
7830 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007831
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007832 do {
7833 Py_BEGIN_ALLOW_THREADS
7834 res = waitid(idtype, id, &si, options);
7835 Py_END_ALLOW_THREADS
7836 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7837 if (res < 0)
7838 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007839
7840 if (si.si_pid == 0)
7841 Py_RETURN_NONE;
7842
Eddie Elizondob3966632019-11-05 07:16:14 -08007843 PyObject *WaitidResultType = _posixstate(module)->WaitidResultType;
7844 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007845 if (!result)
7846 return NULL;
7847
7848 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007849 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007850 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7851 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7852 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7853 if (PyErr_Occurred()) {
7854 Py_DECREF(result);
7855 return NULL;
7856 }
7857
7858 return result;
7859}
Larry Hastings2f936352014-08-05 14:04:04 +10007860#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007861
Larry Hastings2f936352014-08-05 14:04:04 +10007862
7863#if defined(HAVE_WAITPID)
7864/*[clinic input]
7865os.waitpid
7866 pid: pid_t
7867 options: int
7868 /
7869
7870Wait for completion of a given child process.
7871
7872Returns a tuple of information regarding the child process:
7873 (pid, status)
7874
7875The options argument is ignored on Windows.
7876[clinic start generated code]*/
7877
Larry Hastings2f936352014-08-05 14:04:04 +10007878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007879os_waitpid_impl(PyObject *module, pid_t pid, int options)
7880/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007881{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007882 pid_t res;
7883 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007884 WAIT_TYPE status;
7885 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007886
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007887 do {
7888 Py_BEGIN_ALLOW_THREADS
7889 res = waitpid(pid, &status, options);
7890 Py_END_ALLOW_THREADS
7891 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7892 if (res < 0)
7893 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007894
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007895 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007896}
Tim Petersab034fa2002-02-01 11:27:43 +00007897#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007898/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007899/*[clinic input]
7900os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007901 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007902 options: int
7903 /
7904
7905Wait for completion of a given process.
7906
7907Returns a tuple of information regarding the process:
7908 (pid, status << 8)
7909
7910The options argument is ignored on Windows.
7911[clinic start generated code]*/
7912
Larry Hastings2f936352014-08-05 14:04:04 +10007913static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007914os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007915/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007916{
7917 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007918 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007919 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007920
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007921 do {
7922 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007923 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007924 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007925 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007926 Py_END_ALLOW_THREADS
7927 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007928 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007929 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007930
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007932 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007933}
Larry Hastings2f936352014-08-05 14:04:04 +10007934#endif
7935
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007936
Guido van Rossumad0ee831995-03-01 10:34:45 +00007937#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007938/*[clinic input]
7939os.wait
7940
7941Wait for completion of a child process.
7942
7943Returns a tuple of information about the child process:
7944 (pid, status)
7945[clinic start generated code]*/
7946
Larry Hastings2f936352014-08-05 14:04:04 +10007947static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007948os_wait_impl(PyObject *module)
7949/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007950{
Victor Stinner8c62be82010-05-06 00:08:46 +00007951 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007952 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007953 WAIT_TYPE status;
7954 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007955
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007956 do {
7957 Py_BEGIN_ALLOW_THREADS
7958 pid = wait(&status);
7959 Py_END_ALLOW_THREADS
7960 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7961 if (pid < 0)
7962 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007963
Victor Stinner8c62be82010-05-06 00:08:46 +00007964 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007965}
Larry Hastings2f936352014-08-05 14:04:04 +10007966#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007967
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08007968#if defined(__linux__) && defined(__NR_pidfd_open)
7969/*[clinic input]
7970os.pidfd_open
7971 pid: pid_t
7972 flags: unsigned_int = 0
7973
7974Return a file descriptor referring to the process *pid*.
7975
7976The descriptor can be used to perform process management without races and
7977signals.
7978[clinic start generated code]*/
7979
7980static PyObject *
7981os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
7982/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
7983{
7984 int fd = syscall(__NR_pidfd_open, pid, flags);
7985 if (fd < 0) {
7986 return posix_error();
7987 }
7988 return PyLong_FromLong(fd);
7989}
7990#endif
7991
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007992
Larry Hastings9cf065c2012-06-22 16:30:09 -07007993#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007994/*[clinic input]
7995os.readlink
7996
7997 path: path_t
7998 *
7999 dir_fd: dir_fd(requires='readlinkat') = None
8000
8001Return a string representing the path to which the symbolic link points.
8002
8003If dir_fd is not None, it should be a file descriptor open to a directory,
8004and path should be relative; path will then be relative to that directory.
8005
8006dir_fd may not be implemented on your platform. If it is unavailable,
8007using it will raise a NotImplementedError.
8008[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008009
Barry Warsaw53699e91996-12-10 23:23:01 +00008010static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008011os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8012/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008013{
Berker Peksage0b5b202018-08-15 13:03:41 +03008014#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008015 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008016 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008017
8018 Py_BEGIN_ALLOW_THREADS
8019#ifdef HAVE_READLINKAT
8020 if (dir_fd != DEFAULT_DIR_FD)
8021 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8022 else
8023#endif
8024 length = readlink(path->narrow, buffer, MAXPATHLEN);
8025 Py_END_ALLOW_THREADS
8026
8027 if (length < 0) {
8028 return path_error(path);
8029 }
8030 buffer[length] = '\0';
8031
8032 if (PyUnicode_Check(path->object))
8033 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8034 else
8035 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008036#elif defined(MS_WINDOWS)
8037 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008038 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008039 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008040 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8041 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008042 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008043
Larry Hastings2f936352014-08-05 14:04:04 +10008044 /* First get a handle to the reparse point */
8045 Py_BEGIN_ALLOW_THREADS
8046 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008047 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008048 0,
8049 0,
8050 0,
8051 OPEN_EXISTING,
8052 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8053 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008054 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8055 /* New call DeviceIoControl to read the reparse point */
8056 io_result = DeviceIoControl(
8057 reparse_point_handle,
8058 FSCTL_GET_REPARSE_POINT,
8059 0, 0, /* in buffer */
8060 target_buffer, sizeof(target_buffer),
8061 &n_bytes_returned,
8062 0 /* we're not using OVERLAPPED_IO */
8063 );
8064 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008065 }
Larry Hastings2f936352014-08-05 14:04:04 +10008066 Py_END_ALLOW_THREADS
8067
Berker Peksage0b5b202018-08-15 13:03:41 +03008068 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008069 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008070 }
Larry Hastings2f936352014-08-05 14:04:04 +10008071
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008072 wchar_t *name = NULL;
8073 Py_ssize_t nameLen = 0;
8074 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008075 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008076 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8077 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8078 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008079 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008080 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8081 {
8082 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8083 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8084 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8085 }
8086 else
8087 {
8088 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8089 }
8090 if (name) {
8091 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8092 /* Our buffer is mutable, so this is okay */
8093 name[1] = L'\\';
8094 }
8095 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008096 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008097 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8098 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008099 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008100 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008101#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008102}
Berker Peksage0b5b202018-08-15 13:03:41 +03008103#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008104
Larry Hastings9cf065c2012-06-22 16:30:09 -07008105#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07008106
8107#if defined(MS_WINDOWS)
8108
Steve Dower6921e732018-03-05 14:26:08 -08008109/* Remove the last portion of the path - return 0 on success */
8110static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008111_dirnameW(WCHAR *path)
8112{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008113 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008114 size_t length = wcsnlen_s(path, MAX_PATH);
8115 if (length == MAX_PATH) {
8116 return -1;
8117 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008118
8119 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008120 for(ptr = path + length; ptr != path; ptr--) {
8121 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008122 break;
Steve Dower6921e732018-03-05 14:26:08 -08008123 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008124 }
8125 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008126 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008127}
8128
Victor Stinner31b3b922013-06-05 01:49:17 +02008129/* Is this path absolute? */
8130static int
8131_is_absW(const WCHAR *path)
8132{
Steve Dower6921e732018-03-05 14:26:08 -08008133 return path[0] == L'\\' || path[0] == L'/' ||
8134 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008135}
8136
Steve Dower6921e732018-03-05 14:26:08 -08008137/* join root and rest with a backslash - return 0 on success */
8138static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008139_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8140{
Victor Stinner31b3b922013-06-05 01:49:17 +02008141 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008142 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008143 }
8144
Steve Dower6921e732018-03-05 14:26:08 -08008145 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8146 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008147 }
Steve Dower6921e732018-03-05 14:26:08 -08008148
8149 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8150 return -1;
8151 }
8152
8153 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008154}
8155
Victor Stinner31b3b922013-06-05 01:49:17 +02008156/* Return True if the path at src relative to dest is a directory */
8157static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008158_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008159{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008160 WIN32_FILE_ATTRIBUTE_DATA src_info;
8161 WCHAR dest_parent[MAX_PATH];
8162 WCHAR src_resolved[MAX_PATH] = L"";
8163
8164 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008165 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8166 _dirnameW(dest_parent)) {
8167 return 0;
8168 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008169 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008170 if (_joinW(src_resolved, dest_parent, src)) {
8171 return 0;
8172 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008173 return (
8174 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8175 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8176 );
8177}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008178#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008179
Larry Hastings2f936352014-08-05 14:04:04 +10008180
8181/*[clinic input]
8182os.symlink
8183 src: path_t
8184 dst: path_t
8185 target_is_directory: bool = False
8186 *
8187 dir_fd: dir_fd(requires='symlinkat')=None
8188
8189# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8190
8191Create a symbolic link pointing to src named dst.
8192
8193target_is_directory is required on Windows if the target is to be
8194 interpreted as a directory. (On Windows, symlink requires
8195 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8196 target_is_directory is ignored on non-Windows platforms.
8197
8198If dir_fd is not None, it should be a file descriptor open to a directory,
8199 and path should be relative; path will then be relative to that directory.
8200dir_fd may not be implemented on your platform.
8201 If it is unavailable, using it will raise a NotImplementedError.
8202
8203[clinic start generated code]*/
8204
Larry Hastings2f936352014-08-05 14:04:04 +10008205static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008206os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008207 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008208/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008209{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008210#ifdef MS_WINDOWS
8211 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008212 DWORD flags = 0;
8213
8214 /* Assumed true, set to false if detected to not be available. */
8215 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008216#else
8217 int result;
8218#endif
8219
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008220 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8221 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8222 return NULL;
8223 }
8224
Larry Hastings9cf065c2012-06-22 16:30:09 -07008225#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008226
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008227 if (windows_has_symlink_unprivileged_flag) {
8228 /* Allow non-admin symlinks if system allows it. */
8229 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8230 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008231
Larry Hastings9cf065c2012-06-22 16:30:09 -07008232 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008233 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008234 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8235 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8236 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8237 }
8238
8239 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008240 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008241 Py_END_ALLOW_THREADS
8242
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008243 if (windows_has_symlink_unprivileged_flag && !result &&
8244 ERROR_INVALID_PARAMETER == GetLastError()) {
8245
8246 Py_BEGIN_ALLOW_THREADS
8247 _Py_BEGIN_SUPPRESS_IPH
8248 /* This error might be caused by
8249 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8250 Try again, and update windows_has_symlink_unprivileged_flag if we
8251 are successful this time.
8252
8253 NOTE: There is a risk of a race condition here if there are other
8254 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8255 another process (or thread) changes that condition in between our
8256 calls to CreateSymbolicLink.
8257 */
8258 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8259 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8260 _Py_END_SUPPRESS_IPH
8261 Py_END_ALLOW_THREADS
8262
8263 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8264 windows_has_symlink_unprivileged_flag = FALSE;
8265 }
8266 }
8267
Larry Hastings2f936352014-08-05 14:04:04 +10008268 if (!result)
8269 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008270
8271#else
8272
Steve Dower6921e732018-03-05 14:26:08 -08008273 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8274 PyErr_SetString(PyExc_ValueError,
8275 "symlink: src and dst must be the same type");
8276 return NULL;
8277 }
8278
Larry Hastings9cf065c2012-06-22 16:30:09 -07008279 Py_BEGIN_ALLOW_THREADS
8280#if HAVE_SYMLINKAT
8281 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10008282 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008283 else
8284#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008285 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008286 Py_END_ALLOW_THREADS
8287
Larry Hastings2f936352014-08-05 14:04:04 +10008288 if (result)
8289 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008290#endif
8291
Larry Hastings2f936352014-08-05 14:04:04 +10008292 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008293}
8294#endif /* HAVE_SYMLINK */
8295
Larry Hastings9cf065c2012-06-22 16:30:09 -07008296
Brian Curtind40e6f72010-07-08 21:39:08 +00008297
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008298
Larry Hastings605a62d2012-06-24 04:33:36 -07008299static PyStructSequence_Field times_result_fields[] = {
8300 {"user", "user time"},
8301 {"system", "system time"},
8302 {"children_user", "user time of children"},
8303 {"children_system", "system time of children"},
8304 {"elapsed", "elapsed time since an arbitrary point in the past"},
8305 {NULL}
8306};
8307
8308PyDoc_STRVAR(times_result__doc__,
8309"times_result: Result from os.times().\n\n\
8310This object may be accessed either as a tuple of\n\
8311 (user, system, children_user, children_system, elapsed),\n\
8312or via the attributes user, system, children_user, children_system,\n\
8313and elapsed.\n\
8314\n\
8315See os.times for more information.");
8316
8317static PyStructSequence_Desc times_result_desc = {
8318 "times_result", /* name */
8319 times_result__doc__, /* doc */
8320 times_result_fields,
8321 5
8322};
8323
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008324#ifdef MS_WINDOWS
8325#define HAVE_TIMES /* mandatory, for the method table */
8326#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008327
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008328#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008329
8330static PyObject *
8331build_times_result(double user, double system,
8332 double children_user, double children_system,
8333 double elapsed)
8334{
Eddie Elizondob3966632019-11-05 07:16:14 -08008335 PyObject *TimesResultType = _posixstate_global->TimesResultType;
8336 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008337 if (value == NULL)
8338 return NULL;
8339
8340#define SET(i, field) \
8341 { \
8342 PyObject *o = PyFloat_FromDouble(field); \
8343 if (!o) { \
8344 Py_DECREF(value); \
8345 return NULL; \
8346 } \
8347 PyStructSequence_SET_ITEM(value, i, o); \
8348 } \
8349
8350 SET(0, user);
8351 SET(1, system);
8352 SET(2, children_user);
8353 SET(3, children_system);
8354 SET(4, elapsed);
8355
8356#undef SET
8357
8358 return value;
8359}
8360
Larry Hastings605a62d2012-06-24 04:33:36 -07008361
Larry Hastings2f936352014-08-05 14:04:04 +10008362#ifndef MS_WINDOWS
8363#define NEED_TICKS_PER_SECOND
8364static long ticks_per_second = -1;
8365#endif /* MS_WINDOWS */
8366
8367/*[clinic input]
8368os.times
8369
8370Return a collection containing process timing information.
8371
8372The object returned behaves like a named tuple with these fields:
8373 (utime, stime, cutime, cstime, elapsed_time)
8374All fields are floating point numbers.
8375[clinic start generated code]*/
8376
Larry Hastings2f936352014-08-05 14:04:04 +10008377static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008378os_times_impl(PyObject *module)
8379/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008380#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008381{
Victor Stinner8c62be82010-05-06 00:08:46 +00008382 FILETIME create, exit, kernel, user;
8383 HANDLE hProc;
8384 hProc = GetCurrentProcess();
8385 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8386 /* The fields of a FILETIME structure are the hi and lo part
8387 of a 64-bit value expressed in 100 nanosecond units.
8388 1e7 is one second in such units; 1e-7 the inverse.
8389 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8390 */
Larry Hastings605a62d2012-06-24 04:33:36 -07008391 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00008392 (double)(user.dwHighDateTime*429.4967296 +
8393 user.dwLowDateTime*1e-7),
8394 (double)(kernel.dwHighDateTime*429.4967296 +
8395 kernel.dwLowDateTime*1e-7),
8396 (double)0,
8397 (double)0,
8398 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008399}
Larry Hastings2f936352014-08-05 14:04:04 +10008400#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008401{
Larry Hastings2f936352014-08-05 14:04:04 +10008402
8403
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008404 struct tms t;
8405 clock_t c;
8406 errno = 0;
8407 c = times(&t);
8408 if (c == (clock_t) -1)
8409 return posix_error();
8410 return build_times_result(
8411 (double)t.tms_utime / ticks_per_second,
8412 (double)t.tms_stime / ticks_per_second,
8413 (double)t.tms_cutime / ticks_per_second,
8414 (double)t.tms_cstime / ticks_per_second,
8415 (double)c / ticks_per_second);
8416}
Larry Hastings2f936352014-08-05 14:04:04 +10008417#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008418#endif /* HAVE_TIMES */
8419
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008420
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008421#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008422/*[clinic input]
8423os.getsid
8424
8425 pid: pid_t
8426 /
8427
8428Call the system call getsid(pid) and return the result.
8429[clinic start generated code]*/
8430
Larry Hastings2f936352014-08-05 14:04:04 +10008431static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008432os_getsid_impl(PyObject *module, pid_t pid)
8433/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008434{
Victor Stinner8c62be82010-05-06 00:08:46 +00008435 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008436 sid = getsid(pid);
8437 if (sid < 0)
8438 return posix_error();
8439 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008440}
8441#endif /* HAVE_GETSID */
8442
8443
Guido van Rossumb6775db1994-08-01 11:34:53 +00008444#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008445/*[clinic input]
8446os.setsid
8447
8448Call the system call setsid().
8449[clinic start generated code]*/
8450
Larry Hastings2f936352014-08-05 14:04:04 +10008451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008452os_setsid_impl(PyObject *module)
8453/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008454{
Victor Stinner8c62be82010-05-06 00:08:46 +00008455 if (setsid() < 0)
8456 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008457 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008458}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008459#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008460
Larry Hastings2f936352014-08-05 14:04:04 +10008461
Guido van Rossumb6775db1994-08-01 11:34:53 +00008462#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008463/*[clinic input]
8464os.setpgid
8465
8466 pid: pid_t
8467 pgrp: pid_t
8468 /
8469
8470Call the system call setpgid(pid, pgrp).
8471[clinic start generated code]*/
8472
Larry Hastings2f936352014-08-05 14:04:04 +10008473static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008474os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8475/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008476{
Victor Stinner8c62be82010-05-06 00:08:46 +00008477 if (setpgid(pid, pgrp) < 0)
8478 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008479 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008480}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008481#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008482
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008483
Guido van Rossumb6775db1994-08-01 11:34:53 +00008484#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008485/*[clinic input]
8486os.tcgetpgrp
8487
8488 fd: int
8489 /
8490
8491Return the process group associated with the terminal specified by fd.
8492[clinic start generated code]*/
8493
Larry Hastings2f936352014-08-05 14:04:04 +10008494static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008495os_tcgetpgrp_impl(PyObject *module, int fd)
8496/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008497{
8498 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008499 if (pgid < 0)
8500 return posix_error();
8501 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008502}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008503#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008504
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008505
Guido van Rossumb6775db1994-08-01 11:34:53 +00008506#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008507/*[clinic input]
8508os.tcsetpgrp
8509
8510 fd: int
8511 pgid: pid_t
8512 /
8513
8514Set the process group associated with the terminal specified by fd.
8515[clinic start generated code]*/
8516
Larry Hastings2f936352014-08-05 14:04:04 +10008517static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008518os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8519/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008520{
Victor Stinner8c62be82010-05-06 00:08:46 +00008521 if (tcsetpgrp(fd, pgid) < 0)
8522 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008523 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008524}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008525#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008526
Guido van Rossum687dd131993-05-17 08:34:16 +00008527/* Functions acting on file descriptors */
8528
Victor Stinnerdaf45552013-08-28 00:53:59 +02008529#ifdef O_CLOEXEC
8530extern int _Py_open_cloexec_works;
8531#endif
8532
Larry Hastings2f936352014-08-05 14:04:04 +10008533
8534/*[clinic input]
8535os.open -> int
8536 path: path_t
8537 flags: int
8538 mode: int = 0o777
8539 *
8540 dir_fd: dir_fd(requires='openat') = None
8541
8542# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8543
8544Open a file for low level IO. Returns a file descriptor (integer).
8545
8546If dir_fd is not None, it should be a file descriptor open to a directory,
8547 and path should be relative; path will then be relative to that directory.
8548dir_fd may not be implemented on your platform.
8549 If it is unavailable, using it will raise a NotImplementedError.
8550[clinic start generated code]*/
8551
Larry Hastings2f936352014-08-05 14:04:04 +10008552static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008553os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8554/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008555{
8556 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008557 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008558
Victor Stinnerdaf45552013-08-28 00:53:59 +02008559#ifdef O_CLOEXEC
8560 int *atomic_flag_works = &_Py_open_cloexec_works;
8561#elif !defined(MS_WINDOWS)
8562 int *atomic_flag_works = NULL;
8563#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008564
Victor Stinnerdaf45552013-08-28 00:53:59 +02008565#ifdef MS_WINDOWS
8566 flags |= O_NOINHERIT;
8567#elif defined(O_CLOEXEC)
8568 flags |= O_CLOEXEC;
8569#endif
8570
Steve Dowerb82e17e2019-05-23 08:45:22 -07008571 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
8572 return -1;
8573 }
8574
Steve Dower8fc89802015-04-12 00:26:27 -04008575 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008576 do {
8577 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008578#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008579 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008580#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008581#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008582 if (dir_fd != DEFAULT_DIR_FD)
8583 fd = openat(dir_fd, path->narrow, flags, mode);
8584 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008585#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008586 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008587#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008588 Py_END_ALLOW_THREADS
8589 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008590 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008591
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008592 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008593 if (!async_err)
8594 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008595 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008596 }
8597
Victor Stinnerdaf45552013-08-28 00:53:59 +02008598#ifndef MS_WINDOWS
8599 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8600 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008601 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008602 }
8603#endif
8604
Larry Hastings2f936352014-08-05 14:04:04 +10008605 return fd;
8606}
8607
8608
8609/*[clinic input]
8610os.close
8611
8612 fd: int
8613
8614Close a file descriptor.
8615[clinic start generated code]*/
8616
Barry Warsaw53699e91996-12-10 23:23:01 +00008617static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008618os_close_impl(PyObject *module, int fd)
8619/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008620{
Larry Hastings2f936352014-08-05 14:04:04 +10008621 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008622 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8623 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8624 * for more details.
8625 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008626 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008627 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008628 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008629 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008630 Py_END_ALLOW_THREADS
8631 if (res < 0)
8632 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008633 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008634}
8635
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008636
Jakub Kulíke20134f2019-09-11 17:11:57 +02008637#ifdef HAVE_FDWALK
8638static int
8639_fdwalk_close_func(void *lohi, int fd)
8640{
8641 int lo = ((int *)lohi)[0];
8642 int hi = ((int *)lohi)[1];
8643
8644 if (fd >= hi)
8645 return 1;
8646 else if (fd >= lo)
8647 close(fd);
8648 return 0;
8649}
8650#endif /* HAVE_FDWALK */
8651
Larry Hastings2f936352014-08-05 14:04:04 +10008652/*[clinic input]
8653os.closerange
8654
8655 fd_low: int
8656 fd_high: int
8657 /
8658
8659Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8660[clinic start generated code]*/
8661
Larry Hastings2f936352014-08-05 14:04:04 +10008662static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008663os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8664/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008665{
Jakub Kulíke20134f2019-09-11 17:11:57 +02008666#ifdef HAVE_FDWALK
8667 int lohi[2];
8668#else
Larry Hastings2f936352014-08-05 14:04:04 +10008669 int i;
Jakub Kulíke20134f2019-09-11 17:11:57 +02008670#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008671 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008672 _Py_BEGIN_SUPPRESS_IPH
Jakub Kulíke20134f2019-09-11 17:11:57 +02008673#ifdef HAVE_FDWALK
8674 lohi[0] = Py_MAX(fd_low, 0);
8675 lohi[1] = fd_high;
8676 fdwalk(_fdwalk_close_func, lohi);
8677#else
Benjamin Peterson207116b2016-09-08 11:28:06 -07008678 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008679 close(i);
Jakub Kulíke20134f2019-09-11 17:11:57 +02008680#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008681 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008682 Py_END_ALLOW_THREADS
8683 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008684}
8685
8686
Larry Hastings2f936352014-08-05 14:04:04 +10008687/*[clinic input]
8688os.dup -> int
8689
8690 fd: int
8691 /
8692
8693Return a duplicate of a file descriptor.
8694[clinic start generated code]*/
8695
Larry Hastings2f936352014-08-05 14:04:04 +10008696static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008697os_dup_impl(PyObject *module, int fd)
8698/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008699{
8700 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008701}
8702
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008703
Larry Hastings2f936352014-08-05 14:04:04 +10008704/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008705os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008706 fd: int
8707 fd2: int
8708 inheritable: bool=True
8709
8710Duplicate file descriptor.
8711[clinic start generated code]*/
8712
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008713static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008714os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008715/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008716{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008717 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008718#if defined(HAVE_DUP3) && \
8719 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8720 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008721 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008722#endif
8723
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008724 if (fd < 0 || fd2 < 0) {
8725 posix_error();
8726 return -1;
8727 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008728
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008729 /* dup2() can fail with EINTR if the target FD is already open, because it
8730 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8731 * upon close(), and therefore below.
8732 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008733#ifdef MS_WINDOWS
8734 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008735 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008736 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008737 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008738 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008739 if (res < 0) {
8740 posix_error();
8741 return -1;
8742 }
8743 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008744
8745 /* Character files like console cannot be make non-inheritable */
8746 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8747 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008748 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008749 }
8750
8751#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8752 Py_BEGIN_ALLOW_THREADS
8753 if (!inheritable)
8754 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8755 else
8756 res = dup2(fd, fd2);
8757 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008758 if (res < 0) {
8759 posix_error();
8760 return -1;
8761 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008762
8763#else
8764
8765#ifdef HAVE_DUP3
8766 if (!inheritable && dup3_works != 0) {
8767 Py_BEGIN_ALLOW_THREADS
8768 res = dup3(fd, fd2, O_CLOEXEC);
8769 Py_END_ALLOW_THREADS
8770 if (res < 0) {
8771 if (dup3_works == -1)
8772 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008773 if (dup3_works) {
8774 posix_error();
8775 return -1;
8776 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008777 }
8778 }
8779
8780 if (inheritable || dup3_works == 0)
8781 {
8782#endif
8783 Py_BEGIN_ALLOW_THREADS
8784 res = dup2(fd, fd2);
8785 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008786 if (res < 0) {
8787 posix_error();
8788 return -1;
8789 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008790
8791 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8792 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008793 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008794 }
8795#ifdef HAVE_DUP3
8796 }
8797#endif
8798
8799#endif
8800
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008801 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008802}
8803
Larry Hastings2f936352014-08-05 14:04:04 +10008804
Ross Lagerwall7807c352011-03-17 20:20:30 +02008805#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008806/*[clinic input]
8807os.lockf
8808
8809 fd: int
8810 An open file descriptor.
8811 command: int
8812 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8813 length: Py_off_t
8814 The number of bytes to lock, starting at the current position.
8815 /
8816
8817Apply, test or remove a POSIX lock on an open file descriptor.
8818
8819[clinic start generated code]*/
8820
Larry Hastings2f936352014-08-05 14:04:04 +10008821static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008822os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8823/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008824{
8825 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008826
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008827 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
8828 return NULL;
8829 }
8830
Ross Lagerwall7807c352011-03-17 20:20:30 +02008831 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008832 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008833 Py_END_ALLOW_THREADS
8834
8835 if (res < 0)
8836 return posix_error();
8837
8838 Py_RETURN_NONE;
8839}
Larry Hastings2f936352014-08-05 14:04:04 +10008840#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008842
Larry Hastings2f936352014-08-05 14:04:04 +10008843/*[clinic input]
8844os.lseek -> Py_off_t
8845
8846 fd: int
8847 position: Py_off_t
8848 how: int
8849 /
8850
8851Set the position of a file descriptor. Return the new position.
8852
8853Return the new cursor position in number of bytes
8854relative to the beginning of the file.
8855[clinic start generated code]*/
8856
Larry Hastings2f936352014-08-05 14:04:04 +10008857static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008858os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8859/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008860{
8861 Py_off_t result;
8862
Guido van Rossum687dd131993-05-17 08:34:16 +00008863#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8865 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008866 case 0: how = SEEK_SET; break;
8867 case 1: how = SEEK_CUR; break;
8868 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008869 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008870#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008871
Victor Stinner8c62be82010-05-06 00:08:46 +00008872 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008873 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008874#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008875 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008876#else
Larry Hastings2f936352014-08-05 14:04:04 +10008877 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008878#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008879 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008880 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008881 if (result < 0)
8882 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008883
Larry Hastings2f936352014-08-05 14:04:04 +10008884 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008885}
8886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008887
Larry Hastings2f936352014-08-05 14:04:04 +10008888/*[clinic input]
8889os.read
8890 fd: int
8891 length: Py_ssize_t
8892 /
8893
8894Read from a file descriptor. Returns a bytes object.
8895[clinic start generated code]*/
8896
Larry Hastings2f936352014-08-05 14:04:04 +10008897static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008898os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8899/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008900{
Victor Stinner8c62be82010-05-06 00:08:46 +00008901 Py_ssize_t n;
8902 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008903
8904 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008905 errno = EINVAL;
8906 return posix_error();
8907 }
Larry Hastings2f936352014-08-05 14:04:04 +10008908
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008909 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008910
8911 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008912 if (buffer == NULL)
8913 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008914
Victor Stinner66aab0c2015-03-19 22:53:20 +01008915 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8916 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008917 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008918 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008919 }
Larry Hastings2f936352014-08-05 14:04:04 +10008920
8921 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008922 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008923
Victor Stinner8c62be82010-05-06 00:08:46 +00008924 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008925}
8926
Ross Lagerwall7807c352011-03-17 20:20:30 +02008927#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008928 || defined(__APPLE__))) \
8929 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8930 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8931static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008932iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008933{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008934 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008935
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008936 *iov = PyMem_New(struct iovec, cnt);
8937 if (*iov == NULL) {
8938 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008939 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008940 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008941
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008942 *buf = PyMem_New(Py_buffer, cnt);
8943 if (*buf == NULL) {
8944 PyMem_Del(*iov);
8945 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008946 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008947 }
8948
8949 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008950 PyObject *item = PySequence_GetItem(seq, i);
8951 if (item == NULL)
8952 goto fail;
8953 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8954 Py_DECREF(item);
8955 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008956 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008957 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008958 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008959 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008960 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008961 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008962
8963fail:
8964 PyMem_Del(*iov);
8965 for (j = 0; j < i; j++) {
8966 PyBuffer_Release(&(*buf)[j]);
8967 }
8968 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008969 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008970}
8971
8972static void
8973iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8974{
8975 int i;
8976 PyMem_Del(iov);
8977 for (i = 0; i < cnt; i++) {
8978 PyBuffer_Release(&buf[i]);
8979 }
8980 PyMem_Del(buf);
8981}
8982#endif
8983
Larry Hastings2f936352014-08-05 14:04:04 +10008984
Ross Lagerwall7807c352011-03-17 20:20:30 +02008985#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008986/*[clinic input]
8987os.readv -> Py_ssize_t
8988
8989 fd: int
8990 buffers: object
8991 /
8992
8993Read from a file descriptor fd into an iterable of buffers.
8994
8995The buffers should be mutable buffers accepting bytes.
8996readv will transfer data into each buffer until it is full
8997and then move on to the next buffer in the sequence to hold
8998the rest of the data.
8999
9000readv returns the total number of bytes read,
9001which may be less than the total capacity of all the buffers.
9002[clinic start generated code]*/
9003
Larry Hastings2f936352014-08-05 14:04:04 +10009004static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009005os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9006/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009007{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009008 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009009 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009010 struct iovec *iov;
9011 Py_buffer *buf;
9012
Larry Hastings2f936352014-08-05 14:04:04 +10009013 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009014 PyErr_SetString(PyExc_TypeError,
9015 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009016 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009017 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009018
Larry Hastings2f936352014-08-05 14:04:04 +10009019 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009020 if (cnt < 0)
9021 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009022
9023 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9024 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009025
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009026 do {
9027 Py_BEGIN_ALLOW_THREADS
9028 n = readv(fd, iov, cnt);
9029 Py_END_ALLOW_THREADS
9030 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009031
9032 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009033 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009034 if (!async_err)
9035 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009036 return -1;
9037 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009038
Larry Hastings2f936352014-08-05 14:04:04 +10009039 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009040}
Larry Hastings2f936352014-08-05 14:04:04 +10009041#endif /* HAVE_READV */
9042
Ross Lagerwall7807c352011-03-17 20:20:30 +02009043
9044#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009045/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009046os.pread
9047
9048 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009049 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009050 offset: Py_off_t
9051 /
9052
9053Read a number of bytes from a file descriptor starting at a particular offset.
9054
9055Read length bytes from file descriptor fd, starting at offset bytes from
9056the beginning of the file. The file offset remains unchanged.
9057[clinic start generated code]*/
9058
Larry Hastings2f936352014-08-05 14:04:04 +10009059static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009060os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9061/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009062{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009063 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009064 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009065 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009066
Larry Hastings2f936352014-08-05 14:04:04 +10009067 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009068 errno = EINVAL;
9069 return posix_error();
9070 }
Larry Hastings2f936352014-08-05 14:04:04 +10009071 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009072 if (buffer == NULL)
9073 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009074
9075 do {
9076 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009077 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009078 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009079 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009080 Py_END_ALLOW_THREADS
9081 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9082
Ross Lagerwall7807c352011-03-17 20:20:30 +02009083 if (n < 0) {
9084 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009085 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009086 }
Larry Hastings2f936352014-08-05 14:04:04 +10009087 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009088 _PyBytes_Resize(&buffer, n);
9089 return buffer;
9090}
Larry Hastings2f936352014-08-05 14:04:04 +10009091#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009092
Pablo Galindo4defba32018-01-27 16:16:37 +00009093#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9094/*[clinic input]
9095os.preadv -> Py_ssize_t
9096
9097 fd: int
9098 buffers: object
9099 offset: Py_off_t
9100 flags: int = 0
9101 /
9102
9103Reads from a file descriptor into a number of mutable bytes-like objects.
9104
9105Combines the functionality of readv() and pread(). As readv(), it will
9106transfer data into each buffer until it is full and then move on to the next
9107buffer in the sequence to hold the rest of the data. Its fourth argument,
9108specifies the file offset at which the input operation is to be performed. It
9109will return the total number of bytes read (which can be less than the total
9110capacity of all the objects).
9111
9112The flags argument contains a bitwise OR of zero or more of the following flags:
9113
9114- RWF_HIPRI
9115- RWF_NOWAIT
9116
9117Using non-zero flags requires Linux 4.6 or newer.
9118[clinic start generated code]*/
9119
9120static Py_ssize_t
9121os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9122 int flags)
9123/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9124{
9125 Py_ssize_t cnt, n;
9126 int async_err = 0;
9127 struct iovec *iov;
9128 Py_buffer *buf;
9129
9130 if (!PySequence_Check(buffers)) {
9131 PyErr_SetString(PyExc_TypeError,
9132 "preadv2() arg 2 must be a sequence");
9133 return -1;
9134 }
9135
9136 cnt = PySequence_Size(buffers);
9137 if (cnt < 0) {
9138 return -1;
9139 }
9140
9141#ifndef HAVE_PREADV2
9142 if(flags != 0) {
9143 argument_unavailable_error("preadv2", "flags");
9144 return -1;
9145 }
9146#endif
9147
9148 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9149 return -1;
9150 }
9151#ifdef HAVE_PREADV2
9152 do {
9153 Py_BEGIN_ALLOW_THREADS
9154 _Py_BEGIN_SUPPRESS_IPH
9155 n = preadv2(fd, iov, cnt, offset, flags);
9156 _Py_END_SUPPRESS_IPH
9157 Py_END_ALLOW_THREADS
9158 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9159#else
9160 do {
9161 Py_BEGIN_ALLOW_THREADS
9162 _Py_BEGIN_SUPPRESS_IPH
9163 n = preadv(fd, iov, cnt, offset);
9164 _Py_END_SUPPRESS_IPH
9165 Py_END_ALLOW_THREADS
9166 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9167#endif
9168
9169 iov_cleanup(iov, buf, cnt);
9170 if (n < 0) {
9171 if (!async_err) {
9172 posix_error();
9173 }
9174 return -1;
9175 }
9176
9177 return n;
9178}
9179#endif /* HAVE_PREADV */
9180
Larry Hastings2f936352014-08-05 14:04:04 +10009181
9182/*[clinic input]
9183os.write -> Py_ssize_t
9184
9185 fd: int
9186 data: Py_buffer
9187 /
9188
9189Write a bytes object to a file descriptor.
9190[clinic start generated code]*/
9191
Larry Hastings2f936352014-08-05 14:04:04 +10009192static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009193os_write_impl(PyObject *module, int fd, Py_buffer *data)
9194/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009195{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009196 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009197}
9198
9199#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009200PyDoc_STRVAR(posix_sendfile__doc__,
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009201"sendfile(out_fd, in_fd, offset, count) -> byteswritten\n\
9202sendfile(out_fd, in_fd, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009203 -> byteswritten\n\
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009204Copy count bytes from file descriptor in_fd to file descriptor out_fd.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009205
Larry Hastings2f936352014-08-05 14:04:04 +10009206/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009207static PyObject *
9208posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
9209{
9210 int in, out;
9211 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009212 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009213 off_t offset;
9214
9215#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9216#ifndef __APPLE__
9217 Py_ssize_t len;
9218#endif
9219 PyObject *headers = NULL, *trailers = NULL;
9220 Py_buffer *hbuf, *tbuf;
9221 off_t sbytes;
9222 struct sf_hdtr sf;
9223 int flags = 0;
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009224 static char *keywords[] = {"out_fd", "in_fd",
Benjamin Petersond8a43b42011-02-26 21:35:16 +00009225 "offset", "count",
9226 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009227
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009228 sf.headers = NULL;
9229 sf.trailers = NULL;
9230
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009231#ifdef __APPLE__
9232 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10009233 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009234#else
9235 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10009236 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009237#endif
9238 &headers, &trailers, &flags))
9239 return NULL;
9240 if (headers != NULL) {
9241 if (!PySequence_Check(headers)) {
9242 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009243 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009244 return NULL;
9245 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009246 Py_ssize_t i = PySequence_Size(headers);
9247 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009248 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009249 if (i > INT_MAX) {
9250 PyErr_SetString(PyExc_OverflowError,
9251 "sendfile() header is too large");
9252 return NULL;
9253 }
9254 if (i > 0) {
9255 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009256 if (iov_setup(&(sf.headers), &hbuf,
9257 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009258 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009259#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009260 for (i = 0; i < sf.hdr_cnt; i++) {
9261 Py_ssize_t blen = sf.headers[i].iov_len;
9262# define OFF_T_MAX 0x7fffffffffffffff
9263 if (sbytes >= OFF_T_MAX - blen) {
9264 PyErr_SetString(PyExc_OverflowError,
9265 "sendfile() header is too large");
9266 return NULL;
9267 }
9268 sbytes += blen;
9269 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009270#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009271 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009272 }
9273 }
9274 if (trailers != NULL) {
9275 if (!PySequence_Check(trailers)) {
9276 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009277 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009278 return NULL;
9279 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009280 Py_ssize_t i = PySequence_Size(trailers);
9281 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009282 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009283 if (i > INT_MAX) {
9284 PyErr_SetString(PyExc_OverflowError,
9285 "sendfile() trailer is too large");
9286 return NULL;
9287 }
9288 if (i > 0) {
9289 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009290 if (iov_setup(&(sf.trailers), &tbuf,
9291 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009292 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009293 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009294 }
9295 }
9296
Steve Dower8fc89802015-04-12 00:26:27 -04009297 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009298 do {
9299 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009300#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009301 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009302#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009303 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009304#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009305 Py_END_ALLOW_THREADS
9306 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009307 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009308
9309 if (sf.headers != NULL)
9310 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9311 if (sf.trailers != NULL)
9312 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9313
9314 if (ret < 0) {
9315 if ((errno == EAGAIN) || (errno == EBUSY)) {
9316 if (sbytes != 0) {
9317 // some data has been sent
9318 goto done;
9319 }
9320 else {
9321 // no data has been sent; upper application is supposed
9322 // to retry on EAGAIN or EBUSY
9323 return posix_error();
9324 }
9325 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009326 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009327 }
9328 goto done;
9329
9330done:
9331 #if !defined(HAVE_LARGEFILE_SUPPORT)
9332 return Py_BuildValue("l", sbytes);
9333 #else
9334 return Py_BuildValue("L", sbytes);
9335 #endif
9336
9337#else
9338 Py_ssize_t count;
9339 PyObject *offobj;
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009340 static char *keywords[] = {"out_fd", "in_fd",
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009341 "offset", "count", NULL};
9342 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
9343 keywords, &out, &in, &offobj, &count))
9344 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009345#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009346 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009347 do {
9348 Py_BEGIN_ALLOW_THREADS
9349 ret = sendfile(out, in, NULL, count);
9350 Py_END_ALLOW_THREADS
9351 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009352 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009353 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009354 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009355 }
9356#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009357 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009358 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009359
9360 do {
9361 Py_BEGIN_ALLOW_THREADS
9362 ret = sendfile(out, in, &offset, count);
9363 Py_END_ALLOW_THREADS
9364 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009365 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009366 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009367 return Py_BuildValue("n", ret);
9368#endif
9369}
Larry Hastings2f936352014-08-05 14:04:04 +10009370#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009371
Larry Hastings2f936352014-08-05 14:04:04 +10009372
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009373#if defined(__APPLE__)
9374/*[clinic input]
9375os._fcopyfile
9376
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009377 in_fd: int
9378 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009379 flags: int
9380 /
9381
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009382Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009383[clinic start generated code]*/
9384
9385static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009386os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9387/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009388{
9389 int ret;
9390
9391 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009392 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009393 Py_END_ALLOW_THREADS
9394 if (ret < 0)
9395 return posix_error();
9396 Py_RETURN_NONE;
9397}
9398#endif
9399
9400
Larry Hastings2f936352014-08-05 14:04:04 +10009401/*[clinic input]
9402os.fstat
9403
9404 fd : int
9405
9406Perform a stat system call on the given file descriptor.
9407
9408Like stat(), but for an open file descriptor.
9409Equivalent to os.stat(fd).
9410[clinic start generated code]*/
9411
Larry Hastings2f936352014-08-05 14:04:04 +10009412static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009413os_fstat_impl(PyObject *module, int fd)
9414/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009415{
Victor Stinner8c62be82010-05-06 00:08:46 +00009416 STRUCT_STAT st;
9417 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009418 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009419
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009420 do {
9421 Py_BEGIN_ALLOW_THREADS
9422 res = FSTAT(fd, &st);
9423 Py_END_ALLOW_THREADS
9424 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009425 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009426#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009427 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009428#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009429 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009430#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009431 }
Tim Peters5aa91602002-01-30 05:46:57 +00009432
Victor Stinner4195b5c2012-02-08 23:03:19 +01009433 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009434}
9435
Larry Hastings2f936352014-08-05 14:04:04 +10009436
9437/*[clinic input]
9438os.isatty -> bool
9439 fd: int
9440 /
9441
9442Return True if the fd is connected to a terminal.
9443
9444Return True if the file descriptor is an open file descriptor
9445connected to the slave end of a terminal.
9446[clinic start generated code]*/
9447
Larry Hastings2f936352014-08-05 14:04:04 +10009448static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009449os_isatty_impl(PyObject *module, int fd)
9450/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009451{
Steve Dower8fc89802015-04-12 00:26:27 -04009452 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009453 _Py_BEGIN_SUPPRESS_IPH
9454 return_value = isatty(fd);
9455 _Py_END_SUPPRESS_IPH
9456 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009457}
9458
9459
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009460#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009461/*[clinic input]
9462os.pipe
9463
9464Create a pipe.
9465
9466Returns a tuple of two file descriptors:
9467 (read_fd, write_fd)
9468[clinic start generated code]*/
9469
Larry Hastings2f936352014-08-05 14:04:04 +10009470static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009471os_pipe_impl(PyObject *module)
9472/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009473{
Victor Stinner8c62be82010-05-06 00:08:46 +00009474 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009475#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009476 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009477 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009478 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009479#else
9480 int res;
9481#endif
9482
9483#ifdef MS_WINDOWS
9484 attr.nLength = sizeof(attr);
9485 attr.lpSecurityDescriptor = NULL;
9486 attr.bInheritHandle = FALSE;
9487
9488 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009489 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009490 ok = CreatePipe(&read, &write, &attr, 0);
9491 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009492 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9493 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009494 if (fds[0] == -1 || fds[1] == -1) {
9495 CloseHandle(read);
9496 CloseHandle(write);
9497 ok = 0;
9498 }
9499 }
Steve Dowerc3630612016-11-19 18:41:16 -08009500 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009501 Py_END_ALLOW_THREADS
9502
Victor Stinner8c62be82010-05-06 00:08:46 +00009503 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009504 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009505#else
9506
9507#ifdef HAVE_PIPE2
9508 Py_BEGIN_ALLOW_THREADS
9509 res = pipe2(fds, O_CLOEXEC);
9510 Py_END_ALLOW_THREADS
9511
9512 if (res != 0 && errno == ENOSYS)
9513 {
9514#endif
9515 Py_BEGIN_ALLOW_THREADS
9516 res = pipe(fds);
9517 Py_END_ALLOW_THREADS
9518
9519 if (res == 0) {
9520 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9521 close(fds[0]);
9522 close(fds[1]);
9523 return NULL;
9524 }
9525 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9526 close(fds[0]);
9527 close(fds[1]);
9528 return NULL;
9529 }
9530 }
9531#ifdef HAVE_PIPE2
9532 }
9533#endif
9534
9535 if (res != 0)
9536 return PyErr_SetFromErrno(PyExc_OSError);
9537#endif /* !MS_WINDOWS */
9538 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009539}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009540#endif /* HAVE_PIPE */
9541
Larry Hastings2f936352014-08-05 14:04:04 +10009542
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009543#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009544/*[clinic input]
9545os.pipe2
9546
9547 flags: int
9548 /
9549
9550Create a pipe with flags set atomically.
9551
9552Returns a tuple of two file descriptors:
9553 (read_fd, write_fd)
9554
9555flags can be constructed by ORing together one or more of these values:
9556O_NONBLOCK, O_CLOEXEC.
9557[clinic start generated code]*/
9558
Larry Hastings2f936352014-08-05 14:04:04 +10009559static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009560os_pipe2_impl(PyObject *module, int flags)
9561/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009562{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009563 int fds[2];
9564 int res;
9565
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009566 res = pipe2(fds, flags);
9567 if (res != 0)
9568 return posix_error();
9569 return Py_BuildValue("(ii)", fds[0], fds[1]);
9570}
9571#endif /* HAVE_PIPE2 */
9572
Larry Hastings2f936352014-08-05 14:04:04 +10009573
Ross Lagerwall7807c352011-03-17 20:20:30 +02009574#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009575/*[clinic input]
9576os.writev -> Py_ssize_t
9577 fd: int
9578 buffers: object
9579 /
9580
9581Iterate over buffers, and write the contents of each to a file descriptor.
9582
9583Returns the total number of bytes written.
9584buffers must be a sequence of bytes-like objects.
9585[clinic start generated code]*/
9586
Larry Hastings2f936352014-08-05 14:04:04 +10009587static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009588os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9589/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009590{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009591 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009592 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009593 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009594 struct iovec *iov;
9595 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009596
9597 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009598 PyErr_SetString(PyExc_TypeError,
9599 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009600 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009601 }
Larry Hastings2f936352014-08-05 14:04:04 +10009602 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009603 if (cnt < 0)
9604 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009605
Larry Hastings2f936352014-08-05 14:04:04 +10009606 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9607 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009608 }
9609
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009610 do {
9611 Py_BEGIN_ALLOW_THREADS
9612 result = writev(fd, iov, cnt);
9613 Py_END_ALLOW_THREADS
9614 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009615
9616 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009617 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009618 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009619
Georg Brandl306336b2012-06-24 12:55:33 +02009620 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009621}
Larry Hastings2f936352014-08-05 14:04:04 +10009622#endif /* HAVE_WRITEV */
9623
9624
9625#ifdef HAVE_PWRITE
9626/*[clinic input]
9627os.pwrite -> Py_ssize_t
9628
9629 fd: int
9630 buffer: Py_buffer
9631 offset: Py_off_t
9632 /
9633
9634Write bytes to a file descriptor starting at a particular offset.
9635
9636Write buffer to fd, starting at offset bytes from the beginning of
9637the file. Returns the number of bytes writte. Does not change the
9638current file offset.
9639[clinic start generated code]*/
9640
Larry Hastings2f936352014-08-05 14:04:04 +10009641static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009642os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9643/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009644{
9645 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009646 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009647
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009648 do {
9649 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009650 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009651 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009652 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009653 Py_END_ALLOW_THREADS
9654 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009655
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009656 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009657 posix_error();
9658 return size;
9659}
9660#endif /* HAVE_PWRITE */
9661
Pablo Galindo4defba32018-01-27 16:16:37 +00009662#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9663/*[clinic input]
9664os.pwritev -> Py_ssize_t
9665
9666 fd: int
9667 buffers: object
9668 offset: Py_off_t
9669 flags: int = 0
9670 /
9671
9672Writes the contents of bytes-like objects to a file descriptor at a given offset.
9673
9674Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9675of bytes-like objects. Buffers are processed in array order. Entire contents of first
9676buffer is written before proceeding to second, and so on. The operating system may
9677set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9678This function writes the contents of each object to the file descriptor and returns
9679the total number of bytes written.
9680
9681The flags argument contains a bitwise OR of zero or more of the following flags:
9682
9683- RWF_DSYNC
9684- RWF_SYNC
9685
9686Using non-zero flags requires Linux 4.7 or newer.
9687[clinic start generated code]*/
9688
9689static Py_ssize_t
9690os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9691 int flags)
9692/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9693{
9694 Py_ssize_t cnt;
9695 Py_ssize_t result;
9696 int async_err = 0;
9697 struct iovec *iov;
9698 Py_buffer *buf;
9699
9700 if (!PySequence_Check(buffers)) {
9701 PyErr_SetString(PyExc_TypeError,
9702 "pwritev() arg 2 must be a sequence");
9703 return -1;
9704 }
9705
9706 cnt = PySequence_Size(buffers);
9707 if (cnt < 0) {
9708 return -1;
9709 }
9710
9711#ifndef HAVE_PWRITEV2
9712 if(flags != 0) {
9713 argument_unavailable_error("pwritev2", "flags");
9714 return -1;
9715 }
9716#endif
9717
9718 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9719 return -1;
9720 }
9721#ifdef HAVE_PWRITEV2
9722 do {
9723 Py_BEGIN_ALLOW_THREADS
9724 _Py_BEGIN_SUPPRESS_IPH
9725 result = pwritev2(fd, iov, cnt, offset, flags);
9726 _Py_END_SUPPRESS_IPH
9727 Py_END_ALLOW_THREADS
9728 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9729#else
9730 do {
9731 Py_BEGIN_ALLOW_THREADS
9732 _Py_BEGIN_SUPPRESS_IPH
9733 result = pwritev(fd, iov, cnt, offset);
9734 _Py_END_SUPPRESS_IPH
9735 Py_END_ALLOW_THREADS
9736 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9737#endif
9738
9739 iov_cleanup(iov, buf, cnt);
9740 if (result < 0) {
9741 if (!async_err) {
9742 posix_error();
9743 }
9744 return -1;
9745 }
9746
9747 return result;
9748}
9749#endif /* HAVE_PWRITEV */
9750
Pablo Galindoaac4d032019-05-31 19:39:47 +01009751#ifdef HAVE_COPY_FILE_RANGE
9752/*[clinic input]
9753
9754os.copy_file_range
9755 src: int
9756 Source file descriptor.
9757 dst: int
9758 Destination file descriptor.
9759 count: Py_ssize_t
9760 Number of bytes to copy.
9761 offset_src: object = None
9762 Starting offset in src.
9763 offset_dst: object = None
9764 Starting offset in dst.
9765
9766Copy count bytes from one file descriptor to another.
9767
9768If offset_src is None, then src is read from the current position;
9769respectively for offset_dst.
9770[clinic start generated code]*/
9771
9772static PyObject *
9773os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
9774 PyObject *offset_src, PyObject *offset_dst)
9775/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
9776{
9777 off_t offset_src_val, offset_dst_val;
9778 off_t *p_offset_src = NULL;
9779 off_t *p_offset_dst = NULL;
9780 Py_ssize_t ret;
9781 int async_err = 0;
9782 /* The flags argument is provided to allow
9783 * for future extensions and currently must be to 0. */
9784 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +00009785
9786
Pablo Galindoaac4d032019-05-31 19:39:47 +01009787 if (count < 0) {
9788 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
9789 return NULL;
9790 }
9791
9792 if (offset_src != Py_None) {
9793 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
9794 return NULL;
9795 }
9796 p_offset_src = &offset_src_val;
9797 }
9798
9799 if (offset_dst != Py_None) {
9800 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
9801 return NULL;
9802 }
9803 p_offset_dst = &offset_dst_val;
9804 }
9805
9806 do {
9807 Py_BEGIN_ALLOW_THREADS
9808 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
9809 Py_END_ALLOW_THREADS
9810 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9811
9812 if (ret < 0) {
9813 return (!async_err) ? posix_error() : NULL;
9814 }
9815
9816 return PyLong_FromSsize_t(ret);
9817}
9818#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +10009819
9820#ifdef HAVE_MKFIFO
9821/*[clinic input]
9822os.mkfifo
9823
9824 path: path_t
9825 mode: int=0o666
9826 *
9827 dir_fd: dir_fd(requires='mkfifoat')=None
9828
9829Create a "fifo" (a POSIX named pipe).
9830
9831If dir_fd is not None, it should be a file descriptor open to a directory,
9832 and path should be relative; path will then be relative to that directory.
9833dir_fd may not be implemented on your platform.
9834 If it is unavailable, using it will raise a NotImplementedError.
9835[clinic start generated code]*/
9836
Larry Hastings2f936352014-08-05 14:04:04 +10009837static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009838os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9839/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009840{
9841 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009842 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009843
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009844 do {
9845 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009846#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009847 if (dir_fd != DEFAULT_DIR_FD)
9848 result = mkfifoat(dir_fd, path->narrow, mode);
9849 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009850#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009851 result = mkfifo(path->narrow, mode);
9852 Py_END_ALLOW_THREADS
9853 } while (result != 0 && errno == EINTR &&
9854 !(async_err = PyErr_CheckSignals()));
9855 if (result != 0)
9856 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009857
9858 Py_RETURN_NONE;
9859}
9860#endif /* HAVE_MKFIFO */
9861
9862
9863#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9864/*[clinic input]
9865os.mknod
9866
9867 path: path_t
9868 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009869 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009870 *
9871 dir_fd: dir_fd(requires='mknodat')=None
9872
9873Create a node in the file system.
9874
9875Create a node in the file system (file, device special file or named pipe)
9876at path. mode specifies both the permissions to use and the
9877type of node to be created, being combined (bitwise OR) with one of
9878S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9879device defines the newly created device special file (probably using
9880os.makedev()). Otherwise device is ignored.
9881
9882If dir_fd is not None, it should be a file descriptor open to a directory,
9883 and path should be relative; path will then be relative to that directory.
9884dir_fd may not be implemented on your platform.
9885 If it is unavailable, using it will raise a NotImplementedError.
9886[clinic start generated code]*/
9887
Larry Hastings2f936352014-08-05 14:04:04 +10009888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009889os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009890 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009891/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009892{
9893 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009894 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009895
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009896 do {
9897 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009898#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009899 if (dir_fd != DEFAULT_DIR_FD)
9900 result = mknodat(dir_fd, path->narrow, mode, device);
9901 else
Larry Hastings2f936352014-08-05 14:04:04 +10009902#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009903 result = mknod(path->narrow, mode, device);
9904 Py_END_ALLOW_THREADS
9905 } while (result != 0 && errno == EINTR &&
9906 !(async_err = PyErr_CheckSignals()));
9907 if (result != 0)
9908 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009909
9910 Py_RETURN_NONE;
9911}
9912#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9913
9914
9915#ifdef HAVE_DEVICE_MACROS
9916/*[clinic input]
9917os.major -> unsigned_int
9918
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009919 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009920 /
9921
9922Extracts a device major number from a raw device number.
9923[clinic start generated code]*/
9924
Larry Hastings2f936352014-08-05 14:04:04 +10009925static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009926os_major_impl(PyObject *module, dev_t device)
9927/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009928{
9929 return major(device);
9930}
9931
9932
9933/*[clinic input]
9934os.minor -> unsigned_int
9935
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009936 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009937 /
9938
9939Extracts a device minor number from a raw device number.
9940[clinic start generated code]*/
9941
Larry Hastings2f936352014-08-05 14:04:04 +10009942static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009943os_minor_impl(PyObject *module, dev_t device)
9944/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009945{
9946 return minor(device);
9947}
9948
9949
9950/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009951os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009952
9953 major: int
9954 minor: int
9955 /
9956
9957Composes a raw device number from the major and minor device numbers.
9958[clinic start generated code]*/
9959
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009960static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009961os_makedev_impl(PyObject *module, int major, int minor)
9962/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009963{
9964 return makedev(major, minor);
9965}
9966#endif /* HAVE_DEVICE_MACROS */
9967
9968
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009969#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009970/*[clinic input]
9971os.ftruncate
9972
9973 fd: int
9974 length: Py_off_t
9975 /
9976
9977Truncate a file, specified by file descriptor, to a specific length.
9978[clinic start generated code]*/
9979
Larry Hastings2f936352014-08-05 14:04:04 +10009980static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009981os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9982/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009983{
9984 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009985 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009986
Steve Dowerb82e17e2019-05-23 08:45:22 -07009987 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
9988 return NULL;
9989 }
9990
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009991 do {
9992 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009993 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009994#ifdef MS_WINDOWS
9995 result = _chsize_s(fd, length);
9996#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009997 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009998#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009999 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010000 Py_END_ALLOW_THREADS
10001 } while (result != 0 && errno == EINTR &&
10002 !(async_err = PyErr_CheckSignals()));
10003 if (result != 0)
10004 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010005 Py_RETURN_NONE;
10006}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010007#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010008
10009
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010010#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010011/*[clinic input]
10012os.truncate
10013 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10014 length: Py_off_t
10015
10016Truncate a file, specified by path, to a specific length.
10017
10018On some platforms, path may also be specified as an open file descriptor.
10019 If this functionality is unavailable, using it raises an exception.
10020[clinic start generated code]*/
10021
Larry Hastings2f936352014-08-05 14:04:04 +100010022static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010023os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10024/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010025{
10026 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010027#ifdef MS_WINDOWS
10028 int fd;
10029#endif
10030
10031 if (path->fd != -1)
10032 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010033
Steve Dowerb82e17e2019-05-23 08:45:22 -070010034 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10035 return NULL;
10036 }
10037
Larry Hastings2f936352014-08-05 14:04:04 +100010038 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010039 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010040#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010041 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010042 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010043 result = -1;
10044 else {
10045 result = _chsize_s(fd, length);
10046 close(fd);
10047 if (result < 0)
10048 errno = result;
10049 }
10050#else
10051 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010052#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010053 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010054 Py_END_ALLOW_THREADS
10055 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010056 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010057
10058 Py_RETURN_NONE;
10059}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010060#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010061
Ross Lagerwall7807c352011-03-17 20:20:30 +020010062
Victor Stinnerd6b17692014-09-30 12:20:05 +020010063/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10064 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10065 defined, which is the case in Python on AIX. AIX bug report:
10066 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10067#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10068# define POSIX_FADVISE_AIX_BUG
10069#endif
10070
Victor Stinnerec39e262014-09-30 12:35:58 +020010071
Victor Stinnerd6b17692014-09-30 12:20:05 +020010072#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010073/*[clinic input]
10074os.posix_fallocate
10075
10076 fd: int
10077 offset: Py_off_t
10078 length: Py_off_t
10079 /
10080
10081Ensure a file has allocated at least a particular number of bytes on disk.
10082
10083Ensure that the file specified by fd encompasses a range of bytes
10084starting at offset bytes from the beginning and continuing for length bytes.
10085[clinic start generated code]*/
10086
Larry Hastings2f936352014-08-05 14:04:04 +100010087static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010088os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010089 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010090/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010091{
10092 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010093 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010094
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010095 do {
10096 Py_BEGIN_ALLOW_THREADS
10097 result = posix_fallocate(fd, offset, length);
10098 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010099 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10100
10101 if (result == 0)
10102 Py_RETURN_NONE;
10103
10104 if (async_err)
10105 return NULL;
10106
10107 errno = result;
10108 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010109}
Victor Stinnerec39e262014-09-30 12:35:58 +020010110#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010111
Ross Lagerwall7807c352011-03-17 20:20:30 +020010112
Victor Stinnerd6b17692014-09-30 12:20:05 +020010113#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010114/*[clinic input]
10115os.posix_fadvise
10116
10117 fd: int
10118 offset: Py_off_t
10119 length: Py_off_t
10120 advice: int
10121 /
10122
10123Announce an intention to access data in a specific pattern.
10124
10125Announce an intention to access data in a specific pattern, thus allowing
10126the kernel to make optimizations.
10127The advice applies to the region of the file specified by fd starting at
10128offset and continuing for length bytes.
10129advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10130POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10131POSIX_FADV_DONTNEED.
10132[clinic start generated code]*/
10133
Larry Hastings2f936352014-08-05 14:04:04 +100010134static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010135os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010136 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010137/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010138{
10139 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010140 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010141
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010142 do {
10143 Py_BEGIN_ALLOW_THREADS
10144 result = posix_fadvise(fd, offset, length, advice);
10145 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010146 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10147
10148 if (result == 0)
10149 Py_RETURN_NONE;
10150
10151 if (async_err)
10152 return NULL;
10153
10154 errno = result;
10155 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010156}
Victor Stinnerec39e262014-09-30 12:35:58 +020010157#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010158
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010159
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010160#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010161static PyObject*
10162win32_putenv(PyObject *name, PyObject *value)
10163{
10164 /* Search from index 1 because on Windows starting '=' is allowed for
10165 defining hidden environment variables. */
10166 if (PyUnicode_GET_LENGTH(name) == 0 ||
10167 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10168 {
10169 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10170 return NULL;
10171 }
10172 PyObject *unicode;
10173 if (value != NULL) {
10174 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10175 }
10176 else {
10177 unicode = PyUnicode_FromFormat("%U=", name);
10178 }
10179 if (unicode == NULL) {
10180 return NULL;
10181 }
10182
10183 Py_ssize_t size;
10184 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10185 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10186 Py_DECREF(unicode);
10187
10188 if (env == NULL) {
10189 return NULL;
10190 }
10191 if (size > _MAX_ENV) {
10192 PyErr_Format(PyExc_ValueError,
10193 "the environment variable is longer than %u characters",
10194 _MAX_ENV);
10195 PyMem_Free(env);
10196 return NULL;
10197 }
10198
10199 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10200 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10201 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10202
10203 Prefer _wputenv() to be compatible with C libraries using CRT
10204 variables and CRT functions using these variables (ex: getenv()). */
10205 int err = _wputenv(env);
10206 PyMem_Free(env);
10207
10208 if (err) {
10209 posix_error();
10210 return NULL;
10211 }
10212
10213 Py_RETURN_NONE;
10214}
10215#endif
10216
10217
10218#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010219/*[clinic input]
10220os.putenv
10221
10222 name: unicode
10223 value: unicode
10224 /
10225
10226Change or add an environment variable.
10227[clinic start generated code]*/
10228
Larry Hastings2f936352014-08-05 14:04:04 +100010229static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010230os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10231/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010232{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010233 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10234 return NULL;
10235 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010236 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010237}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010238#else
Larry Hastings2f936352014-08-05 14:04:04 +100010239/*[clinic input]
10240os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010241
Larry Hastings2f936352014-08-05 14:04:04 +100010242 name: FSConverter
10243 value: FSConverter
10244 /
10245
10246Change or add an environment variable.
10247[clinic start generated code]*/
10248
Larry Hastings2f936352014-08-05 14:04:04 +100010249static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010250os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10251/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010252{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010253 const char *name_string = PyBytes_AS_STRING(name);
10254 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010255
Serhiy Storchaka77703942017-06-25 07:33:01 +030010256 if (strchr(name_string, '=') != NULL) {
10257 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10258 return NULL;
10259 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010260
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010261 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10262 return NULL;
10263 }
10264
Victor Stinnerb477d192020-01-22 22:48:16 +010010265 if (setenv(name_string, value_string, 1)) {
10266 return posix_error();
10267 }
Larry Hastings2f936352014-08-05 14:04:04 +100010268 Py_RETURN_NONE;
10269}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010270#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010271
10272
Victor Stinner161e7b32020-01-24 11:53:44 +010010273#ifdef MS_WINDOWS
10274/*[clinic input]
10275os.unsetenv
10276 name: unicode
10277 /
10278
10279Delete an environment variable.
10280[clinic start generated code]*/
10281
10282static PyObject *
10283os_unsetenv_impl(PyObject *module, PyObject *name)
10284/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10285{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010286 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10287 return NULL;
10288 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010289 return win32_putenv(name, NULL);
10290}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010291#else
Larry Hastings2f936352014-08-05 14:04:04 +100010292/*[clinic input]
10293os.unsetenv
10294 name: FSConverter
10295 /
10296
10297Delete an environment variable.
10298[clinic start generated code]*/
10299
Larry Hastings2f936352014-08-05 14:04:04 +100010300static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010301os_unsetenv_impl(PyObject *module, PyObject *name)
10302/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010303{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010304 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10305 return NULL;
10306 }
Victor Stinner984890f2011-11-24 13:53:38 +010010307#ifdef HAVE_BROKEN_UNSETENV
10308 unsetenv(PyBytes_AS_STRING(name));
10309#else
Victor Stinner161e7b32020-01-24 11:53:44 +010010310 int err = unsetenv(PyBytes_AS_STRING(name));
10311 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010010312 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010010313 }
Victor Stinner984890f2011-11-24 13:53:38 +010010314#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010315
Victor Stinner84ae1182010-05-06 22:05:07 +000010316 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010317}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010318#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000010319
Larry Hastings2f936352014-08-05 14:04:04 +100010320
10321/*[clinic input]
10322os.strerror
10323
10324 code: int
10325 /
10326
10327Translate an error code to a message string.
10328[clinic start generated code]*/
10329
Larry Hastings2f936352014-08-05 14:04:04 +100010330static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010331os_strerror_impl(PyObject *module, int code)
10332/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010333{
10334 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 if (message == NULL) {
10336 PyErr_SetString(PyExc_ValueError,
10337 "strerror() argument out of range");
10338 return NULL;
10339 }
Victor Stinner1b579672011-12-17 05:47:23 +010010340 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010341}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010342
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010343
Guido van Rossumc9641791998-08-04 15:26:23 +000010344#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010345#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010346/*[clinic input]
10347os.WCOREDUMP -> bool
10348
10349 status: int
10350 /
10351
10352Return True if the process returning status was dumped to a core file.
10353[clinic start generated code]*/
10354
Larry Hastings2f936352014-08-05 14:04:04 +100010355static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010356os_WCOREDUMP_impl(PyObject *module, int status)
10357/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010358{
10359 WAIT_TYPE wait_status;
10360 WAIT_STATUS_INT(wait_status) = status;
10361 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010362}
10363#endif /* WCOREDUMP */
10364
Larry Hastings2f936352014-08-05 14:04:04 +100010365
Fred Drake106c1a02002-04-23 15:58:02 +000010366#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010367/*[clinic input]
10368os.WIFCONTINUED -> bool
10369
10370 status: int
10371
10372Return True if a particular process was continued from a job control stop.
10373
10374Return True if the process returning status was continued from a
10375job control stop.
10376[clinic start generated code]*/
10377
Larry Hastings2f936352014-08-05 14:04:04 +100010378static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010379os_WIFCONTINUED_impl(PyObject *module, int status)
10380/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010381{
10382 WAIT_TYPE wait_status;
10383 WAIT_STATUS_INT(wait_status) = status;
10384 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010385}
10386#endif /* WIFCONTINUED */
10387
Larry Hastings2f936352014-08-05 14:04:04 +100010388
Guido van Rossumc9641791998-08-04 15:26:23 +000010389#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010390/*[clinic input]
10391os.WIFSTOPPED -> bool
10392
10393 status: int
10394
10395Return True if the process returning status was stopped.
10396[clinic start generated code]*/
10397
Larry Hastings2f936352014-08-05 14:04:04 +100010398static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010399os_WIFSTOPPED_impl(PyObject *module, int status)
10400/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010401{
10402 WAIT_TYPE wait_status;
10403 WAIT_STATUS_INT(wait_status) = status;
10404 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010405}
10406#endif /* WIFSTOPPED */
10407
Larry Hastings2f936352014-08-05 14:04:04 +100010408
Guido van Rossumc9641791998-08-04 15:26:23 +000010409#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010410/*[clinic input]
10411os.WIFSIGNALED -> bool
10412
10413 status: int
10414
10415Return True if the process returning status was terminated by a signal.
10416[clinic start generated code]*/
10417
Larry Hastings2f936352014-08-05 14:04:04 +100010418static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010419os_WIFSIGNALED_impl(PyObject *module, int status)
10420/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010421{
10422 WAIT_TYPE wait_status;
10423 WAIT_STATUS_INT(wait_status) = status;
10424 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010425}
10426#endif /* WIFSIGNALED */
10427
Larry Hastings2f936352014-08-05 14:04:04 +100010428
Guido van Rossumc9641791998-08-04 15:26:23 +000010429#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010430/*[clinic input]
10431os.WIFEXITED -> bool
10432
10433 status: int
10434
10435Return True if the process returning status exited via the exit() system call.
10436[clinic start generated code]*/
10437
Larry Hastings2f936352014-08-05 14:04:04 +100010438static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010439os_WIFEXITED_impl(PyObject *module, int status)
10440/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010441{
10442 WAIT_TYPE wait_status;
10443 WAIT_STATUS_INT(wait_status) = status;
10444 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010445}
10446#endif /* WIFEXITED */
10447
Larry Hastings2f936352014-08-05 14:04:04 +100010448
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010449#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010450/*[clinic input]
10451os.WEXITSTATUS -> int
10452
10453 status: int
10454
10455Return the process return code from status.
10456[clinic start generated code]*/
10457
Larry Hastings2f936352014-08-05 14:04:04 +100010458static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010459os_WEXITSTATUS_impl(PyObject *module, int status)
10460/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010461{
10462 WAIT_TYPE wait_status;
10463 WAIT_STATUS_INT(wait_status) = status;
10464 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010465}
10466#endif /* WEXITSTATUS */
10467
Larry Hastings2f936352014-08-05 14:04:04 +100010468
Guido van Rossumc9641791998-08-04 15:26:23 +000010469#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010470/*[clinic input]
10471os.WTERMSIG -> int
10472
10473 status: int
10474
10475Return the signal that terminated the process that provided the status value.
10476[clinic start generated code]*/
10477
Larry Hastings2f936352014-08-05 14:04:04 +100010478static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010479os_WTERMSIG_impl(PyObject *module, int status)
10480/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010481{
10482 WAIT_TYPE wait_status;
10483 WAIT_STATUS_INT(wait_status) = status;
10484 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010485}
10486#endif /* WTERMSIG */
10487
Larry Hastings2f936352014-08-05 14:04:04 +100010488
Guido van Rossumc9641791998-08-04 15:26:23 +000010489#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010490/*[clinic input]
10491os.WSTOPSIG -> int
10492
10493 status: int
10494
10495Return the signal that stopped the process that provided the status value.
10496[clinic start generated code]*/
10497
Larry Hastings2f936352014-08-05 14:04:04 +100010498static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010499os_WSTOPSIG_impl(PyObject *module, int status)
10500/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010501{
10502 WAIT_TYPE wait_status;
10503 WAIT_STATUS_INT(wait_status) = status;
10504 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010505}
10506#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010507#endif /* HAVE_SYS_WAIT_H */
10508
10509
Thomas Wouters477c8d52006-05-27 19:21:47 +000010510#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010511#ifdef _SCO_DS
10512/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10513 needed definitions in sys/statvfs.h */
10514#define _SVID3
10515#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010516#include <sys/statvfs.h>
10517
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010518static PyObject*
10519_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondob3966632019-11-05 07:16:14 -080010520 PyObject *StatVFSResultType = _posixstate_global->StatVFSResultType;
10521 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 if (v == NULL)
10523 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010524
10525#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10527 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10528 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10529 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10530 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10531 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10532 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10533 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10534 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10535 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010536#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10538 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10539 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010540 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010542 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010544 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010546 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010548 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010550 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10552 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010553#endif
Michael Felt502d5512018-01-05 13:01:58 +010010554/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10555 * (issue #32390). */
10556#if defined(_AIX) && defined(_ALL_SOURCE)
10557 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10558#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010559 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010560#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010561 if (PyErr_Occurred()) {
10562 Py_DECREF(v);
10563 return NULL;
10564 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010565
Victor Stinner8c62be82010-05-06 00:08:46 +000010566 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010567}
10568
Larry Hastings2f936352014-08-05 14:04:04 +100010569
10570/*[clinic input]
10571os.fstatvfs
10572 fd: int
10573 /
10574
10575Perform an fstatvfs system call on the given fd.
10576
10577Equivalent to statvfs(fd).
10578[clinic start generated code]*/
10579
Larry Hastings2f936352014-08-05 14:04:04 +100010580static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010581os_fstatvfs_impl(PyObject *module, int fd)
10582/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010583{
10584 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010585 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010587
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010588 do {
10589 Py_BEGIN_ALLOW_THREADS
10590 result = fstatvfs(fd, &st);
10591 Py_END_ALLOW_THREADS
10592 } while (result != 0 && errno == EINTR &&
10593 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010594 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010595 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010596
Victor Stinner8c62be82010-05-06 00:08:46 +000010597 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010598}
Larry Hastings2f936352014-08-05 14:04:04 +100010599#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010600
10601
Thomas Wouters477c8d52006-05-27 19:21:47 +000010602#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010603#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010604/*[clinic input]
10605os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010606
Larry Hastings2f936352014-08-05 14:04:04 +100010607 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10608
10609Perform a statvfs system call on the given path.
10610
10611path may always be specified as a string.
10612On some platforms, path may also be specified as an open file descriptor.
10613 If this functionality is unavailable, using it raises an exception.
10614[clinic start generated code]*/
10615
Larry Hastings2f936352014-08-05 14:04:04 +100010616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010617os_statvfs_impl(PyObject *module, path_t *path)
10618/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010619{
10620 int result;
10621 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010622
10623 Py_BEGIN_ALLOW_THREADS
10624#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010625 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010626#ifdef __APPLE__
10627 /* handle weak-linking on Mac OS X 10.3 */
10628 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010629 fd_specified("statvfs", path->fd);
10630 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010631 }
10632#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010633 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010634 }
10635 else
10636#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010637 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010638 Py_END_ALLOW_THREADS
10639
10640 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010641 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010642 }
10643
Larry Hastings2f936352014-08-05 14:04:04 +100010644 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010645}
Larry Hastings2f936352014-08-05 14:04:04 +100010646#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10647
Guido van Rossum94f6f721999-01-06 18:42:14 +000010648
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010649#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010650/*[clinic input]
10651os._getdiskusage
10652
Steve Dower23ad6d02018-02-22 10:39:10 -080010653 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010654
10655Return disk usage statistics about the given path as a (total, free) tuple.
10656[clinic start generated code]*/
10657
Larry Hastings2f936352014-08-05 14:04:04 +100010658static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010659os__getdiskusage_impl(PyObject *module, path_t *path)
10660/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010661{
10662 BOOL retval;
10663 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010664 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010665
10666 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010667 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010668 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010669 if (retval == 0) {
10670 if (GetLastError() == ERROR_DIRECTORY) {
10671 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010672
Joe Pamerc8c02492018-09-25 10:57:36 -040010673 dir_path = PyMem_New(wchar_t, path->length + 1);
10674 if (dir_path == NULL) {
10675 return PyErr_NoMemory();
10676 }
10677
10678 wcscpy_s(dir_path, path->length + 1, path->wide);
10679
10680 if (_dirnameW(dir_path) != -1) {
10681 Py_BEGIN_ALLOW_THREADS
10682 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10683 Py_END_ALLOW_THREADS
10684 }
10685 /* Record the last error in case it's modified by PyMem_Free. */
10686 err = GetLastError();
10687 PyMem_Free(dir_path);
10688 if (retval) {
10689 goto success;
10690 }
10691 }
10692 return PyErr_SetFromWindowsErr(err);
10693 }
10694
10695success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010696 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10697}
Larry Hastings2f936352014-08-05 14:04:04 +100010698#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010699
10700
Fred Drakec9680921999-12-13 16:37:25 +000010701/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10702 * It maps strings representing configuration variable names to
10703 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010704 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010705 * rarely-used constants. There are three separate tables that use
10706 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010707 *
10708 * This code is always included, even if none of the interfaces that
10709 * need it are included. The #if hackery needed to avoid it would be
10710 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010711 */
10712struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010713 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010714 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010715};
10716
Fred Drake12c6e2d1999-12-14 21:25:03 +000010717static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010718conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010719 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010720{
Christian Heimes217cfd12007-12-02 14:31:20 +000010721 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010722 int value = _PyLong_AsInt(arg);
10723 if (value == -1 && PyErr_Occurred())
10724 return 0;
10725 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010726 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010727 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010728 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010729 /* look up the value in the table using a binary search */
10730 size_t lo = 0;
10731 size_t mid;
10732 size_t hi = tablesize;
10733 int cmp;
10734 const char *confname;
10735 if (!PyUnicode_Check(arg)) {
10736 PyErr_SetString(PyExc_TypeError,
10737 "configuration names must be strings or integers");
10738 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010740 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010741 if (confname == NULL)
10742 return 0;
10743 while (lo < hi) {
10744 mid = (lo + hi) / 2;
10745 cmp = strcmp(confname, table[mid].name);
10746 if (cmp < 0)
10747 hi = mid;
10748 else if (cmp > 0)
10749 lo = mid + 1;
10750 else {
10751 *valuep = table[mid].value;
10752 return 1;
10753 }
10754 }
10755 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10756 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010757 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010758}
10759
10760
10761#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10762static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010763#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010764 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010765#endif
10766#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010767 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010768#endif
Fred Drakec9680921999-12-13 16:37:25 +000010769#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010770 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010771#endif
10772#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010773 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010774#endif
10775#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010776 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010777#endif
10778#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010779 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010780#endif
10781#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010782 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010783#endif
10784#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010785 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010786#endif
10787#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010788 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010789#endif
10790#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010791 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010792#endif
10793#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010794 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010795#endif
10796#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010797 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010798#endif
10799#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010800 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010801#endif
10802#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010803 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010804#endif
10805#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010806 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010807#endif
10808#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010809 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010810#endif
10811#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010812 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010813#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010814#ifdef _PC_ACL_ENABLED
10815 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10816#endif
10817#ifdef _PC_MIN_HOLE_SIZE
10818 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10819#endif
10820#ifdef _PC_ALLOC_SIZE_MIN
10821 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10822#endif
10823#ifdef _PC_REC_INCR_XFER_SIZE
10824 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10825#endif
10826#ifdef _PC_REC_MAX_XFER_SIZE
10827 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10828#endif
10829#ifdef _PC_REC_MIN_XFER_SIZE
10830 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10831#endif
10832#ifdef _PC_REC_XFER_ALIGN
10833 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10834#endif
10835#ifdef _PC_SYMLINK_MAX
10836 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10837#endif
10838#ifdef _PC_XATTR_ENABLED
10839 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10840#endif
10841#ifdef _PC_XATTR_EXISTS
10842 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10843#endif
10844#ifdef _PC_TIMESTAMP_RESOLUTION
10845 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10846#endif
Fred Drakec9680921999-12-13 16:37:25 +000010847};
10848
Fred Drakec9680921999-12-13 16:37:25 +000010849static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010850conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010851{
10852 return conv_confname(arg, valuep, posix_constants_pathconf,
10853 sizeof(posix_constants_pathconf)
10854 / sizeof(struct constdef));
10855}
10856#endif
10857
Larry Hastings2f936352014-08-05 14:04:04 +100010858
Fred Drakec9680921999-12-13 16:37:25 +000010859#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010860/*[clinic input]
10861os.fpathconf -> long
10862
10863 fd: int
10864 name: path_confname
10865 /
10866
10867Return the configuration limit name for the file descriptor fd.
10868
10869If there is no limit, return -1.
10870[clinic start generated code]*/
10871
Larry Hastings2f936352014-08-05 14:04:04 +100010872static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010873os_fpathconf_impl(PyObject *module, int fd, int name)
10874/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010875{
10876 long limit;
10877
10878 errno = 0;
10879 limit = fpathconf(fd, name);
10880 if (limit == -1 && errno != 0)
10881 posix_error();
10882
10883 return limit;
10884}
10885#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010886
10887
10888#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010889/*[clinic input]
10890os.pathconf -> long
10891 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10892 name: path_confname
10893
10894Return the configuration limit name for the file or directory path.
10895
10896If there is no limit, return -1.
10897On some platforms, path may also be specified as an open file descriptor.
10898 If this functionality is unavailable, using it raises an exception.
10899[clinic start generated code]*/
10900
Larry Hastings2f936352014-08-05 14:04:04 +100010901static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010902os_pathconf_impl(PyObject *module, path_t *path, int name)
10903/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010904{
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010906
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010908#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010909 if (path->fd != -1)
10910 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010911 else
10912#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010913 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010914 if (limit == -1 && errno != 0) {
10915 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010916 /* could be a path or name problem */
10917 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010918 else
Larry Hastings2f936352014-08-05 14:04:04 +100010919 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010920 }
Larry Hastings2f936352014-08-05 14:04:04 +100010921
10922 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010923}
Larry Hastings2f936352014-08-05 14:04:04 +100010924#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010925
10926#ifdef HAVE_CONFSTR
10927static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010928#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010929 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010930#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010931#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010932 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010933#endif
10934#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010936#endif
Fred Draked86ed291999-12-15 15:34:33 +000010937#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010939#endif
10940#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010942#endif
10943#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010945#endif
10946#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010947 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010948#endif
Fred Drakec9680921999-12-13 16:37:25 +000010949#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010950 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010951#endif
10952#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010953 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010954#endif
10955#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010957#endif
10958#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010960#endif
10961#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010962 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010963#endif
10964#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010965 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010966#endif
10967#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010968 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010969#endif
10970#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010972#endif
Fred Draked86ed291999-12-15 15:34:33 +000010973#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010975#endif
Fred Drakec9680921999-12-13 16:37:25 +000010976#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010977 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010978#endif
Fred Draked86ed291999-12-15 15:34:33 +000010979#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010981#endif
10982#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010984#endif
10985#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010986 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010987#endif
10988#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010989 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010990#endif
Fred Drakec9680921999-12-13 16:37:25 +000010991#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010992 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010993#endif
10994#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010996#endif
10997#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010998 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010999#endif
11000#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011001 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011002#endif
11003#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011005#endif
11006#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011007 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011008#endif
11009#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011011#endif
11012#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011013 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011014#endif
11015#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011016 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011017#endif
11018#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011019 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011020#endif
11021#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011023#endif
11024#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011025 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011026#endif
11027#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011028 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011029#endif
11030#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011031 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011032#endif
11033#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011034 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011035#endif
11036#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011037 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011038#endif
Fred Draked86ed291999-12-15 15:34:33 +000011039#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011040 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011041#endif
11042#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011043 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011044#endif
11045#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011046 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011047#endif
11048#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011049 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011050#endif
11051#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011052 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011053#endif
11054#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011055 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011056#endif
11057#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011058 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011059#endif
11060#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011061 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011062#endif
11063#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011065#endif
11066#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011068#endif
11069#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011070 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011071#endif
11072#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011073 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011074#endif
11075#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011076 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011077#endif
Fred Drakec9680921999-12-13 16:37:25 +000011078};
11079
11080static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011081conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011082{
11083 return conv_confname(arg, valuep, posix_constants_confstr,
11084 sizeof(posix_constants_confstr)
11085 / sizeof(struct constdef));
11086}
11087
Larry Hastings2f936352014-08-05 14:04:04 +100011088
11089/*[clinic input]
11090os.confstr
11091
11092 name: confstr_confname
11093 /
11094
11095Return a string-valued system configuration variable.
11096[clinic start generated code]*/
11097
Larry Hastings2f936352014-08-05 14:04:04 +100011098static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011099os_confstr_impl(PyObject *module, int name)
11100/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011101{
11102 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011103 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011104 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011105
Victor Stinnercb043522010-09-10 23:49:04 +000011106 errno = 0;
11107 len = confstr(name, buffer, sizeof(buffer));
11108 if (len == 0) {
11109 if (errno) {
11110 posix_error();
11111 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011112 }
11113 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011114 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011115 }
11116 }
Victor Stinnercb043522010-09-10 23:49:04 +000011117
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011118 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011119 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011120 char *buf = PyMem_Malloc(len);
11121 if (buf == NULL)
11122 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011123 len2 = confstr(name, buf, len);
11124 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011125 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011126 PyMem_Free(buf);
11127 }
11128 else
11129 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011130 return result;
11131}
Larry Hastings2f936352014-08-05 14:04:04 +100011132#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011133
11134
11135#ifdef HAVE_SYSCONF
11136static struct constdef posix_constants_sysconf[] = {
11137#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011138 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011139#endif
11140#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011141 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011142#endif
11143#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011144 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011145#endif
11146#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011147 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011148#endif
11149#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011150 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011151#endif
11152#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011153 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011154#endif
11155#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011156 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011157#endif
11158#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011159 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011160#endif
11161#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011162 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011163#endif
11164#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011165 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011166#endif
Fred Draked86ed291999-12-15 15:34:33 +000011167#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011168 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011169#endif
11170#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011171 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011172#endif
Fred Drakec9680921999-12-13 16:37:25 +000011173#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011174 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011175#endif
Fred Drakec9680921999-12-13 16:37:25 +000011176#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011177 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011178#endif
11179#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011180 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011181#endif
11182#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011183 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011184#endif
11185#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011186 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011187#endif
11188#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011189 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011190#endif
Fred Draked86ed291999-12-15 15:34:33 +000011191#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011192 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011193#endif
Fred Drakec9680921999-12-13 16:37:25 +000011194#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011195 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011196#endif
11197#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011198 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011199#endif
11200#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011201 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011202#endif
11203#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011204 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011205#endif
11206#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011207 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011208#endif
Fred Draked86ed291999-12-15 15:34:33 +000011209#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011210 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011211#endif
Fred Drakec9680921999-12-13 16:37:25 +000011212#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011213 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011214#endif
11215#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011216 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011217#endif
11218#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011219 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011220#endif
11221#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011222 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011223#endif
11224#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011225 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011226#endif
11227#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011228 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011229#endif
11230#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011231 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011232#endif
11233#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011234 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011235#endif
11236#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011237 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011238#endif
11239#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011240 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011241#endif
11242#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011243 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011244#endif
11245#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011246 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011247#endif
11248#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011249 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011250#endif
11251#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011252 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011253#endif
11254#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011255 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011256#endif
11257#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011258 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011259#endif
11260#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011261 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011262#endif
11263#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011264 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011265#endif
11266#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011267 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011268#endif
11269#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011270 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011271#endif
11272#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011273 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011274#endif
11275#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011276 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011277#endif
11278#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011279 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011280#endif
Fred Draked86ed291999-12-15 15:34:33 +000011281#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011282 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011283#endif
Fred Drakec9680921999-12-13 16:37:25 +000011284#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011285 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011286#endif
11287#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011288 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011289#endif
11290#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011291 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011292#endif
Fred Draked86ed291999-12-15 15:34:33 +000011293#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011294 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011295#endif
Fred Drakec9680921999-12-13 16:37:25 +000011296#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011297 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011298#endif
Fred Draked86ed291999-12-15 15:34:33 +000011299#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011300 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011301#endif
11302#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011303 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011304#endif
Fred Drakec9680921999-12-13 16:37:25 +000011305#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011306 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011307#endif
11308#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011309 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011310#endif
11311#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011313#endif
11314#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011315 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011316#endif
Fred Draked86ed291999-12-15 15:34:33 +000011317#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011318 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011319#endif
Fred Drakec9680921999-12-13 16:37:25 +000011320#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011321 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011322#endif
11323#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011324 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011325#endif
11326#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011327 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011328#endif
11329#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011330 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011331#endif
11332#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011334#endif
11335#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011336 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011337#endif
11338#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011339 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011340#endif
Fred Draked86ed291999-12-15 15:34:33 +000011341#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011342 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011343#endif
Fred Drakec9680921999-12-13 16:37:25 +000011344#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011345 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011346#endif
11347#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011348 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011349#endif
Fred Draked86ed291999-12-15 15:34:33 +000011350#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011351 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011352#endif
Fred Drakec9680921999-12-13 16:37:25 +000011353#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011354 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011355#endif
11356#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011357 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011358#endif
11359#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011361#endif
11362#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011363 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011364#endif
11365#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011366 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011367#endif
11368#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011369 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011370#endif
11371#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011373#endif
11374#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011376#endif
11377#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011379#endif
Fred Draked86ed291999-12-15 15:34:33 +000011380#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011382#endif
11383#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011384 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011385#endif
Fred Drakec9680921999-12-13 16:37:25 +000011386#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011388#endif
11389#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011391#endif
11392#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011394#endif
11395#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011397#endif
11398#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011399 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011400#endif
11401#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011402 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011403#endif
11404#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011406#endif
11407#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011408 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011409#endif
11410#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011412#endif
11413#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011415#endif
11416#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011417 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011418#endif
11419#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011420 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011421#endif
11422#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011424#endif
11425#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011427#endif
11428#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011429 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011430#endif
11431#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011432 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011433#endif
11434#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011435 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011436#endif
11437#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011438 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011439#endif
11440#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011442#endif
11443#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011445#endif
11446#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011447 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011448#endif
11449#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011450 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011451#endif
11452#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011453 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011454#endif
11455#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011456 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011457#endif
11458#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011459 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011460#endif
11461#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011462 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011463#endif
11464#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011466#endif
11467#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011468 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011469#endif
11470#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011472#endif
11473#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011474 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011475#endif
11476#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011477 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011478#endif
11479#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011480 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011481#endif
11482#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011484#endif
11485#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011486 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011487#endif
11488#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011489 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011490#endif
Fred Draked86ed291999-12-15 15:34:33 +000011491#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011492 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011493#endif
Fred Drakec9680921999-12-13 16:37:25 +000011494#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011495 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011496#endif
11497#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011498 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011499#endif
11500#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011501 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011502#endif
11503#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011504 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011505#endif
11506#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011507 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011508#endif
11509#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011510 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011511#endif
11512#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011513 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011514#endif
11515#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011516 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011517#endif
11518#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011519 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011520#endif
11521#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011522 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011523#endif
11524#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011525 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011526#endif
11527#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011529#endif
11530#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011531 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011532#endif
11533#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011535#endif
11536#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011537 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011538#endif
11539#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011540 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011541#endif
11542#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011544#endif
11545#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011547#endif
11548#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011549 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011550#endif
11551#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011553#endif
11554#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011556#endif
11557#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011559#endif
11560#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011561 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011562#endif
11563#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011564 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011565#endif
11566#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011567 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011568#endif
11569#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011570 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011571#endif
11572#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011573 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011574#endif
11575#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011576 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011577#endif
11578#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011579 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011580#endif
11581#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011582 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011583#endif
11584#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011585 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011586#endif
11587#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011588 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011589#endif
11590#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011591 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011592#endif
11593#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011594 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011595#endif
11596#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011597 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011598#endif
11599#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011600 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011601#endif
11602#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011603 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011604#endif
11605#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011606 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011607#endif
11608#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011609 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011610#endif
11611#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011612 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011613#endif
11614#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011615 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011616#endif
11617#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011618 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011619#endif
11620#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011621 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011622#endif
11623#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011624 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011625#endif
11626#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011627 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011628#endif
11629};
11630
11631static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011632conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011633{
11634 return conv_confname(arg, valuep, posix_constants_sysconf,
11635 sizeof(posix_constants_sysconf)
11636 / sizeof(struct constdef));
11637}
11638
Larry Hastings2f936352014-08-05 14:04:04 +100011639
11640/*[clinic input]
11641os.sysconf -> long
11642 name: sysconf_confname
11643 /
11644
11645Return an integer-valued system configuration variable.
11646[clinic start generated code]*/
11647
Larry Hastings2f936352014-08-05 14:04:04 +100011648static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011649os_sysconf_impl(PyObject *module, int name)
11650/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011651{
11652 long value;
11653
11654 errno = 0;
11655 value = sysconf(name);
11656 if (value == -1 && errno != 0)
11657 posix_error();
11658 return value;
11659}
11660#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011661
11662
Fred Drakebec628d1999-12-15 18:31:10 +000011663/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011664 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011665 * the exported dictionaries that are used to publish information about the
11666 * names available on the host platform.
11667 *
11668 * Sorting the table at runtime ensures that the table is properly ordered
11669 * when used, even for platforms we're not able to test on. It also makes
11670 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011671 */
Fred Drakebec628d1999-12-15 18:31:10 +000011672
11673static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011674cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011675{
11676 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011677 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011678 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011679 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011680
11681 return strcmp(c1->name, c2->name);
11682}
11683
11684static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011685setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011686 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011687{
Fred Drakebec628d1999-12-15 18:31:10 +000011688 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011689 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011690
11691 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11692 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011693 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011694 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011695
Barry Warsaw3155db32000-04-13 15:20:40 +000011696 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011697 PyObject *o = PyLong_FromLong(table[i].value);
11698 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11699 Py_XDECREF(o);
11700 Py_DECREF(d);
11701 return -1;
11702 }
11703 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011704 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011705 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011706}
11707
Fred Drakebec628d1999-12-15 18:31:10 +000011708/* Return -1 on failure, 0 on success. */
11709static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011710setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011711{
11712#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011713 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011714 sizeof(posix_constants_pathconf)
11715 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011716 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011717 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011718#endif
11719#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011720 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011721 sizeof(posix_constants_confstr)
11722 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011723 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011724 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011725#endif
11726#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011727 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011728 sizeof(posix_constants_sysconf)
11729 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011730 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011731 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011732#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011733 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011734}
Fred Draked86ed291999-12-15 15:34:33 +000011735
11736
Larry Hastings2f936352014-08-05 14:04:04 +100011737/*[clinic input]
11738os.abort
11739
11740Abort the interpreter immediately.
11741
11742This function 'dumps core' or otherwise fails in the hardest way possible
11743on the hosting operating system. This function never returns.
11744[clinic start generated code]*/
11745
Larry Hastings2f936352014-08-05 14:04:04 +100011746static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011747os_abort_impl(PyObject *module)
11748/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011749{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011750 abort();
11751 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011752#ifndef __clang__
11753 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11754 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11755 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011756 Py_FatalError("abort() called from Python code didn't abort!");
11757 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011758#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011759}
Fred Drakebec628d1999-12-15 18:31:10 +000011760
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011761#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011762/* Grab ShellExecute dynamically from shell32 */
11763static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011764static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11765 LPCWSTR, INT);
11766static int
11767check_ShellExecute()
11768{
11769 HINSTANCE hShell32;
11770
11771 /* only recheck */
11772 if (-1 == has_ShellExecute) {
11773 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011774 /* Security note: this call is not vulnerable to "DLL hijacking".
11775 SHELL32 is part of "KnownDLLs" and so Windows always load
11776 the system SHELL32.DLL, even if there is another SHELL32.DLL
11777 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011778 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011779 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011780 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11781 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011782 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011783 } else {
11784 has_ShellExecute = 0;
11785 }
Tony Roberts4860f012019-02-02 18:16:42 +010011786 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011787 }
11788 return has_ShellExecute;
11789}
11790
11791
Steve Dowercc16be82016-09-08 10:35:16 -070011792/*[clinic input]
11793os.startfile
11794 filepath: path_t
11795 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011796
Steve Dowercc16be82016-09-08 10:35:16 -070011797Start a file with its associated application.
11798
11799When "operation" is not specified or "open", this acts like
11800double-clicking the file in Explorer, or giving the file name as an
11801argument to the DOS "start" command: the file is opened with whatever
11802application (if any) its extension is associated.
11803When another "operation" is given, it specifies what should be done with
11804the file. A typical operation is "print".
11805
11806startfile returns as soon as the associated application is launched.
11807There is no option to wait for the application to close, and no way
11808to retrieve the application's exit status.
11809
11810The filepath is relative to the current directory. If you want to use
11811an absolute path, make sure the first character is not a slash ("/");
11812the underlying Win32 ShellExecute function doesn't work if it is.
11813[clinic start generated code]*/
11814
11815static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011816os_startfile_impl(PyObject *module, path_t *filepath,
11817 const Py_UNICODE *operation)
Serhiy Storchaka279f4462019-09-14 12:24:05 +030011818/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011819{
11820 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011821
11822 if(!check_ShellExecute()) {
11823 /* If the OS doesn't have ShellExecute, return a
11824 NotImplementedError. */
11825 return PyErr_Format(PyExc_NotImplementedError,
11826 "startfile not available on this platform");
11827 }
11828
Saiyang Gou7514f4f2020-02-12 23:47:42 -080011829 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080011830 return NULL;
11831 }
11832
Victor Stinner8c62be82010-05-06 00:08:46 +000011833 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011834 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011835 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011836 Py_END_ALLOW_THREADS
11837
Victor Stinner8c62be82010-05-06 00:08:46 +000011838 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011839 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011840 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011841 }
Steve Dowercc16be82016-09-08 10:35:16 -070011842 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011843}
Larry Hastings2f936352014-08-05 14:04:04 +100011844#endif /* MS_WINDOWS */
11845
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011846
Martin v. Löwis438b5342002-12-27 10:16:42 +000011847#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011848/*[clinic input]
11849os.getloadavg
11850
11851Return average recent system load information.
11852
11853Return the number of processes in the system run queue averaged over
11854the last 1, 5, and 15 minutes as a tuple of three floats.
11855Raises OSError if the load average was unobtainable.
11856[clinic start generated code]*/
11857
Larry Hastings2f936352014-08-05 14:04:04 +100011858static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011859os_getloadavg_impl(PyObject *module)
11860/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011861{
11862 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011863 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011864 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11865 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011866 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011867 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011868}
Larry Hastings2f936352014-08-05 14:04:04 +100011869#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011870
Larry Hastings2f936352014-08-05 14:04:04 +100011871
11872/*[clinic input]
11873os.device_encoding
11874 fd: int
11875
11876Return a string describing the encoding of a terminal's file descriptor.
11877
11878The file descriptor must be attached to a terminal.
11879If the device is not a terminal, return None.
11880[clinic start generated code]*/
11881
Larry Hastings2f936352014-08-05 14:04:04 +100011882static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011883os_device_encoding_impl(PyObject *module, int fd)
11884/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011885{
Brett Cannonefb00c02012-02-29 18:31:31 -050011886 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011887}
11888
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011889
Larry Hastings2f936352014-08-05 14:04:04 +100011890#ifdef HAVE_SETRESUID
11891/*[clinic input]
11892os.setresuid
11893
11894 ruid: uid_t
11895 euid: uid_t
11896 suid: uid_t
11897 /
11898
11899Set the current process's real, effective, and saved user ids.
11900[clinic start generated code]*/
11901
Larry Hastings2f936352014-08-05 14:04:04 +100011902static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011903os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11904/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011905{
Victor Stinner8c62be82010-05-06 00:08:46 +000011906 if (setresuid(ruid, euid, suid) < 0)
11907 return posix_error();
11908 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011909}
Larry Hastings2f936352014-08-05 14:04:04 +100011910#endif /* HAVE_SETRESUID */
11911
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011912
11913#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011914/*[clinic input]
11915os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011916
Larry Hastings2f936352014-08-05 14:04:04 +100011917 rgid: gid_t
11918 egid: gid_t
11919 sgid: gid_t
11920 /
11921
11922Set the current process's real, effective, and saved group ids.
11923[clinic start generated code]*/
11924
Larry Hastings2f936352014-08-05 14:04:04 +100011925static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011926os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11927/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011928{
Victor Stinner8c62be82010-05-06 00:08:46 +000011929 if (setresgid(rgid, egid, sgid) < 0)
11930 return posix_error();
11931 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011932}
Larry Hastings2f936352014-08-05 14:04:04 +100011933#endif /* HAVE_SETRESGID */
11934
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011935
11936#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011937/*[clinic input]
11938os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011939
Larry Hastings2f936352014-08-05 14:04:04 +100011940Return a tuple of the current process's real, effective, and saved user ids.
11941[clinic start generated code]*/
11942
Larry Hastings2f936352014-08-05 14:04:04 +100011943static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011944os_getresuid_impl(PyObject *module)
11945/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011946{
Victor Stinner8c62be82010-05-06 00:08:46 +000011947 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011948 if (getresuid(&ruid, &euid, &suid) < 0)
11949 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011950 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11951 _PyLong_FromUid(euid),
11952 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011953}
Larry Hastings2f936352014-08-05 14:04:04 +100011954#endif /* HAVE_GETRESUID */
11955
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011956
11957#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011958/*[clinic input]
11959os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011960
Larry Hastings2f936352014-08-05 14:04:04 +100011961Return a tuple of the current process's real, effective, and saved group ids.
11962[clinic start generated code]*/
11963
Larry Hastings2f936352014-08-05 14:04:04 +100011964static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011965os_getresgid_impl(PyObject *module)
11966/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011967{
11968 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011969 if (getresgid(&rgid, &egid, &sgid) < 0)
11970 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011971 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11972 _PyLong_FromGid(egid),
11973 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011974}
Larry Hastings2f936352014-08-05 14:04:04 +100011975#endif /* HAVE_GETRESGID */
11976
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011977
Benjamin Peterson9428d532011-09-14 11:45:52 -040011978#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011979/*[clinic input]
11980os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011981
Larry Hastings2f936352014-08-05 14:04:04 +100011982 path: path_t(allow_fd=True)
11983 attribute: path_t
11984 *
11985 follow_symlinks: bool = True
11986
11987Return the value of extended attribute attribute on path.
11988
BNMetricsb9427072018-11-02 15:20:19 +000011989path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011990If follow_symlinks is False, and the last element of the path is a symbolic
11991 link, getxattr will examine the symbolic link itself instead of the file
11992 the link points to.
11993
11994[clinic start generated code]*/
11995
Larry Hastings2f936352014-08-05 14:04:04 +100011996static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011997os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011998 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011999/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012000{
12001 Py_ssize_t i;
12002 PyObject *buffer = NULL;
12003
12004 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12005 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012006
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012007 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12008 return NULL;
12009 }
12010
Larry Hastings9cf065c2012-06-22 16:30:09 -070012011 for (i = 0; ; i++) {
12012 void *ptr;
12013 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012014 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012015 Py_ssize_t buffer_size = buffer_sizes[i];
12016 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012017 path_error(path);
12018 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012019 }
12020 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12021 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012022 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012023 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012024
Larry Hastings9cf065c2012-06-22 16:30:09 -070012025 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012026 if (path->fd >= 0)
12027 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012028 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012029 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012030 else
Larry Hastings2f936352014-08-05 14:04:04 +100012031 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012032 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012033
Larry Hastings9cf065c2012-06-22 16:30:09 -070012034 if (result < 0) {
12035 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012036 if (errno == ERANGE)
12037 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012038 path_error(path);
12039 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012040 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012041
Larry Hastings9cf065c2012-06-22 16:30:09 -070012042 if (result != buffer_size) {
12043 /* Can only shrink. */
12044 _PyBytes_Resize(&buffer, result);
12045 }
12046 break;
12047 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012048
Larry Hastings9cf065c2012-06-22 16:30:09 -070012049 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012050}
12051
Larry Hastings2f936352014-08-05 14:04:04 +100012052
12053/*[clinic input]
12054os.setxattr
12055
12056 path: path_t(allow_fd=True)
12057 attribute: path_t
12058 value: Py_buffer
12059 flags: int = 0
12060 *
12061 follow_symlinks: bool = True
12062
12063Set extended attribute attribute on path to value.
12064
BNMetricsb9427072018-11-02 15:20:19 +000012065path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012066If follow_symlinks is False, and the last element of the path is a symbolic
12067 link, setxattr will modify the symbolic link itself instead of the file
12068 the link points to.
12069
12070[clinic start generated code]*/
12071
Benjamin Peterson799bd802011-08-31 22:15:17 -040012072static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012073os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012074 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012075/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012076{
Larry Hastings2f936352014-08-05 14:04:04 +100012077 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012078
Larry Hastings2f936352014-08-05 14:04:04 +100012079 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012080 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012081
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012082 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12083 value->buf, value->len, flags) < 0) {
12084 return NULL;
12085 }
12086
Benjamin Peterson799bd802011-08-31 22:15:17 -040012087 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012088 if (path->fd > -1)
12089 result = fsetxattr(path->fd, attribute->narrow,
12090 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012091 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012092 result = setxattr(path->narrow, attribute->narrow,
12093 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012094 else
Larry Hastings2f936352014-08-05 14:04:04 +100012095 result = lsetxattr(path->narrow, attribute->narrow,
12096 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012097 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012098
Larry Hastings9cf065c2012-06-22 16:30:09 -070012099 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012100 path_error(path);
12101 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012102 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012103
Larry Hastings2f936352014-08-05 14:04:04 +100012104 Py_RETURN_NONE;
12105}
12106
12107
12108/*[clinic input]
12109os.removexattr
12110
12111 path: path_t(allow_fd=True)
12112 attribute: path_t
12113 *
12114 follow_symlinks: bool = True
12115
12116Remove extended attribute attribute on path.
12117
BNMetricsb9427072018-11-02 15:20:19 +000012118path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012119If follow_symlinks is False, and the last element of the path is a symbolic
12120 link, removexattr will modify the symbolic link itself instead of the file
12121 the link points to.
12122
12123[clinic start generated code]*/
12124
Larry Hastings2f936352014-08-05 14:04:04 +100012125static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012126os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012127 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012128/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012129{
12130 ssize_t result;
12131
12132 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12133 return NULL;
12134
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012135 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12136 return NULL;
12137 }
12138
Larry Hastings2f936352014-08-05 14:04:04 +100012139 Py_BEGIN_ALLOW_THREADS;
12140 if (path->fd > -1)
12141 result = fremovexattr(path->fd, attribute->narrow);
12142 else if (follow_symlinks)
12143 result = removexattr(path->narrow, attribute->narrow);
12144 else
12145 result = lremovexattr(path->narrow, attribute->narrow);
12146 Py_END_ALLOW_THREADS;
12147
12148 if (result) {
12149 return path_error(path);
12150 }
12151
12152 Py_RETURN_NONE;
12153}
12154
12155
12156/*[clinic input]
12157os.listxattr
12158
12159 path: path_t(allow_fd=True, nullable=True) = None
12160 *
12161 follow_symlinks: bool = True
12162
12163Return a list of extended attributes on path.
12164
BNMetricsb9427072018-11-02 15:20:19 +000012165path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012166if path is None, listxattr will examine the current directory.
12167If follow_symlinks is False, and the last element of the path is a symbolic
12168 link, listxattr will examine the symbolic link itself instead of the file
12169 the link points to.
12170[clinic start generated code]*/
12171
Larry Hastings2f936352014-08-05 14:04:04 +100012172static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012173os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012174/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012175{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012176 Py_ssize_t i;
12177 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012178 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012179 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012180
Larry Hastings2f936352014-08-05 14:04:04 +100012181 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012182 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012183
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012184 if (PySys_Audit("os.listxattr", "(O)",
12185 path->object ? path->object : Py_None) < 0) {
12186 return NULL;
12187 }
12188
Larry Hastings2f936352014-08-05 14:04:04 +100012189 name = path->narrow ? path->narrow : ".";
12190
Larry Hastings9cf065c2012-06-22 16:30:09 -070012191 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012192 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012193 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012194 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012195 Py_ssize_t buffer_size = buffer_sizes[i];
12196 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012197 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012198 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012199 break;
12200 }
12201 buffer = PyMem_MALLOC(buffer_size);
12202 if (!buffer) {
12203 PyErr_NoMemory();
12204 break;
12205 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012206
Larry Hastings9cf065c2012-06-22 16:30:09 -070012207 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012208 if (path->fd > -1)
12209 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012210 else if (follow_symlinks)
12211 length = listxattr(name, buffer, buffer_size);
12212 else
12213 length = llistxattr(name, buffer, buffer_size);
12214 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012215
Larry Hastings9cf065c2012-06-22 16:30:09 -070012216 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012217 if (errno == ERANGE) {
12218 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012219 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012220 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012221 }
Larry Hastings2f936352014-08-05 14:04:04 +100012222 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012223 break;
12224 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012225
Larry Hastings9cf065c2012-06-22 16:30:09 -070012226 result = PyList_New(0);
12227 if (!result) {
12228 goto exit;
12229 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012230
Larry Hastings9cf065c2012-06-22 16:30:09 -070012231 end = buffer + length;
12232 for (trace = start = buffer; trace != end; trace++) {
12233 if (!*trace) {
12234 int error;
12235 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12236 trace - start);
12237 if (!attribute) {
12238 Py_DECREF(result);
12239 result = NULL;
12240 goto exit;
12241 }
12242 error = PyList_Append(result, attribute);
12243 Py_DECREF(attribute);
12244 if (error) {
12245 Py_DECREF(result);
12246 result = NULL;
12247 goto exit;
12248 }
12249 start = trace + 1;
12250 }
12251 }
12252 break;
12253 }
12254exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012255 if (buffer)
12256 PyMem_FREE(buffer);
12257 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012258}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012259#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012260
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012261
Larry Hastings2f936352014-08-05 14:04:04 +100012262/*[clinic input]
12263os.urandom
12264
12265 size: Py_ssize_t
12266 /
12267
12268Return a bytes object containing random bytes suitable for cryptographic use.
12269[clinic start generated code]*/
12270
Larry Hastings2f936352014-08-05 14:04:04 +100012271static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012272os_urandom_impl(PyObject *module, Py_ssize_t size)
12273/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012274{
12275 PyObject *bytes;
12276 int result;
12277
Georg Brandl2fb477c2012-02-21 00:33:36 +010012278 if (size < 0)
12279 return PyErr_Format(PyExc_ValueError,
12280 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012281 bytes = PyBytes_FromStringAndSize(NULL, size);
12282 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012283 return NULL;
12284
Victor Stinnere66987e2016-09-06 16:33:52 -070012285 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012286 if (result == -1) {
12287 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012288 return NULL;
12289 }
Larry Hastings2f936352014-08-05 14:04:04 +100012290 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012291}
12292
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012293#ifdef HAVE_MEMFD_CREATE
12294/*[clinic input]
12295os.memfd_create
12296
12297 name: FSConverter
12298 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12299
12300[clinic start generated code]*/
12301
12302static PyObject *
12303os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12304/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12305{
12306 int fd;
12307 const char *bytes = PyBytes_AS_STRING(name);
12308 Py_BEGIN_ALLOW_THREADS
12309 fd = memfd_create(bytes, flags);
12310 Py_END_ALLOW_THREADS
12311 if (fd == -1) {
12312 return PyErr_SetFromErrno(PyExc_OSError);
12313 }
12314 return PyLong_FromLong(fd);
12315}
12316#endif
12317
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012318/* Terminal size querying */
12319
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012320PyDoc_STRVAR(TerminalSize_docstring,
12321 "A tuple of (columns, lines) for holding terminal window size");
12322
12323static PyStructSequence_Field TerminalSize_fields[] = {
12324 {"columns", "width of the terminal window in characters"},
12325 {"lines", "height of the terminal window in characters"},
12326 {NULL, NULL}
12327};
12328
12329static PyStructSequence_Desc TerminalSize_desc = {
12330 "os.terminal_size",
12331 TerminalSize_docstring,
12332 TerminalSize_fields,
12333 2,
12334};
12335
12336#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100012337/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012338PyDoc_STRVAR(termsize__doc__,
12339 "Return the size of the terminal window as (columns, lines).\n" \
12340 "\n" \
12341 "The optional argument fd (default standard output) specifies\n" \
12342 "which file descriptor should be queried.\n" \
12343 "\n" \
12344 "If the file descriptor is not connected to a terminal, an OSError\n" \
12345 "is thrown.\n" \
12346 "\n" \
12347 "This function will only be defined if an implementation is\n" \
12348 "available for this system.\n" \
12349 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080012350 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012351 "normally be used, os.get_terminal_size is the low-level implementation.");
12352
12353static PyObject*
12354get_terminal_size(PyObject *self, PyObject *args)
12355{
12356 int columns, lines;
12357 PyObject *termsize;
12358
12359 int fd = fileno(stdout);
12360 /* Under some conditions stdout may not be connected and
12361 * fileno(stdout) may point to an invalid file descriptor. For example
12362 * GUI apps don't have valid standard streams by default.
12363 *
12364 * If this happens, and the optional fd argument is not present,
12365 * the ioctl below will fail returning EBADF. This is what we want.
12366 */
12367
12368 if (!PyArg_ParseTuple(args, "|i", &fd))
12369 return NULL;
12370
12371#ifdef TERMSIZE_USE_IOCTL
12372 {
12373 struct winsize w;
12374 if (ioctl(fd, TIOCGWINSZ, &w))
12375 return PyErr_SetFromErrno(PyExc_OSError);
12376 columns = w.ws_col;
12377 lines = w.ws_row;
12378 }
12379#endif /* TERMSIZE_USE_IOCTL */
12380
12381#ifdef TERMSIZE_USE_CONIO
12382 {
12383 DWORD nhandle;
12384 HANDLE handle;
12385 CONSOLE_SCREEN_BUFFER_INFO csbi;
12386 switch (fd) {
12387 case 0: nhandle = STD_INPUT_HANDLE;
12388 break;
12389 case 1: nhandle = STD_OUTPUT_HANDLE;
12390 break;
12391 case 2: nhandle = STD_ERROR_HANDLE;
12392 break;
12393 default:
12394 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12395 }
12396 handle = GetStdHandle(nhandle);
12397 if (handle == NULL)
12398 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12399 if (handle == INVALID_HANDLE_VALUE)
12400 return PyErr_SetFromWindowsErr(0);
12401
12402 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12403 return PyErr_SetFromWindowsErr(0);
12404
12405 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12406 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12407 }
12408#endif /* TERMSIZE_USE_CONIO */
12409
Eddie Elizondob3966632019-11-05 07:16:14 -080012410 PyObject *TerminalSizeType = _posixstate(self)->TerminalSizeType;
12411 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012412 if (termsize == NULL)
12413 return NULL;
12414 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12415 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12416 if (PyErr_Occurred()) {
12417 Py_DECREF(termsize);
12418 return NULL;
12419 }
12420 return termsize;
12421}
12422#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12423
Larry Hastings2f936352014-08-05 14:04:04 +100012424
12425/*[clinic input]
12426os.cpu_count
12427
Charles-François Natali80d62e62015-08-13 20:37:08 +010012428Return the number of CPUs in the system; return None if indeterminable.
12429
12430This number is not equivalent to the number of CPUs the current process can
12431use. The number of usable CPUs can be obtained with
12432``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012433[clinic start generated code]*/
12434
Larry Hastings2f936352014-08-05 14:04:04 +100012435static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012436os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012437/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012438{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012439 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012440#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010012441 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012442#elif defined(__hpux)
12443 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12444#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12445 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012446#elif defined(__DragonFly__) || \
12447 defined(__OpenBSD__) || \
12448 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012449 defined(__NetBSD__) || \
12450 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012451 int mib[2];
12452 size_t len = sizeof(ncpu);
12453 mib[0] = CTL_HW;
12454 mib[1] = HW_NCPU;
12455 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12456 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012457#endif
12458 if (ncpu >= 1)
12459 return PyLong_FromLong(ncpu);
12460 else
12461 Py_RETURN_NONE;
12462}
12463
Victor Stinnerdaf45552013-08-28 00:53:59 +020012464
Larry Hastings2f936352014-08-05 14:04:04 +100012465/*[clinic input]
12466os.get_inheritable -> bool
12467
12468 fd: int
12469 /
12470
12471Get the close-on-exe flag of the specified file descriptor.
12472[clinic start generated code]*/
12473
Larry Hastings2f936352014-08-05 14:04:04 +100012474static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012475os_get_inheritable_impl(PyObject *module, int fd)
12476/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012477{
Steve Dower8fc89802015-04-12 00:26:27 -040012478 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012479 _Py_BEGIN_SUPPRESS_IPH
12480 return_value = _Py_get_inheritable(fd);
12481 _Py_END_SUPPRESS_IPH
12482 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012483}
12484
12485
12486/*[clinic input]
12487os.set_inheritable
12488 fd: int
12489 inheritable: int
12490 /
12491
12492Set the inheritable flag of the specified file descriptor.
12493[clinic start generated code]*/
12494
Larry Hastings2f936352014-08-05 14:04:04 +100012495static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012496os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12497/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012498{
Steve Dower8fc89802015-04-12 00:26:27 -040012499 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012500
Steve Dower8fc89802015-04-12 00:26:27 -040012501 _Py_BEGIN_SUPPRESS_IPH
12502 result = _Py_set_inheritable(fd, inheritable, NULL);
12503 _Py_END_SUPPRESS_IPH
12504 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012505 return NULL;
12506 Py_RETURN_NONE;
12507}
12508
12509
12510#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012511/*[clinic input]
12512os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012513 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012514 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012515
Larry Hastings2f936352014-08-05 14:04:04 +100012516Get the close-on-exe flag of the specified file descriptor.
12517[clinic start generated code]*/
12518
Larry Hastings2f936352014-08-05 14:04:04 +100012519static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012520os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012521/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012522{
12523 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012524
12525 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12526 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012527 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012528 }
12529
Larry Hastings2f936352014-08-05 14:04:04 +100012530 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012531}
12532
Victor Stinnerdaf45552013-08-28 00:53:59 +020012533
Larry Hastings2f936352014-08-05 14:04:04 +100012534/*[clinic input]
12535os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012536 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012537 inheritable: bool
12538 /
12539
12540Set the inheritable flag of the specified handle.
12541[clinic start generated code]*/
12542
Larry Hastings2f936352014-08-05 14:04:04 +100012543static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012544os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012545 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012546/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012547{
12548 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012549 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12550 PyErr_SetFromWindowsErr(0);
12551 return NULL;
12552 }
12553 Py_RETURN_NONE;
12554}
Larry Hastings2f936352014-08-05 14:04:04 +100012555#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012556
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012557#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012558/*[clinic input]
12559os.get_blocking -> bool
12560 fd: int
12561 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012562
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012563Get the blocking mode of the file descriptor.
12564
12565Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12566[clinic start generated code]*/
12567
12568static int
12569os_get_blocking_impl(PyObject *module, int fd)
12570/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012571{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012572 int blocking;
12573
Steve Dower8fc89802015-04-12 00:26:27 -040012574 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012575 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012576 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012577 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012578}
12579
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012580/*[clinic input]
12581os.set_blocking
12582 fd: int
12583 blocking: bool(accept={int})
12584 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012585
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012586Set the blocking mode of the specified file descriptor.
12587
12588Set the O_NONBLOCK flag if blocking is False,
12589clear the O_NONBLOCK flag otherwise.
12590[clinic start generated code]*/
12591
12592static PyObject *
12593os_set_blocking_impl(PyObject *module, int fd, int blocking)
12594/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012595{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012596 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012597
Steve Dower8fc89802015-04-12 00:26:27 -040012598 _Py_BEGIN_SUPPRESS_IPH
12599 result = _Py_set_blocking(fd, blocking);
12600 _Py_END_SUPPRESS_IPH
12601 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012602 return NULL;
12603 Py_RETURN_NONE;
12604}
12605#endif /* !MS_WINDOWS */
12606
12607
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012608/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080012609class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012610[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080012611/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012612
12613typedef struct {
12614 PyObject_HEAD
12615 PyObject *name;
12616 PyObject *path;
12617 PyObject *stat;
12618 PyObject *lstat;
12619#ifdef MS_WINDOWS
12620 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012621 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012622 int got_file_index;
12623#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012624#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012625 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012626#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012627 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012628 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012629#endif
12630} DirEntry;
12631
Eddie Elizondob3966632019-11-05 07:16:14 -080012632static PyObject *
12633_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
12634{
12635 PyErr_Format(PyExc_TypeError,
12636 "cannot create '%.100s' instances", _PyType_Name(type));
12637 return NULL;
12638}
12639
Victor Stinner6036e442015-03-08 01:58:04 +010012640static void
12641DirEntry_dealloc(DirEntry *entry)
12642{
Eddie Elizondob3966632019-11-05 07:16:14 -080012643 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010012644 Py_XDECREF(entry->name);
12645 Py_XDECREF(entry->path);
12646 Py_XDECREF(entry->stat);
12647 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080012648 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
12649 free_func(entry);
12650 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010012651}
12652
12653/* Forward reference */
12654static int
12655DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12656
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012657/*[clinic input]
12658os.DirEntry.is_symlink -> bool
12659
12660Return True if the entry is a symbolic link; cached per entry.
12661[clinic start generated code]*/
12662
Victor Stinner6036e442015-03-08 01:58:04 +010012663static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012664os_DirEntry_is_symlink_impl(DirEntry *self)
12665/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012666{
12667#ifdef MS_WINDOWS
12668 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012669#elif defined(HAVE_DIRENT_D_TYPE)
12670 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012671 if (self->d_type != DT_UNKNOWN)
12672 return self->d_type == DT_LNK;
12673 else
12674 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012675#else
12676 /* POSIX without d_type */
12677 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012678#endif
12679}
12680
12681static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012682DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12683{
12684 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012685 STRUCT_STAT st;
12686 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012687
12688#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012689 if (!PyUnicode_FSDecoder(self->path, &ub))
12690 return NULL;
12691 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012692#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012693 if (!PyUnicode_FSConverter(self->path, &ub))
12694 return NULL;
12695 const char *path = PyBytes_AS_STRING(ub);
12696 if (self->dir_fd != DEFAULT_DIR_FD) {
12697#ifdef HAVE_FSTATAT
12698 result = fstatat(self->dir_fd, path, &st,
12699 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12700#else
12701 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12702 return NULL;
12703#endif /* HAVE_FSTATAT */
12704 }
12705 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012706#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012707 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012708 if (follow_symlinks)
12709 result = STAT(path, &st);
12710 else
12711 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012712 }
12713 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012714
12715 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012716 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012717
12718 return _pystat_fromstructstat(&st);
12719}
12720
12721static PyObject *
12722DirEntry_get_lstat(DirEntry *self)
12723{
12724 if (!self->lstat) {
12725#ifdef MS_WINDOWS
12726 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12727#else /* POSIX */
12728 self->lstat = DirEntry_fetch_stat(self, 0);
12729#endif
12730 }
12731 Py_XINCREF(self->lstat);
12732 return self->lstat;
12733}
12734
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012735/*[clinic input]
12736os.DirEntry.stat
12737 *
12738 follow_symlinks: bool = True
12739
12740Return stat_result object for the entry; cached per entry.
12741[clinic start generated code]*/
12742
Victor Stinner6036e442015-03-08 01:58:04 +010012743static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012744os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12745/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012746{
12747 if (!follow_symlinks)
12748 return DirEntry_get_lstat(self);
12749
12750 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012751 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012752 if (result == -1)
12753 return NULL;
12754 else if (result)
12755 self->stat = DirEntry_fetch_stat(self, 1);
12756 else
12757 self->stat = DirEntry_get_lstat(self);
12758 }
12759
12760 Py_XINCREF(self->stat);
12761 return self->stat;
12762}
12763
Victor Stinner6036e442015-03-08 01:58:04 +010012764/* Set exception and return -1 on error, 0 for False, 1 for True */
12765static int
12766DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12767{
12768 PyObject *stat = NULL;
12769 PyObject *st_mode = NULL;
12770 long mode;
12771 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012772#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012773 int is_symlink;
12774 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012775#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012776#ifdef MS_WINDOWS
12777 unsigned long dir_bits;
12778#endif
12779
12780#ifdef MS_WINDOWS
12781 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12782 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012783#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012784 is_symlink = self->d_type == DT_LNK;
12785 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12786#endif
12787
Victor Stinner35a97c02015-03-08 02:59:09 +010012788#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012789 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012790#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012791 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012792 if (!stat) {
12793 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12794 /* If file doesn't exist (anymore), then return False
12795 (i.e., say it's not a file/directory) */
12796 PyErr_Clear();
12797 return 0;
12798 }
12799 goto error;
12800 }
Eddie Elizondob3966632019-11-05 07:16:14 -080012801 st_mode = PyObject_GetAttr(stat, _posixstate_global->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012802 if (!st_mode)
12803 goto error;
12804
12805 mode = PyLong_AsLong(st_mode);
12806 if (mode == -1 && PyErr_Occurred())
12807 goto error;
12808 Py_CLEAR(st_mode);
12809 Py_CLEAR(stat);
12810 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012811#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012812 }
12813 else if (is_symlink) {
12814 assert(mode_bits != S_IFLNK);
12815 result = 0;
12816 }
12817 else {
12818 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12819#ifdef MS_WINDOWS
12820 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12821 if (mode_bits == S_IFDIR)
12822 result = dir_bits != 0;
12823 else
12824 result = dir_bits == 0;
12825#else /* POSIX */
12826 if (mode_bits == S_IFDIR)
12827 result = self->d_type == DT_DIR;
12828 else
12829 result = self->d_type == DT_REG;
12830#endif
12831 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012832#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012833
12834 return result;
12835
12836error:
12837 Py_XDECREF(st_mode);
12838 Py_XDECREF(stat);
12839 return -1;
12840}
12841
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012842/*[clinic input]
12843os.DirEntry.is_dir -> bool
12844 *
12845 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012846
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012847Return True if the entry is a directory; cached per entry.
12848[clinic start generated code]*/
12849
12850static int
12851os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12852/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12853{
12854 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012855}
12856
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012857/*[clinic input]
12858os.DirEntry.is_file -> bool
12859 *
12860 follow_symlinks: bool = True
12861
12862Return True if the entry is a file; cached per entry.
12863[clinic start generated code]*/
12864
12865static int
12866os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12867/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012868{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012869 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012870}
12871
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012872/*[clinic input]
12873os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012874
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012875Return inode of the entry; cached per entry.
12876[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012877
12878static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012879os_DirEntry_inode_impl(DirEntry *self)
12880/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012881{
12882#ifdef MS_WINDOWS
12883 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012884 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012885 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012886 STRUCT_STAT stat;
12887 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012888
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012889 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012890 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012891 path = PyUnicode_AsUnicode(unicode);
12892 result = LSTAT(path, &stat);
12893 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012894
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012895 if (result != 0)
12896 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012897
12898 self->win32_file_index = stat.st_ino;
12899 self->got_file_index = 1;
12900 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012901 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12902 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012903#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012904 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12905 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012906#endif
12907}
12908
12909static PyObject *
12910DirEntry_repr(DirEntry *self)
12911{
12912 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12913}
12914
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012915/*[clinic input]
12916os.DirEntry.__fspath__
12917
12918Returns the path for the entry.
12919[clinic start generated code]*/
12920
Brett Cannon96881cd2016-06-10 14:37:21 -070012921static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012922os_DirEntry___fspath___impl(DirEntry *self)
12923/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012924{
12925 Py_INCREF(self->path);
12926 return self->path;
12927}
12928
Victor Stinner6036e442015-03-08 01:58:04 +010012929static PyMemberDef DirEntry_members[] = {
12930 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12931 "the entry's base filename, relative to scandir() \"path\" argument"},
12932 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12933 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12934 {NULL}
12935};
12936
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012937#include "clinic/posixmodule.c.h"
12938
Victor Stinner6036e442015-03-08 01:58:04 +010012939static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012940 OS_DIRENTRY_IS_DIR_METHODDEF
12941 OS_DIRENTRY_IS_FILE_METHODDEF
12942 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12943 OS_DIRENTRY_STAT_METHODDEF
12944 OS_DIRENTRY_INODE_METHODDEF
12945 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012946 {NULL}
12947};
12948
Eddie Elizondob3966632019-11-05 07:16:14 -080012949static PyType_Slot DirEntryType_slots[] = {
12950 {Py_tp_new, _disabled_new},
12951 {Py_tp_dealloc, DirEntry_dealloc},
12952 {Py_tp_repr, DirEntry_repr},
12953 {Py_tp_methods, DirEntry_methods},
12954 {Py_tp_members, DirEntry_members},
12955 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010012956};
12957
Eddie Elizondob3966632019-11-05 07:16:14 -080012958static PyType_Spec DirEntryType_spec = {
12959 MODNAME ".DirEntry",
12960 sizeof(DirEntry),
12961 0,
12962 Py_TPFLAGS_DEFAULT,
12963 DirEntryType_slots
12964};
12965
12966
Victor Stinner6036e442015-03-08 01:58:04 +010012967#ifdef MS_WINDOWS
12968
12969static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012970join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012971{
12972 Py_ssize_t path_len;
12973 Py_ssize_t size;
12974 wchar_t *result;
12975 wchar_t ch;
12976
12977 if (!path_wide) { /* Default arg: "." */
12978 path_wide = L".";
12979 path_len = 1;
12980 }
12981 else {
12982 path_len = wcslen(path_wide);
12983 }
12984
12985 /* The +1's are for the path separator and the NUL */
12986 size = path_len + 1 + wcslen(filename) + 1;
12987 result = PyMem_New(wchar_t, size);
12988 if (!result) {
12989 PyErr_NoMemory();
12990 return NULL;
12991 }
12992 wcscpy(result, path_wide);
12993 if (path_len > 0) {
12994 ch = result[path_len - 1];
12995 if (ch != SEP && ch != ALTSEP && ch != L':')
12996 result[path_len++] = SEP;
12997 wcscpy(result + path_len, filename);
12998 }
12999 return result;
13000}
13001
13002static PyObject *
13003DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
13004{
13005 DirEntry *entry;
13006 BY_HANDLE_FILE_INFORMATION file_info;
13007 ULONG reparse_tag;
13008 wchar_t *joined_path;
13009
Eddie Elizondob3966632019-11-05 07:16:14 -080013010 PyObject *DirEntryType = _posixstate_global->DirEntryType;
13011 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013012 if (!entry)
13013 return NULL;
13014 entry->name = NULL;
13015 entry->path = NULL;
13016 entry->stat = NULL;
13017 entry->lstat = NULL;
13018 entry->got_file_index = 0;
13019
13020 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13021 if (!entry->name)
13022 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013023 if (path->narrow) {
13024 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13025 if (!entry->name)
13026 goto error;
13027 }
Victor Stinner6036e442015-03-08 01:58:04 +010013028
13029 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13030 if (!joined_path)
13031 goto error;
13032
13033 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13034 PyMem_Free(joined_path);
13035 if (!entry->path)
13036 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013037 if (path->narrow) {
13038 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13039 if (!entry->path)
13040 goto error;
13041 }
Victor Stinner6036e442015-03-08 01:58:04 +010013042
Steve Dowercc16be82016-09-08 10:35:16 -070013043 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013044 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13045
13046 return (PyObject *)entry;
13047
13048error:
13049 Py_DECREF(entry);
13050 return NULL;
13051}
13052
13053#else /* POSIX */
13054
13055static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013056join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013057{
13058 Py_ssize_t path_len;
13059 Py_ssize_t size;
13060 char *result;
13061
13062 if (!path_narrow) { /* Default arg: "." */
13063 path_narrow = ".";
13064 path_len = 1;
13065 }
13066 else {
13067 path_len = strlen(path_narrow);
13068 }
13069
13070 if (filename_len == -1)
13071 filename_len = strlen(filename);
13072
13073 /* The +1's are for the path separator and the NUL */
13074 size = path_len + 1 + filename_len + 1;
13075 result = PyMem_New(char, size);
13076 if (!result) {
13077 PyErr_NoMemory();
13078 return NULL;
13079 }
13080 strcpy(result, path_narrow);
13081 if (path_len > 0 && result[path_len - 1] != '/')
13082 result[path_len++] = '/';
13083 strcpy(result + path_len, filename);
13084 return result;
13085}
13086
13087static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013088DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010013089 ino_t d_ino
13090#ifdef HAVE_DIRENT_D_TYPE
13091 , unsigned char d_type
13092#endif
13093 )
Victor Stinner6036e442015-03-08 01:58:04 +010013094{
13095 DirEntry *entry;
13096 char *joined_path;
13097
Eddie Elizondob3966632019-11-05 07:16:14 -080013098 PyObject *DirEntryType = _posixstate_global->DirEntryType;
13099 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013100 if (!entry)
13101 return NULL;
13102 entry->name = NULL;
13103 entry->path = NULL;
13104 entry->stat = NULL;
13105 entry->lstat = NULL;
13106
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013107 if (path->fd != -1) {
13108 entry->dir_fd = path->fd;
13109 joined_path = NULL;
13110 }
13111 else {
13112 entry->dir_fd = DEFAULT_DIR_FD;
13113 joined_path = join_path_filename(path->narrow, name, name_len);
13114 if (!joined_path)
13115 goto error;
13116 }
Victor Stinner6036e442015-03-08 01:58:04 +010013117
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013118 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013119 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013120 if (joined_path)
13121 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013122 }
13123 else {
13124 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013125 if (joined_path)
13126 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013127 }
13128 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013129 if (!entry->name)
13130 goto error;
13131
13132 if (path->fd != -1) {
13133 entry->path = entry->name;
13134 Py_INCREF(entry->path);
13135 }
13136 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013137 goto error;
13138
Victor Stinner35a97c02015-03-08 02:59:09 +010013139#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013140 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013141#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013142 entry->d_ino = d_ino;
13143
13144 return (PyObject *)entry;
13145
13146error:
13147 Py_XDECREF(entry);
13148 return NULL;
13149}
13150
13151#endif
13152
13153
13154typedef struct {
13155 PyObject_HEAD
13156 path_t path;
13157#ifdef MS_WINDOWS
13158 HANDLE handle;
13159 WIN32_FIND_DATAW file_data;
13160 int first_time;
13161#else /* POSIX */
13162 DIR *dirp;
13163#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013164#ifdef HAVE_FDOPENDIR
13165 int fd;
13166#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013167} ScandirIterator;
13168
13169#ifdef MS_WINDOWS
13170
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013171static int
13172ScandirIterator_is_closed(ScandirIterator *iterator)
13173{
13174 return iterator->handle == INVALID_HANDLE_VALUE;
13175}
13176
Victor Stinner6036e442015-03-08 01:58:04 +010013177static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013178ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013179{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013180 HANDLE handle = iterator->handle;
13181
13182 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013183 return;
13184
Victor Stinner6036e442015-03-08 01:58:04 +010013185 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013186 Py_BEGIN_ALLOW_THREADS
13187 FindClose(handle);
13188 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013189}
13190
13191static PyObject *
13192ScandirIterator_iternext(ScandirIterator *iterator)
13193{
13194 WIN32_FIND_DATAW *file_data = &iterator->file_data;
13195 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013196 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013197
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013198 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013199 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013200 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013201
13202 while (1) {
13203 if (!iterator->first_time) {
13204 Py_BEGIN_ALLOW_THREADS
13205 success = FindNextFileW(iterator->handle, file_data);
13206 Py_END_ALLOW_THREADS
13207 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013208 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013209 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013210 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013211 break;
13212 }
13213 }
13214 iterator->first_time = 0;
13215
13216 /* Skip over . and .. */
13217 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013218 wcscmp(file_data->cFileName, L"..") != 0) {
13219 entry = DirEntry_from_find_data(&iterator->path, file_data);
13220 if (!entry)
13221 break;
13222 return entry;
13223 }
Victor Stinner6036e442015-03-08 01:58:04 +010013224
13225 /* Loop till we get a non-dot directory or finish iterating */
13226 }
13227
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013228 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013229 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013230 return NULL;
13231}
13232
13233#else /* POSIX */
13234
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013235static int
13236ScandirIterator_is_closed(ScandirIterator *iterator)
13237{
13238 return !iterator->dirp;
13239}
13240
Victor Stinner6036e442015-03-08 01:58:04 +010013241static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013242ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013243{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013244 DIR *dirp = iterator->dirp;
13245
13246 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013247 return;
13248
Victor Stinner6036e442015-03-08 01:58:04 +010013249 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013250 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013251#ifdef HAVE_FDOPENDIR
13252 if (iterator->path.fd != -1)
13253 rewinddir(dirp);
13254#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013255 closedir(dirp);
13256 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013257 return;
13258}
13259
13260static PyObject *
13261ScandirIterator_iternext(ScandirIterator *iterator)
13262{
13263 struct dirent *direntp;
13264 Py_ssize_t name_len;
13265 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013266 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013267
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013268 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013269 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013270 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013271
13272 while (1) {
13273 errno = 0;
13274 Py_BEGIN_ALLOW_THREADS
13275 direntp = readdir(iterator->dirp);
13276 Py_END_ALLOW_THREADS
13277
13278 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013279 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013280 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013281 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013282 break;
13283 }
13284
13285 /* Skip over . and .. */
13286 name_len = NAMLEN(direntp);
13287 is_dot = direntp->d_name[0] == '.' &&
13288 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
13289 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013290 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010013291 name_len, direntp->d_ino
13292#ifdef HAVE_DIRENT_D_TYPE
13293 , direntp->d_type
13294#endif
13295 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013296 if (!entry)
13297 break;
13298 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013299 }
13300
13301 /* Loop till we get a non-dot directory or finish iterating */
13302 }
13303
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013304 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013305 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013306 return NULL;
13307}
13308
13309#endif
13310
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013311static PyObject *
13312ScandirIterator_close(ScandirIterator *self, PyObject *args)
13313{
13314 ScandirIterator_closedir(self);
13315 Py_RETURN_NONE;
13316}
13317
13318static PyObject *
13319ScandirIterator_enter(PyObject *self, PyObject *args)
13320{
13321 Py_INCREF(self);
13322 return self;
13323}
13324
13325static PyObject *
13326ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13327{
13328 ScandirIterator_closedir(self);
13329 Py_RETURN_NONE;
13330}
13331
Victor Stinner6036e442015-03-08 01:58:04 +010013332static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013333ScandirIterator_finalize(ScandirIterator *iterator)
13334{
13335 PyObject *error_type, *error_value, *error_traceback;
13336
13337 /* Save the current exception, if any. */
13338 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13339
13340 if (!ScandirIterator_is_closed(iterator)) {
13341 ScandirIterator_closedir(iterator);
13342
13343 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13344 "unclosed scandir iterator %R", iterator)) {
13345 /* Spurious errors can appear at shutdown */
13346 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13347 PyErr_WriteUnraisable((PyObject *) iterator);
13348 }
13349 }
13350 }
13351
Victor Stinner7bfa4092016-03-23 00:43:54 +010013352 path_cleanup(&iterator->path);
13353
13354 /* Restore the saved exception. */
13355 PyErr_Restore(error_type, error_value, error_traceback);
13356}
13357
13358static void
Victor Stinner6036e442015-03-08 01:58:04 +010013359ScandirIterator_dealloc(ScandirIterator *iterator)
13360{
Eddie Elizondob3966632019-11-05 07:16:14 -080013361 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010013362 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13363 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013364
Eddie Elizondob3966632019-11-05 07:16:14 -080013365 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13366 free_func(iterator);
13367 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013368}
13369
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013370static PyMethodDef ScandirIterator_methods[] = {
13371 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13372 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13373 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13374 {NULL}
13375};
13376
Eddie Elizondob3966632019-11-05 07:16:14 -080013377static PyType_Slot ScandirIteratorType_slots[] = {
13378 {Py_tp_new, _disabled_new},
13379 {Py_tp_dealloc, ScandirIterator_dealloc},
13380 {Py_tp_finalize, ScandirIterator_finalize},
13381 {Py_tp_iter, PyObject_SelfIter},
13382 {Py_tp_iternext, ScandirIterator_iternext},
13383 {Py_tp_methods, ScandirIterator_methods},
13384 {0, 0},
13385};
13386
13387static PyType_Spec ScandirIteratorType_spec = {
13388 MODNAME ".ScandirIterator",
13389 sizeof(ScandirIterator),
13390 0,
13391 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
13392 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010013393};
13394
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013395/*[clinic input]
13396os.scandir
13397
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013398 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013399
13400Return an iterator of DirEntry objects for given path.
13401
BNMetricsb9427072018-11-02 15:20:19 +000013402path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013403is bytes, the names of yielded DirEntry objects will also be bytes; in
13404all other circumstances they will be str.
13405
13406If path is None, uses the path='.'.
13407[clinic start generated code]*/
13408
Victor Stinner6036e442015-03-08 01:58:04 +010013409static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013410os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013411/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013412{
13413 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013414#ifdef MS_WINDOWS
13415 wchar_t *path_strW;
13416#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013417 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013418#ifdef HAVE_FDOPENDIR
13419 int fd = -1;
13420#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013421#endif
13422
Steve Dower60419a72019-06-24 08:42:54 -070013423 if (PySys_Audit("os.scandir", "O",
13424 path->object ? path->object : Py_None) < 0) {
13425 return NULL;
13426 }
13427
Eddie Elizondob3966632019-11-05 07:16:14 -080013428 PyObject *ScandirIteratorType = _posixstate(module)->ScandirIteratorType;
13429 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010013430 if (!iterator)
13431 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013432
13433#ifdef MS_WINDOWS
13434 iterator->handle = INVALID_HANDLE_VALUE;
13435#else
13436 iterator->dirp = NULL;
13437#endif
13438
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013439 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013440 /* Move the ownership to iterator->path */
13441 path->object = NULL;
13442 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013443
13444#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013445 iterator->first_time = 1;
13446
13447 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13448 if (!path_strW)
13449 goto error;
13450
13451 Py_BEGIN_ALLOW_THREADS
13452 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13453 Py_END_ALLOW_THREADS
13454
13455 PyMem_Free(path_strW);
13456
13457 if (iterator->handle == INVALID_HANDLE_VALUE) {
13458 path_error(&iterator->path);
13459 goto error;
13460 }
13461#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013462 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013463#ifdef HAVE_FDOPENDIR
13464 if (path->fd != -1) {
13465 /* closedir() closes the FD, so we duplicate it */
13466 fd = _Py_dup(path->fd);
13467 if (fd == -1)
13468 goto error;
13469
13470 Py_BEGIN_ALLOW_THREADS
13471 iterator->dirp = fdopendir(fd);
13472 Py_END_ALLOW_THREADS
13473 }
13474 else
13475#endif
13476 {
13477 if (iterator->path.narrow)
13478 path_str = iterator->path.narrow;
13479 else
13480 path_str = ".";
13481
13482 Py_BEGIN_ALLOW_THREADS
13483 iterator->dirp = opendir(path_str);
13484 Py_END_ALLOW_THREADS
13485 }
Victor Stinner6036e442015-03-08 01:58:04 +010013486
13487 if (!iterator->dirp) {
13488 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013489#ifdef HAVE_FDOPENDIR
13490 if (fd != -1) {
13491 Py_BEGIN_ALLOW_THREADS
13492 close(fd);
13493 Py_END_ALLOW_THREADS
13494 }
13495#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013496 goto error;
13497 }
13498#endif
13499
13500 return (PyObject *)iterator;
13501
13502error:
13503 Py_DECREF(iterator);
13504 return NULL;
13505}
13506
Ethan Furman410ef8e2016-06-04 12:06:26 -070013507/*
13508 Return the file system path representation of the object.
13509
13510 If the object is str or bytes, then allow it to pass through with
13511 an incremented refcount. If the object defines __fspath__(), then
13512 return the result of that method. All other types raise a TypeError.
13513*/
13514PyObject *
13515PyOS_FSPath(PyObject *path)
13516{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013517 /* For error message reasons, this function is manually inlined in
13518 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013519 PyObject *func = NULL;
13520 PyObject *path_repr = NULL;
13521
13522 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13523 Py_INCREF(path);
13524 return path;
13525 }
13526
13527 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13528 if (NULL == func) {
13529 return PyErr_Format(PyExc_TypeError,
13530 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013531 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080013532 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070013533 }
13534
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013535 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013536 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013537 if (NULL == path_repr) {
13538 return NULL;
13539 }
13540
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013541 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13542 PyErr_Format(PyExc_TypeError,
13543 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080013544 "not %.200s", _PyType_Name(Py_TYPE(path)),
13545 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013546 Py_DECREF(path_repr);
13547 return NULL;
13548 }
13549
Ethan Furman410ef8e2016-06-04 12:06:26 -070013550 return path_repr;
13551}
13552
13553/*[clinic input]
13554os.fspath
13555
13556 path: object
13557
13558Return the file system path representation of the object.
13559
Brett Cannonb4f43e92016-06-09 14:32:08 -070013560If the object is str or bytes, then allow it to pass through as-is. If the
13561object defines __fspath__(), then return the result of that method. All other
13562types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013563[clinic start generated code]*/
13564
13565static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013566os_fspath_impl(PyObject *module, PyObject *path)
13567/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013568{
13569 return PyOS_FSPath(path);
13570}
Victor Stinner6036e442015-03-08 01:58:04 +010013571
Victor Stinner9b1f4742016-09-06 16:18:52 -070013572#ifdef HAVE_GETRANDOM_SYSCALL
13573/*[clinic input]
13574os.getrandom
13575
13576 size: Py_ssize_t
13577 flags: int=0
13578
13579Obtain a series of random bytes.
13580[clinic start generated code]*/
13581
13582static PyObject *
13583os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13584/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13585{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013586 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013587 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013588
13589 if (size < 0) {
13590 errno = EINVAL;
13591 return posix_error();
13592 }
13593
Victor Stinnerec2319c2016-09-20 23:00:59 +020013594 bytes = PyBytes_FromStringAndSize(NULL, size);
13595 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013596 PyErr_NoMemory();
13597 return NULL;
13598 }
13599
13600 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013601 n = syscall(SYS_getrandom,
13602 PyBytes_AS_STRING(bytes),
13603 PyBytes_GET_SIZE(bytes),
13604 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013605 if (n < 0 && errno == EINTR) {
13606 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013607 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013608 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013609
13610 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013611 continue;
13612 }
13613 break;
13614 }
13615
13616 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013617 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013618 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013619 }
13620
Victor Stinnerec2319c2016-09-20 23:00:59 +020013621 if (n != size) {
13622 _PyBytes_Resize(&bytes, n);
13623 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013624
13625 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013626
13627error:
13628 Py_DECREF(bytes);
13629 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013630}
13631#endif /* HAVE_GETRANDOM_SYSCALL */
13632
Steve Dower2438cdf2019-03-29 16:37:16 -070013633#ifdef MS_WINDOWS
13634/* bpo-36085: Helper functions for managing DLL search directories
13635 * on win32
13636 */
13637
13638typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13639typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13640
13641/*[clinic input]
13642os._add_dll_directory
13643
13644 path: path_t
13645
13646Add a path to the DLL search path.
13647
13648This search path is used when resolving dependencies for imported
13649extension modules (the module itself is resolved through sys.path),
13650and also by ctypes.
13651
13652Returns an opaque value that may be passed to os.remove_dll_directory
13653to remove this directory from the search path.
13654[clinic start generated code]*/
13655
13656static PyObject *
13657os__add_dll_directory_impl(PyObject *module, path_t *path)
13658/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13659{
13660 HMODULE hKernel32;
13661 PAddDllDirectory AddDllDirectory;
13662 DLL_DIRECTORY_COOKIE cookie = 0;
13663 DWORD err = 0;
13664
Saiyang Gou7514f4f2020-02-12 23:47:42 -080013665 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
13666 return NULL;
13667 }
13668
Steve Dower2438cdf2019-03-29 16:37:16 -070013669 /* For Windows 7, we have to load this. As this will be a fairly
13670 infrequent operation, just do it each time. Kernel32 is always
13671 loaded. */
13672 Py_BEGIN_ALLOW_THREADS
13673 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13674 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13675 hKernel32, "AddDllDirectory")) ||
13676 !(cookie = (*AddDllDirectory)(path->wide))) {
13677 err = GetLastError();
13678 }
13679 Py_END_ALLOW_THREADS
13680
13681 if (err) {
13682 return win32_error_object_err("add_dll_directory",
13683 path->object, err);
13684 }
13685
13686 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13687}
13688
13689/*[clinic input]
13690os._remove_dll_directory
13691
13692 cookie: object
13693
13694Removes a path from the DLL search path.
13695
13696The parameter is an opaque value that was returned from
13697os.add_dll_directory. You can only remove directories that you added
13698yourself.
13699[clinic start generated code]*/
13700
13701static PyObject *
13702os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13703/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13704{
13705 HMODULE hKernel32;
13706 PRemoveDllDirectory RemoveDllDirectory;
13707 DLL_DIRECTORY_COOKIE cookieValue;
13708 DWORD err = 0;
13709
13710 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13711 PyErr_SetString(PyExc_TypeError,
13712 "Provided cookie was not returned from os.add_dll_directory");
13713 return NULL;
13714 }
13715
13716 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13717 cookie, "DLL directory cookie");
13718
13719 /* For Windows 7, we have to load this. As this will be a fairly
13720 infrequent operation, just do it each time. Kernel32 is always
13721 loaded. */
13722 Py_BEGIN_ALLOW_THREADS
13723 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13724 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13725 hKernel32, "RemoveDllDirectory")) ||
13726 !(*RemoveDllDirectory)(cookieValue)) {
13727 err = GetLastError();
13728 }
13729 Py_END_ALLOW_THREADS
13730
13731 if (err) {
13732 return win32_error_object_err("remove_dll_directory",
13733 NULL, err);
13734 }
13735
13736 if (PyCapsule_SetName(cookie, NULL)) {
13737 return NULL;
13738 }
13739
13740 Py_RETURN_NONE;
13741}
13742
13743#endif
Larry Hastings31826802013-10-19 00:09:25 -070013744
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013745static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013746
13747 OS_STAT_METHODDEF
13748 OS_ACCESS_METHODDEF
13749 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013750 OS_CHDIR_METHODDEF
13751 OS_CHFLAGS_METHODDEF
13752 OS_CHMOD_METHODDEF
13753 OS_FCHMOD_METHODDEF
13754 OS_LCHMOD_METHODDEF
13755 OS_CHOWN_METHODDEF
13756 OS_FCHOWN_METHODDEF
13757 OS_LCHOWN_METHODDEF
13758 OS_LCHFLAGS_METHODDEF
13759 OS_CHROOT_METHODDEF
13760 OS_CTERMID_METHODDEF
13761 OS_GETCWD_METHODDEF
13762 OS_GETCWDB_METHODDEF
13763 OS_LINK_METHODDEF
13764 OS_LISTDIR_METHODDEF
13765 OS_LSTAT_METHODDEF
13766 OS_MKDIR_METHODDEF
13767 OS_NICE_METHODDEF
13768 OS_GETPRIORITY_METHODDEF
13769 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013770 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013771 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013772 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010013773 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013774 OS_RENAME_METHODDEF
13775 OS_REPLACE_METHODDEF
13776 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013777 OS_SYMLINK_METHODDEF
13778 OS_SYSTEM_METHODDEF
13779 OS_UMASK_METHODDEF
13780 OS_UNAME_METHODDEF
13781 OS_UNLINK_METHODDEF
13782 OS_REMOVE_METHODDEF
13783 OS_UTIME_METHODDEF
13784 OS_TIMES_METHODDEF
13785 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013786 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013787 OS_EXECV_METHODDEF
13788 OS_EXECVE_METHODDEF
13789 OS_SPAWNV_METHODDEF
13790 OS_SPAWNVE_METHODDEF
13791 OS_FORK1_METHODDEF
13792 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013793 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013794 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13795 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13796 OS_SCHED_GETPARAM_METHODDEF
13797 OS_SCHED_GETSCHEDULER_METHODDEF
13798 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13799 OS_SCHED_SETPARAM_METHODDEF
13800 OS_SCHED_SETSCHEDULER_METHODDEF
13801 OS_SCHED_YIELD_METHODDEF
13802 OS_SCHED_SETAFFINITY_METHODDEF
13803 OS_SCHED_GETAFFINITY_METHODDEF
13804 OS_OPENPTY_METHODDEF
13805 OS_FORKPTY_METHODDEF
13806 OS_GETEGID_METHODDEF
13807 OS_GETEUID_METHODDEF
13808 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013809#ifdef HAVE_GETGROUPLIST
13810 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13811#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013812 OS_GETGROUPS_METHODDEF
13813 OS_GETPID_METHODDEF
13814 OS_GETPGRP_METHODDEF
13815 OS_GETPPID_METHODDEF
13816 OS_GETUID_METHODDEF
13817 OS_GETLOGIN_METHODDEF
13818 OS_KILL_METHODDEF
13819 OS_KILLPG_METHODDEF
13820 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013821#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013822 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013823#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013824 OS_SETUID_METHODDEF
13825 OS_SETEUID_METHODDEF
13826 OS_SETREUID_METHODDEF
13827 OS_SETGID_METHODDEF
13828 OS_SETEGID_METHODDEF
13829 OS_SETREGID_METHODDEF
13830 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013831#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013832 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013833#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013834 OS_GETPGID_METHODDEF
13835 OS_SETPGRP_METHODDEF
13836 OS_WAIT_METHODDEF
13837 OS_WAIT3_METHODDEF
13838 OS_WAIT4_METHODDEF
13839 OS_WAITID_METHODDEF
13840 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080013841 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013842 OS_GETSID_METHODDEF
13843 OS_SETSID_METHODDEF
13844 OS_SETPGID_METHODDEF
13845 OS_TCGETPGRP_METHODDEF
13846 OS_TCSETPGRP_METHODDEF
13847 OS_OPEN_METHODDEF
13848 OS_CLOSE_METHODDEF
13849 OS_CLOSERANGE_METHODDEF
13850 OS_DEVICE_ENCODING_METHODDEF
13851 OS_DUP_METHODDEF
13852 OS_DUP2_METHODDEF
13853 OS_LOCKF_METHODDEF
13854 OS_LSEEK_METHODDEF
13855 OS_READ_METHODDEF
13856 OS_READV_METHODDEF
13857 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013858 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013859 OS_WRITE_METHODDEF
13860 OS_WRITEV_METHODDEF
13861 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013862 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013863#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013864 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013865 posix_sendfile__doc__},
13866#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013867 OS_FSTAT_METHODDEF
13868 OS_ISATTY_METHODDEF
13869 OS_PIPE_METHODDEF
13870 OS_PIPE2_METHODDEF
13871 OS_MKFIFO_METHODDEF
13872 OS_MKNOD_METHODDEF
13873 OS_MAJOR_METHODDEF
13874 OS_MINOR_METHODDEF
13875 OS_MAKEDEV_METHODDEF
13876 OS_FTRUNCATE_METHODDEF
13877 OS_TRUNCATE_METHODDEF
13878 OS_POSIX_FALLOCATE_METHODDEF
13879 OS_POSIX_FADVISE_METHODDEF
13880 OS_PUTENV_METHODDEF
13881 OS_UNSETENV_METHODDEF
13882 OS_STRERROR_METHODDEF
13883 OS_FCHDIR_METHODDEF
13884 OS_FSYNC_METHODDEF
13885 OS_SYNC_METHODDEF
13886 OS_FDATASYNC_METHODDEF
13887 OS_WCOREDUMP_METHODDEF
13888 OS_WIFCONTINUED_METHODDEF
13889 OS_WIFSTOPPED_METHODDEF
13890 OS_WIFSIGNALED_METHODDEF
13891 OS_WIFEXITED_METHODDEF
13892 OS_WEXITSTATUS_METHODDEF
13893 OS_WTERMSIG_METHODDEF
13894 OS_WSTOPSIG_METHODDEF
13895 OS_FSTATVFS_METHODDEF
13896 OS_STATVFS_METHODDEF
13897 OS_CONFSTR_METHODDEF
13898 OS_SYSCONF_METHODDEF
13899 OS_FPATHCONF_METHODDEF
13900 OS_PATHCONF_METHODDEF
13901 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013902 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013903 OS__GETDISKUSAGE_METHODDEF
13904 OS__GETFINALPATHNAME_METHODDEF
13905 OS__GETVOLUMEPATHNAME_METHODDEF
13906 OS_GETLOADAVG_METHODDEF
13907 OS_URANDOM_METHODDEF
13908 OS_SETRESUID_METHODDEF
13909 OS_SETRESGID_METHODDEF
13910 OS_GETRESUID_METHODDEF
13911 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013912
Larry Hastings2f936352014-08-05 14:04:04 +100013913 OS_GETXATTR_METHODDEF
13914 OS_SETXATTR_METHODDEF
13915 OS_REMOVEXATTR_METHODDEF
13916 OS_LISTXATTR_METHODDEF
13917
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013918#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13919 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13920#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013921 OS_CPU_COUNT_METHODDEF
13922 OS_GET_INHERITABLE_METHODDEF
13923 OS_SET_INHERITABLE_METHODDEF
13924 OS_GET_HANDLE_INHERITABLE_METHODDEF
13925 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013926#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013927 OS_GET_BLOCKING_METHODDEF
13928 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013929#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013930 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013931 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013932 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060013933 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070013934#ifdef MS_WINDOWS
13935 OS__ADD_DLL_DIRECTORY_METHODDEF
13936 OS__REMOVE_DLL_DIRECTORY_METHODDEF
13937#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013938 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013939};
13940
Barry Warsaw4a342091996-12-19 23:50:02 +000013941static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013942all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013943{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013944#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013945 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013946#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013947#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013948 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013949#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013950#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013951 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013952#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013953#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013954 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013955#endif
Fred Drakec9680921999-12-13 16:37:25 +000013956#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013957 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013958#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013959#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013960 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013961#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013962#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013963 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013964#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013965#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013966 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013967#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013968#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013969 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013970#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013971#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013972 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013973#endif
13974#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013975 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013976#endif
13977#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013978 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013979#endif
13980#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013981 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013982#endif
13983#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013984 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013985#endif
13986#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013987 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013988#endif
13989#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013990 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013991#endif
13992#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013993 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013994#endif
13995#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013996 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013997#endif
13998#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013999 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014000#endif
14001#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014002 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014003#endif
14004#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014005 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014006#endif
14007#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014008 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014009#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014010#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014011 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014012#endif
14013#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014014 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014015#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014016#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014017 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014018#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014019#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014020 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014021#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014022#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014023#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014024 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014025#endif
14026#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014027 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014028#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014029#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014030#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014031 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014032#endif
14033#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014034 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014035#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014036#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014037 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014038#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014039#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014040 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014041#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014042#ifdef O_TMPFILE
14043 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14044#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014045#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014046 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014047#endif
14048#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014049 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014050#endif
14051#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014052 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014053#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014054#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014055 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014056#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014057#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014058 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014059#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014060
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014061
Jesus Cea94363612012-06-22 18:32:07 +020014062#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014063 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014064#endif
14065#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014066 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014067#endif
14068
Tim Peters5aa91602002-01-30 05:46:57 +000014069/* MS Windows */
14070#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014071 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014072 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014073#endif
14074#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000014075 /* Optimize for short life (keep in memory). */
14076 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014077 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014078#endif
14079#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000014080 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014081 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014082#endif
14083#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000014084 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014085 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014086#endif
14087#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014088 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014089 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014090#endif
14091
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014092/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014093#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014094 /* Send a SIGIO signal whenever input or output
14095 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014096 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014097#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014098#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014099 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014100 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014101#endif
14102#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000014103 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014104 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014105#endif
14106#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000014107 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014108 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014109#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014110#ifdef O_NOLINKS
14111 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014112 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014113#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014114#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014115 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014116 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014117#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000014118
Victor Stinner8c62be82010-05-06 00:08:46 +000014119 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014120#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014121 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014122#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014123#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014124 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014125#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014126#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014127 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014128#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014129#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014130 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014131#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014132#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014133 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014134#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014135#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014136 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014137#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014138#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014139 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014140#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014141#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014142 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014143#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014144#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014145 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014146#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014147#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014148 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014149#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014150#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014151 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014152#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014153#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014154 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014155#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014156#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014157 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014158#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014159#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014160 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014161#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014162#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014163 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014164#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014165#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014166 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014167#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014168#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014169 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014170#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014171
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000014172 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014173#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014174 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014175#endif /* ST_RDONLY */
14176#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014177 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014178#endif /* ST_NOSUID */
14179
doko@ubuntu.comca616a22013-12-08 15:23:07 +010014180 /* GNU extensions */
14181#ifdef ST_NODEV
14182 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
14183#endif /* ST_NODEV */
14184#ifdef ST_NOEXEC
14185 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
14186#endif /* ST_NOEXEC */
14187#ifdef ST_SYNCHRONOUS
14188 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
14189#endif /* ST_SYNCHRONOUS */
14190#ifdef ST_MANDLOCK
14191 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
14192#endif /* ST_MANDLOCK */
14193#ifdef ST_WRITE
14194 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
14195#endif /* ST_WRITE */
14196#ifdef ST_APPEND
14197 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
14198#endif /* ST_APPEND */
14199#ifdef ST_NOATIME
14200 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
14201#endif /* ST_NOATIME */
14202#ifdef ST_NODIRATIME
14203 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
14204#endif /* ST_NODIRATIME */
14205#ifdef ST_RELATIME
14206 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
14207#endif /* ST_RELATIME */
14208
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014209 /* FreeBSD sendfile() constants */
14210#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014211 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014212#endif
14213#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014214 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014215#endif
14216#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014217 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014218#endif
14219
Ross Lagerwall7807c352011-03-17 20:20:30 +020014220 /* constants for posix_fadvise */
14221#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014222 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014223#endif
14224#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014225 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014226#endif
14227#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014228 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014229#endif
14230#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014231 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014232#endif
14233#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014234 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014235#endif
14236#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014237 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014238#endif
14239
14240 /* constants for waitid */
14241#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014242 if (PyModule_AddIntMacro(m, P_PID)) return -1;
14243 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
14244 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080014245#ifdef P_PIDFD
14246 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
14247#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014248#endif
14249#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014250 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014251#endif
14252#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014253 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014254#endif
14255#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014256 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014257#endif
14258#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014259 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014260#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014261#ifdef CLD_KILLED
14262 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
14263#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014264#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014265 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014266#endif
14267#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014268 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014269#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014270#ifdef CLD_STOPPED
14271 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
14272#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014273#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014274 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014275#endif
14276
14277 /* constants for lockf */
14278#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014279 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014280#endif
14281#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014282 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014283#endif
14284#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014285 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014286#endif
14287#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014288 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014289#endif
14290
Pablo Galindo4defba32018-01-27 16:16:37 +000014291#ifdef RWF_DSYNC
14292 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14293#endif
14294#ifdef RWF_HIPRI
14295 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14296#endif
14297#ifdef RWF_SYNC
14298 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14299#endif
14300#ifdef RWF_NOWAIT
14301 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14302#endif
14303
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014304/* constants for posix_spawn */
14305#ifdef HAVE_POSIX_SPAWN
14306 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14307 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14308 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14309#endif
14310
pxinwrf2d7ac72019-05-21 18:46:37 +080014311#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014312 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14313 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014314 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014315#endif
14316#ifdef HAVE_SPAWNV
14317 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014318 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014319#endif
14320
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014321#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014322#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014323 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014324#endif
14325#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014326 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014327#endif
14328#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014329 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014330#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014331#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014332 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014333#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014334#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014335 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014336#endif
14337#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014338 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014339#endif
14340#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014341 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014342#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014343#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014344 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014345#endif
14346#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014347 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014348#endif
14349#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014350 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014351#endif
14352#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014353 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014354#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014355#endif
14356
Benjamin Peterson9428d532011-09-14 11:45:52 -040014357#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014358 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
14359 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
14360 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040014361#endif
14362
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014363#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014364 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014365#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014366#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014367 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014368#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014369#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014370 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014371#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014372#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014373 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014374#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014375#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014376 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014377#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014378#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014379 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014380#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014381#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014382 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014383#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010014384#if HAVE_DECL_RTLD_MEMBER
14385 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
14386#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020014387
Victor Stinner9b1f4742016-09-06 16:18:52 -070014388#ifdef HAVE_GETRANDOM_SYSCALL
14389 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
14390 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
14391#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014392#ifdef HAVE_MEMFD_CREATE
14393 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
14394 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
14395#ifdef MFD_HUGETLB
14396 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014397#endif
14398#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014399 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014400#endif
14401#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014402 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014403#endif
14404#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014405 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014406#endif
14407#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014408 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014409#endif
14410#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014411 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014412#endif
14413#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014414 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014415#endif
14416#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014417 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014418#endif
14419#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014420 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014421#endif
14422#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014423 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014424#endif
14425#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014426 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014427#endif
14428#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014429 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014430#endif
14431#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014432 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014433#endif
14434#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014435 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014436#endif
14437#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014438 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
14439#endif
14440#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070014441
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014442#if defined(__APPLE__)
14443 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
14444#endif
14445
Steve Dower2438cdf2019-03-29 16:37:16 -070014446#ifdef MS_WINDOWS
14447 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
14448 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
14449 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
14450 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
14451 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
14452#endif
14453
Victor Stinner8c62be82010-05-06 00:08:46 +000014454 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000014455}
14456
14457
Martin v. Löwis1a214512008-06-11 05:26:20 +000014458static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000014459 PyModuleDef_HEAD_INIT,
14460 MODNAME,
14461 posix__doc__,
Eddie Elizondob3966632019-11-05 07:16:14 -080014462 sizeof(_posixstate),
Victor Stinner8c62be82010-05-06 00:08:46 +000014463 posix_methods,
14464 NULL,
Eddie Elizondob3966632019-11-05 07:16:14 -080014465 _posix_traverse,
14466 _posix_clear,
14467 _posix_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +000014468};
14469
14470
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014471static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014472
14473#ifdef HAVE_FACCESSAT
14474 "HAVE_FACCESSAT",
14475#endif
14476
14477#ifdef HAVE_FCHDIR
14478 "HAVE_FCHDIR",
14479#endif
14480
14481#ifdef HAVE_FCHMOD
14482 "HAVE_FCHMOD",
14483#endif
14484
14485#ifdef HAVE_FCHMODAT
14486 "HAVE_FCHMODAT",
14487#endif
14488
14489#ifdef HAVE_FCHOWN
14490 "HAVE_FCHOWN",
14491#endif
14492
Larry Hastings00964ed2013-08-12 13:49:30 -040014493#ifdef HAVE_FCHOWNAT
14494 "HAVE_FCHOWNAT",
14495#endif
14496
Larry Hastings9cf065c2012-06-22 16:30:09 -070014497#ifdef HAVE_FEXECVE
14498 "HAVE_FEXECVE",
14499#endif
14500
14501#ifdef HAVE_FDOPENDIR
14502 "HAVE_FDOPENDIR",
14503#endif
14504
Georg Brandl306336b2012-06-24 12:55:33 +020014505#ifdef HAVE_FPATHCONF
14506 "HAVE_FPATHCONF",
14507#endif
14508
Larry Hastings9cf065c2012-06-22 16:30:09 -070014509#ifdef HAVE_FSTATAT
14510 "HAVE_FSTATAT",
14511#endif
14512
14513#ifdef HAVE_FSTATVFS
14514 "HAVE_FSTATVFS",
14515#endif
14516
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014517#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014518 "HAVE_FTRUNCATE",
14519#endif
14520
Larry Hastings9cf065c2012-06-22 16:30:09 -070014521#ifdef HAVE_FUTIMENS
14522 "HAVE_FUTIMENS",
14523#endif
14524
14525#ifdef HAVE_FUTIMES
14526 "HAVE_FUTIMES",
14527#endif
14528
14529#ifdef HAVE_FUTIMESAT
14530 "HAVE_FUTIMESAT",
14531#endif
14532
14533#ifdef HAVE_LINKAT
14534 "HAVE_LINKAT",
14535#endif
14536
14537#ifdef HAVE_LCHFLAGS
14538 "HAVE_LCHFLAGS",
14539#endif
14540
14541#ifdef HAVE_LCHMOD
14542 "HAVE_LCHMOD",
14543#endif
14544
14545#ifdef HAVE_LCHOWN
14546 "HAVE_LCHOWN",
14547#endif
14548
14549#ifdef HAVE_LSTAT
14550 "HAVE_LSTAT",
14551#endif
14552
14553#ifdef HAVE_LUTIMES
14554 "HAVE_LUTIMES",
14555#endif
14556
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014557#ifdef HAVE_MEMFD_CREATE
14558 "HAVE_MEMFD_CREATE",
14559#endif
14560
Larry Hastings9cf065c2012-06-22 16:30:09 -070014561#ifdef HAVE_MKDIRAT
14562 "HAVE_MKDIRAT",
14563#endif
14564
14565#ifdef HAVE_MKFIFOAT
14566 "HAVE_MKFIFOAT",
14567#endif
14568
14569#ifdef HAVE_MKNODAT
14570 "HAVE_MKNODAT",
14571#endif
14572
14573#ifdef HAVE_OPENAT
14574 "HAVE_OPENAT",
14575#endif
14576
14577#ifdef HAVE_READLINKAT
14578 "HAVE_READLINKAT",
14579#endif
14580
14581#ifdef HAVE_RENAMEAT
14582 "HAVE_RENAMEAT",
14583#endif
14584
14585#ifdef HAVE_SYMLINKAT
14586 "HAVE_SYMLINKAT",
14587#endif
14588
14589#ifdef HAVE_UNLINKAT
14590 "HAVE_UNLINKAT",
14591#endif
14592
14593#ifdef HAVE_UTIMENSAT
14594 "HAVE_UTIMENSAT",
14595#endif
14596
14597#ifdef MS_WINDOWS
14598 "MS_WINDOWS",
14599#endif
14600
14601 NULL
14602};
14603
14604
Mark Hammondfe51c6d2002-08-02 02:27:13 +000014605PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000014606INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014607{
Victor Stinner8c62be82010-05-06 00:08:46 +000014608 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014609 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014610 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000014611
Eddie Elizondob3966632019-11-05 07:16:14 -080014612 m = PyState_FindModule(&posixmodule);
14613 if (m != NULL) {
14614 Py_INCREF(m);
14615 return m;
14616 }
14617
Victor Stinner8c62be82010-05-06 00:08:46 +000014618 m = PyModule_Create(&posixmodule);
14619 if (m == NULL)
14620 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000014621
Victor Stinner8c62be82010-05-06 00:08:46 +000014622 /* Initialize environ dictionary */
14623 v = convertenviron();
14624 Py_XINCREF(v);
14625 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
14626 return NULL;
14627 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014628
Victor Stinner8c62be82010-05-06 00:08:46 +000014629 if (all_ins(m))
14630 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000014631
Victor Stinner8c62be82010-05-06 00:08:46 +000014632 if (setup_confname_tables(m))
14633 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000014634
Victor Stinner8c62be82010-05-06 00:08:46 +000014635 Py_INCREF(PyExc_OSError);
14636 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014637
Ross Lagerwall7807c352011-03-17 20:20:30 +020014638#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080014639 waitid_result_desc.name = MODNAME ".waitid_result";
14640 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
14641 if (WaitidResultType == NULL) {
14642 return NULL;
14643 }
14644 Py_INCREF(WaitidResultType);
14645 PyModule_AddObject(m, "waitid_result", WaitidResultType);
14646 _posixstate(m)->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014647#endif
14648
Eddie Elizondob3966632019-11-05 07:16:14 -080014649 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
14650 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14651 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14652 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
14653 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
14654 if (StatResultType == NULL) {
14655 return NULL;
14656 }
14657 Py_INCREF(StatResultType);
14658 PyModule_AddObject(m, "stat_result", StatResultType);
14659 _posixstate(m)->StatResultType = StatResultType;
14660 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
14661 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014662
Eddie Elizondob3966632019-11-05 07:16:14 -080014663 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
14664 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
14665 if (StatVFSResultType == NULL) {
14666 return NULL;
14667 }
14668 Py_INCREF(StatVFSResultType);
14669 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
14670 _posixstate(m)->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014671#ifdef NEED_TICKS_PER_SECOND
14672# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080014673 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014674# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080014675 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014676# else
Eddie Elizondob3966632019-11-05 07:16:14 -080014677 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014678# endif
14679#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014680
William Orr81574b82018-10-01 22:19:56 -070014681#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080014682 sched_param_desc.name = MODNAME ".sched_param";
14683 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
14684 if (SchedParamType == NULL) {
14685 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014686 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014687 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080014688 PyModule_AddObject(m, "sched_param", SchedParamType);
14689 _posixstate(m)->SchedParamType = SchedParamType;
14690 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014691#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014692
Eddie Elizondob3966632019-11-05 07:16:14 -080014693 /* initialize TerminalSize_info */
14694 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
14695 if (TerminalSizeType == NULL) {
14696 return NULL;
14697 }
14698 Py_INCREF(TerminalSizeType);
14699 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
14700 _posixstate(m)->TerminalSizeType = TerminalSizeType;
14701
14702 /* initialize scandir types */
14703 PyObject *ScandirIteratorType = PyType_FromSpec(&ScandirIteratorType_spec);
14704 if (ScandirIteratorType == NULL) {
14705 return NULL;
14706 }
14707 _posixstate(m)->ScandirIteratorType = ScandirIteratorType;
14708
14709 PyObject *DirEntryType = PyType_FromSpec(&DirEntryType_spec);
14710 if (DirEntryType == NULL) {
14711 return NULL;
14712 }
14713 Py_INCREF(DirEntryType);
14714 PyModule_AddObject(m, "DirEntry", DirEntryType);
14715 _posixstate(m)->DirEntryType = DirEntryType;
14716
Larry Hastings605a62d2012-06-24 04:33:36 -070014717 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080014718 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014719 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014720 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014721 }
Eddie Elizondob3966632019-11-05 07:16:14 -080014722 Py_INCREF(TimesResultType);
14723 PyModule_AddObject(m, "times_result", TimesResultType);
14724 _posixstate(m)->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070014725
Eddie Elizondob3966632019-11-05 07:16:14 -080014726 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014727 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014728 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014729 }
Eddie Elizondob3966632019-11-05 07:16:14 -080014730 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014731 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -080014732 _posixstate(m)->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070014733
Thomas Wouters477c8d52006-05-27 19:21:47 +000014734#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014735 /*
14736 * Step 2 of weak-linking support on Mac OS X.
14737 *
14738 * The code below removes functions that are not available on the
14739 * currently active platform.
14740 *
14741 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014742 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014743 * OSX 10.4.
14744 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014745#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014746 if (fstatvfs == NULL) {
14747 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14748 return NULL;
14749 }
14750 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014751#endif /* HAVE_FSTATVFS */
14752
14753#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014754 if (statvfs == NULL) {
14755 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14756 return NULL;
14757 }
14758 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014759#endif /* HAVE_STATVFS */
14760
14761# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014762 if (lchown == NULL) {
14763 if (PyObject_DelAttrString(m, "lchown") == -1) {
14764 return NULL;
14765 }
14766 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014767#endif /* HAVE_LCHOWN */
14768
14769
14770#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014771
Eddie Elizondob3966632019-11-05 07:16:14 -080014772 if ((_posixstate(m)->billion = PyLong_FromLong(1000000000)) == NULL)
14773 return NULL;
14774#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
14775 _posixstate(m)->struct_rusage = PyUnicode_InternFromString("struct_rusage");
14776 if (_posixstate(m)->struct_rusage == NULL)
14777 return NULL;
14778#endif
14779 _posixstate(m)->st_mode = PyUnicode_InternFromString("st_mode");
14780 if (_posixstate(m)->st_mode == NULL)
Larry Hastings6fe20b32012-04-19 15:07:49 -070014781 return NULL;
14782
Larry Hastings9cf065c2012-06-22 16:30:09 -070014783 /* suppress "function not used" warnings */
14784 {
14785 int ignored;
14786 fd_specified("", -1);
14787 follow_symlinks_specified("", 1);
14788 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14789 dir_fd_converter(Py_None, &ignored);
14790 dir_fd_unavailable(Py_None, &ignored);
14791 }
14792
14793 /*
14794 * provide list of locally available functions
14795 * so os.py can populate support_* lists
14796 */
14797 list = PyList_New(0);
14798 if (!list)
14799 return NULL;
14800 for (trace = have_functions; *trace; trace++) {
14801 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14802 if (!unicode)
14803 return NULL;
14804 if (PyList_Append(list, unicode))
14805 return NULL;
14806 Py_DECREF(unicode);
14807 }
14808 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014809
Victor Stinner8c62be82010-05-06 00:08:46 +000014810 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014811}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014812
14813#ifdef __cplusplus
14814}
14815#endif