blob: 71b99fd836f1527662a12937814f04bbdd9d73b7 [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
Victor Stinner0852c7d2020-01-22 21:53:26 +0100822/* Windows: _wputenv(env) copies the *env* string and doesn't require the
823 caller to manage the variable memory. */
824#if defined(HAVE_PUTENV) && !defined(MS_WINDOWS)
Victor Stinner623ed612020-01-21 19:25:32 +0100825# define PY_PUTENV_DICT
826#endif
827
Eddie Elizondob3966632019-11-05 07:16:14 -0800828typedef struct {
829 PyObject *billion;
Victor Stinner623ed612020-01-21 19:25:32 +0100830#ifdef PY_PUTENV_DICT
831 /* putenv() and _wputenv() requires that the caller manages the environment
832 variable memory. Use a Python dictionary for that: name => env, where
833 env is a string like "name=value". On Windows, dict keys and values are
834 Unicode strings. On Unix, they are bytes strings. */
835 PyObject *putenv_dict;
836#endif
Eddie Elizondob3966632019-11-05 07:16:14 -0800837 PyObject *DirEntryType;
838 PyObject *ScandirIteratorType;
839#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
840 PyObject *SchedParamType;
841#endif
842 PyObject *StatResultType;
843 PyObject *StatVFSResultType;
844 PyObject *TerminalSizeType;
845 PyObject *TimesResultType;
846 PyObject *UnameResultType;
847#if defined(HAVE_WAITID) && !defined(__APPLE__)
848 PyObject *WaitidResultType;
849#endif
850#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
851 PyObject *struct_rusage;
852#endif
853 PyObject *st_mode;
854} _posixstate;
855
856static struct PyModuleDef posixmodule;
857
858#define _posixstate(o) ((_posixstate *)PyModule_GetState(o))
859#define _posixstate_global ((_posixstate *)PyModule_GetState(PyState_FindModule(&posixmodule)))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700860
Larry Hastings9cf065c2012-06-22 16:30:09 -0700861/*
862 * A PyArg_ParseTuple "converter" function
863 * that handles filesystem paths in the manner
864 * preferred by the os module.
865 *
866 * path_converter accepts (Unicode) strings and their
867 * subclasses, and bytes and their subclasses. What
868 * it does with the argument depends on the platform:
869 *
870 * * On Windows, if we get a (Unicode) string we
871 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700872 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700873 *
874 * * On all other platforms, strings are encoded
875 * to bytes using PyUnicode_FSConverter, then we
876 * extract the char * from the bytes object and
877 * return that.
878 *
879 * path_converter also optionally accepts signed
880 * integers (representing open file descriptors) instead
881 * of path strings.
882 *
883 * Input fields:
884 * path.nullable
885 * If nonzero, the path is permitted to be None.
886 * path.allow_fd
887 * If nonzero, the path is permitted to be a file handle
888 * (a signed int) instead of a string.
889 * path.function_name
890 * If non-NULL, path_converter will use that as the name
891 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700892 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700893 * path.argument_name
894 * If non-NULL, path_converter will use that as the name
895 * of the parameter in error messages.
896 * (If path.argument_name is NULL it uses "path".)
897 *
898 * Output fields:
899 * path.wide
900 * Points to the path if it was expressed as Unicode
901 * and was not encoded. (Only used on Windows.)
902 * path.narrow
903 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700904 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000905 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700906 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700907 * path.fd
908 * Contains a file descriptor if path.accept_fd was true
909 * and the caller provided a signed integer instead of any
910 * sort of string.
911 *
912 * WARNING: if your "path" parameter is optional, and is
913 * unspecified, path_converter will never get called.
914 * So if you set allow_fd, you *MUST* initialize path.fd = -1
915 * yourself!
916 * path.length
917 * The length of the path in characters, if specified as
918 * a string.
919 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800920 * The original object passed in (if get a PathLike object,
921 * the result of PyOS_FSPath() is treated as the original object).
922 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700923 * path.cleanup
924 * For internal use only. May point to a temporary object.
925 * (Pay no attention to the man behind the curtain.)
926 *
927 * At most one of path.wide or path.narrow will be non-NULL.
928 * If path was None and path.nullable was set,
929 * or if path was an integer and path.allow_fd was set,
930 * both path.wide and path.narrow will be NULL
931 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200932 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933 * path_converter takes care to not write to the path_t
934 * unless it's successful. However it must reset the
935 * "cleanup" field each time it's called.
936 *
937 * Use as follows:
938 * path_t path;
939 * memset(&path, 0, sizeof(path));
940 * PyArg_ParseTuple(args, "O&", path_converter, &path);
941 * // ... use values from path ...
942 * path_cleanup(&path);
943 *
944 * (Note that if PyArg_Parse fails you don't need to call
945 * path_cleanup(). However it is safe to do so.)
946 */
947typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100948 const char *function_name;
949 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700950 int nullable;
951 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300952 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700953#ifdef MS_WINDOWS
954 BOOL narrow;
955#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300956 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700957#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700958 int fd;
959 Py_ssize_t length;
960 PyObject *object;
961 PyObject *cleanup;
962} path_t;
963
Steve Dowercc16be82016-09-08 10:35:16 -0700964#ifdef MS_WINDOWS
965#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
966 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
967#else
Larry Hastings2f936352014-08-05 14:04:04 +1000968#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
969 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700970#endif
Larry Hastings31826802013-10-19 00:09:25 -0700971
Larry Hastings9cf065c2012-06-22 16:30:09 -0700972static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800973path_cleanup(path_t *path)
974{
975 Py_CLEAR(path->object);
976 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700977}
978
979static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300980path_converter(PyObject *o, void *p)
981{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700982 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800983 PyObject *bytes = NULL;
984 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700985 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300986 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700987#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800988 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700989 const wchar_t *wide;
990#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700991
992#define FORMAT_EXCEPTION(exc, fmt) \
993 PyErr_Format(exc, "%s%s" fmt, \
994 path->function_name ? path->function_name : "", \
995 path->function_name ? ": " : "", \
996 path->argument_name ? path->argument_name : "path")
997
998 /* Py_CLEANUP_SUPPORTED support */
999 if (o == NULL) {
1000 path_cleanup(path);
1001 return 1;
1002 }
1003
Brett Cannon3f9183b2016-08-26 14:44:48 -07001004 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +08001005 path->object = path->cleanup = NULL;
1006 /* path->object owns a reference to the original object */
1007 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001008
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001009 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001010 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001011#ifdef MS_WINDOWS
1012 path->narrow = FALSE;
1013#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001014 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001015#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001016 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001017 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001018 }
1019
Brett Cannon3f9183b2016-08-26 14:44:48 -07001020 /* Only call this here so that we don't treat the return value of
1021 os.fspath() as an fd or buffer. */
1022 is_index = path->allow_fd && PyIndex_Check(o);
1023 is_buffer = PyObject_CheckBuffer(o);
1024 is_bytes = PyBytes_Check(o);
1025 is_unicode = PyUnicode_Check(o);
1026
1027 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
1028 /* Inline PyOS_FSPath() for better error messages. */
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001029 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001030
1031 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1032 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001033 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001034 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001035 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001036 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001037 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001038 goto error_exit;
1039 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001040 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001041 is_unicode = 1;
1042 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001043 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001044 is_bytes = 1;
1045 }
1046 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001047 PyErr_Format(PyExc_TypeError,
1048 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -08001049 "not %.200s", _PyType_Name(Py_TYPE(o)),
1050 _PyType_Name(Py_TYPE(res)));
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001051 Py_DECREF(res);
1052 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001053 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001054
1055 /* still owns a reference to the original object */
1056 Py_DECREF(o);
1057 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001058 }
1059
1060 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001061#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001062 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001063 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001064 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001065 }
Victor Stinner59799a82013-11-13 14:17:30 +01001066 if (length > 32767) {
1067 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001068 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001069 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001070 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001071 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001072 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001073 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001074
1075 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001076 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001077 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001078 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001079#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001080 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001081 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001082 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001083#endif
1084 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001085 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001086 bytes = o;
1087 Py_INCREF(bytes);
1088 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001089 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001090 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001091 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001092 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1093 "%s%s%s should be %s, not %.200s",
1094 path->function_name ? path->function_name : "",
1095 path->function_name ? ": " : "",
1096 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001097 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1098 "integer or None" :
1099 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1100 path->nullable ? "string, bytes, os.PathLike or None" :
1101 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001102 _PyType_Name(Py_TYPE(o)))) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001103 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001104 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001105 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001106 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001107 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001108 }
1109 }
Steve Dowercc16be82016-09-08 10:35:16 -07001110 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001111 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001112 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001113 }
1114 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001115#ifdef MS_WINDOWS
1116 path->narrow = FALSE;
1117#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001118 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001119#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001120 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001121 }
1122 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001123 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001124 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1125 path->function_name ? path->function_name : "",
1126 path->function_name ? ": " : "",
1127 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001128 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1129 "integer or None" :
1130 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1131 path->nullable ? "string, bytes, os.PathLike or None" :
1132 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001133 _PyType_Name(Py_TYPE(o)));
Xiang Zhang04316c42017-01-08 23:26:57 +08001134 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001135 }
1136
Larry Hastings9cf065c2012-06-22 16:30:09 -07001137 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001138 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001139 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001140 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001141 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001142 }
1143
Steve Dowercc16be82016-09-08 10:35:16 -07001144#ifdef MS_WINDOWS
1145 wo = PyUnicode_DecodeFSDefaultAndSize(
1146 narrow,
1147 length
1148 );
1149 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001150 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001151 }
1152
Xiang Zhang04316c42017-01-08 23:26:57 +08001153 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001154 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001155 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001156 }
1157 if (length > 32767) {
1158 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001159 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001160 }
1161 if (wcslen(wide) != length) {
1162 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001163 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001164 }
1165 path->wide = wide;
1166 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001167 path->cleanup = wo;
1168 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001169#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001170 path->wide = NULL;
1171 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001172 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001173 /* Still a reference owned by path->object, don't have to
1174 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001175 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001176 }
1177 else {
1178 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001179 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001180#endif
1181 path->fd = -1;
1182
1183 success_exit:
1184 path->length = length;
1185 path->object = o;
1186 return Py_CLEANUP_SUPPORTED;
1187
1188 error_exit:
1189 Py_XDECREF(o);
1190 Py_XDECREF(bytes);
1191#ifdef MS_WINDOWS
1192 Py_XDECREF(wo);
1193#endif
1194 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001195}
1196
1197static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001198argument_unavailable_error(const char *function_name, const char *argument_name)
1199{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001200 PyErr_Format(PyExc_NotImplementedError,
1201 "%s%s%s unavailable on this platform",
1202 (function_name != NULL) ? function_name : "",
1203 (function_name != NULL) ? ": ": "",
1204 argument_name);
1205}
1206
1207static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001208dir_fd_unavailable(PyObject *o, void *p)
1209{
1210 int dir_fd;
1211 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001212 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001213 if (dir_fd != DEFAULT_DIR_FD) {
1214 argument_unavailable_error(NULL, "dir_fd");
1215 return 0;
1216 }
1217 *(int *)p = dir_fd;
1218 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219}
1220
1221static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001222fd_specified(const char *function_name, int fd)
1223{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001224 if (fd == -1)
1225 return 0;
1226
1227 argument_unavailable_error(function_name, "fd");
1228 return 1;
1229}
1230
1231static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001232follow_symlinks_specified(const char *function_name, int follow_symlinks)
1233{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001234 if (follow_symlinks)
1235 return 0;
1236
1237 argument_unavailable_error(function_name, "follow_symlinks");
1238 return 1;
1239}
1240
1241static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001242path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1243{
Steve Dowercc16be82016-09-08 10:35:16 -07001244 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1245#ifndef MS_WINDOWS
1246 && !path->narrow
1247#endif
1248 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001249 PyErr_Format(PyExc_ValueError,
1250 "%s: can't specify dir_fd without matching path",
1251 function_name);
1252 return 1;
1253 }
1254 return 0;
1255}
1256
1257static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001258dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1259{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001260 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1261 PyErr_Format(PyExc_ValueError,
1262 "%s: can't specify both dir_fd and fd",
1263 function_name);
1264 return 1;
1265 }
1266 return 0;
1267}
1268
1269static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001270fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1271 int follow_symlinks)
1272{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001273 if ((fd > 0) && (!follow_symlinks)) {
1274 PyErr_Format(PyExc_ValueError,
1275 "%s: cannot use fd and follow_symlinks together",
1276 function_name);
1277 return 1;
1278 }
1279 return 0;
1280}
1281
1282static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001283dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1284 int follow_symlinks)
1285{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001286 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1287 PyErr_Format(PyExc_ValueError,
1288 "%s: cannot use dir_fd and follow_symlinks together",
1289 function_name);
1290 return 1;
1291 }
1292 return 0;
1293}
1294
Larry Hastings2f936352014-08-05 14:04:04 +10001295#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001296 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001297#else
Larry Hastings2f936352014-08-05 14:04:04 +10001298 typedef off_t Py_off_t;
1299#endif
1300
1301static int
1302Py_off_t_converter(PyObject *arg, void *addr)
1303{
1304#ifdef HAVE_LARGEFILE_SUPPORT
1305 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1306#else
1307 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001308#endif
1309 if (PyErr_Occurred())
1310 return 0;
1311 return 1;
1312}
Larry Hastings2f936352014-08-05 14:04:04 +10001313
1314static PyObject *
1315PyLong_FromPy_off_t(Py_off_t offset)
1316{
1317#ifdef HAVE_LARGEFILE_SUPPORT
1318 return PyLong_FromLongLong(offset);
1319#else
1320 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001321#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001322}
1323
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001324#ifdef HAVE_SIGSET_T
1325/* Convert an iterable of integers to a sigset.
1326 Return 1 on success, return 0 and raise an exception on error. */
1327int
1328_Py_Sigset_Converter(PyObject *obj, void *addr)
1329{
1330 sigset_t *mask = (sigset_t *)addr;
1331 PyObject *iterator, *item;
1332 long signum;
1333 int overflow;
1334
Rémi Lapeyref0900192019-05-04 01:30:53 +02001335 // The extra parens suppress the unreachable-code warning with clang on MacOS
1336 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001337 /* Probably only if mask == NULL. */
1338 PyErr_SetFromErrno(PyExc_OSError);
1339 return 0;
1340 }
1341
1342 iterator = PyObject_GetIter(obj);
1343 if (iterator == NULL) {
1344 return 0;
1345 }
1346
1347 while ((item = PyIter_Next(iterator)) != NULL) {
1348 signum = PyLong_AsLongAndOverflow(item, &overflow);
1349 Py_DECREF(item);
1350 if (signum <= 0 || signum >= NSIG) {
1351 if (overflow || signum != -1 || !PyErr_Occurred()) {
1352 PyErr_Format(PyExc_ValueError,
1353 "signal number %ld out of range", signum);
1354 }
1355 goto error;
1356 }
1357 if (sigaddset(mask, (int)signum)) {
1358 if (errno != EINVAL) {
1359 /* Probably impossible */
1360 PyErr_SetFromErrno(PyExc_OSError);
1361 goto error;
1362 }
1363 /* For backwards compatibility, allow idioms such as
1364 * `range(1, NSIG)` but warn about invalid signal numbers
1365 */
1366 const char msg[] =
1367 "invalid signal number %ld, please use valid_signals()";
1368 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1369 goto error;
1370 }
1371 }
1372 }
1373 if (!PyErr_Occurred()) {
1374 Py_DECREF(iterator);
1375 return 1;
1376 }
1377
1378error:
1379 Py_DECREF(iterator);
1380 return 0;
1381}
1382#endif /* HAVE_SIGSET_T */
1383
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001384#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001385
1386static int
Brian Curtind25aef52011-06-13 15:16:04 -05001387win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001388{
Martin Panter70214ad2016-08-04 02:38:59 +00001389 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1390 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001391 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001392
1393 if (0 == DeviceIoControl(
1394 reparse_point_handle,
1395 FSCTL_GET_REPARSE_POINT,
1396 NULL, 0, /* in buffer */
1397 target_buffer, sizeof(target_buffer),
1398 &n_bytes_returned,
1399 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001400 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001401
1402 if (reparse_tag)
1403 *reparse_tag = rdb->ReparseTag;
1404
Brian Curtind25aef52011-06-13 15:16:04 -05001405 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001406}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001407
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001408#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001409
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001410/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001411#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001412/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001413** environ directly, we must obtain it with _NSGetEnviron(). See also
1414** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001415*/
1416#include <crt_externs.h>
pxinwrf2d7ac72019-05-21 18:46:37 +08001417#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001418extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001419#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001420
Barry Warsaw53699e91996-12-10 23:23:01 +00001421static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001422convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001423{
Victor Stinner8c62be82010-05-06 00:08:46 +00001424 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001425#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001426 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001427#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001428 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001429#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001430
Victor Stinner8c62be82010-05-06 00:08:46 +00001431 d = PyDict_New();
1432 if (d == NULL)
1433 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001434#ifdef MS_WINDOWS
1435 /* _wenviron must be initialized in this way if the program is started
1436 through main() instead of wmain(). */
1437 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001438 e = _wenviron;
Benoit Hudson723f71a2019-12-06 14:15:03 -05001439#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1440 /* environ is not accessible as an extern in a shared object on OSX; use
1441 _NSGetEnviron to resolve it. The value changes if you add environment
1442 variables between calls to Py_Initialize, so don't cache the value. */
1443 e = *_NSGetEnviron();
Victor Stinner8c62be82010-05-06 00:08:46 +00001444#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001445 e = environ;
1446#endif
1447 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001448 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001449 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001450 PyObject *k;
1451 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001452#ifdef MS_WINDOWS
1453 const wchar_t *p = wcschr(*e, L'=');
1454#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001455 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001456#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001457 if (p == NULL)
1458 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001459#ifdef MS_WINDOWS
1460 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1461#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001462 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001463#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001464 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001465 Py_DECREF(d);
1466 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001467 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001468#ifdef MS_WINDOWS
1469 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1470#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001471 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001472#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001473 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001474 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001475 Py_DECREF(d);
1476 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001477 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001478 if (PyDict_GetItemWithError(d, k) == NULL) {
1479 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1480 Py_DECREF(v);
1481 Py_DECREF(k);
1482 Py_DECREF(d);
1483 return NULL;
1484 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001485 }
1486 Py_DECREF(k);
1487 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001488 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001489 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001490}
1491
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001492/* Set a POSIX-specific error from errno, and return NULL */
1493
Barry Warsawd58d7641998-07-23 16:14:40 +00001494static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001495posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001496{
Victor Stinner8c62be82010-05-06 00:08:46 +00001497 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001498}
Mark Hammondef8b6542001-05-13 08:04:26 +00001499
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001500#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001501static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001502win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001503{
Victor Stinner8c62be82010-05-06 00:08:46 +00001504 /* XXX We should pass the function name along in the future.
1505 (winreg.c also wants to pass the function name.)
1506 This would however require an additional param to the
1507 Windows error object, which is non-trivial.
1508 */
1509 errno = GetLastError();
1510 if (filename)
1511 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1512 else
1513 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001514}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001515
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001516static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001517win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001518{
1519 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001520 if (filename)
1521 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001522 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001523 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001524 filename);
1525 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001526 return PyErr_SetFromWindowsErr(err);
1527}
1528
1529static PyObject *
1530win32_error_object(const char* function, PyObject* filename)
1531{
1532 errno = GetLastError();
1533 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001534}
1535
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001536#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001537
Larry Hastings9cf065c2012-06-22 16:30:09 -07001538static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001539posix_path_object_error(PyObject *path)
1540{
1541 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1542}
1543
1544static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001545path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001546{
1547#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001548 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1549 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001550#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001551 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001552#endif
1553}
1554
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001555static PyObject *
1556path_object_error2(PyObject *path, PyObject *path2)
1557{
1558#ifdef MS_WINDOWS
1559 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1560 PyExc_OSError, 0, path, path2);
1561#else
1562 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1563#endif
1564}
1565
1566static PyObject *
1567path_error(path_t *path)
1568{
1569 return path_object_error(path->object);
1570}
Larry Hastings31826802013-10-19 00:09:25 -07001571
Larry Hastingsb0827312014-02-09 22:05:19 -08001572static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001573posix_path_error(path_t *path)
1574{
1575 return posix_path_object_error(path->object);
1576}
1577
1578static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001579path_error2(path_t *path, path_t *path2)
1580{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001581 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001582}
1583
1584
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001585/* POSIX generic methods */
1586
Larry Hastings2f936352014-08-05 14:04:04 +10001587static int
1588fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001589{
Victor Stinner8c62be82010-05-06 00:08:46 +00001590 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001591 int *pointer = (int *)p;
1592 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001593 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001594 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001595 *pointer = fd;
1596 return 1;
1597}
1598
1599static PyObject *
1600posix_fildes_fd(int fd, int (*func)(int))
1601{
1602 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001603 int async_err = 0;
1604
1605 do {
1606 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001607 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001608 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001609 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001610 Py_END_ALLOW_THREADS
1611 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1612 if (res != 0)
1613 return (!async_err) ? posix_error() : NULL;
1614 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001615}
Guido van Rossum21142a01999-01-08 21:05:37 +00001616
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001617
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001618#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001619/* This is a reimplementation of the C library's chdir function,
1620 but one that produces Win32 errors instead of DOS error codes.
1621 chdir is essentially a wrapper around SetCurrentDirectory; however,
1622 it also needs to set "magic" environment variables indicating
1623 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001624static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001625win32_wchdir(LPCWSTR path)
1626{
Victor Stinnered537822015-12-13 21:40:26 +01001627 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001628 int result;
1629 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001630
Victor Stinner8c62be82010-05-06 00:08:46 +00001631 if(!SetCurrentDirectoryW(path))
1632 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001633 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001634 if (!result)
1635 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001636 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001637 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001638 if (!new_path) {
1639 SetLastError(ERROR_OUTOFMEMORY);
1640 return FALSE;
1641 }
1642 result = GetCurrentDirectoryW(result, new_path);
1643 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001644 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001645 return FALSE;
1646 }
1647 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001648 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1649 wcsncmp(new_path, L"//", 2) == 0);
1650 if (!is_unc_like_path) {
1651 env[1] = new_path[0];
1652 result = SetEnvironmentVariableW(env, new_path);
1653 }
Victor Stinnered537822015-12-13 21:40:26 +01001654 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001655 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001656 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001657}
1658#endif
1659
Martin v. Löwis14694662006-02-03 12:54:16 +00001660#ifdef MS_WINDOWS
1661/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1662 - time stamps are restricted to second resolution
1663 - file modification times suffer from forth-and-back conversions between
1664 UTC and local time
1665 Therefore, we implement our own stat, based on the Win32 API directly.
1666*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001667#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001668#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001669#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001670
Victor Stinner6036e442015-03-08 01:58:04 +01001671static void
Steve Dowercc16be82016-09-08 10:35:16 -07001672find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1673 BY_HANDLE_FILE_INFORMATION *info,
1674 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001675{
1676 memset(info, 0, sizeof(*info));
1677 info->dwFileAttributes = pFileData->dwFileAttributes;
1678 info->ftCreationTime = pFileData->ftCreationTime;
1679 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1680 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1681 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1682 info->nFileSizeLow = pFileData->nFileSizeLow;
1683/* info->nNumberOfLinks = 1; */
1684 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1685 *reparse_tag = pFileData->dwReserved0;
1686 else
1687 *reparse_tag = 0;
1688}
1689
Guido van Rossumd8faa362007-04-27 19:54:29 +00001690static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001691attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001692{
Victor Stinner8c62be82010-05-06 00:08:46 +00001693 HANDLE hFindFile;
1694 WIN32_FIND_DATAW FileData;
1695 hFindFile = FindFirstFileW(pszFile, &FileData);
1696 if (hFindFile == INVALID_HANDLE_VALUE)
1697 return FALSE;
1698 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001699 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001700 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001701}
1702
Brian Curtind25aef52011-06-13 15:16:04 -05001703static int
Steve Dowercc16be82016-09-08 10:35:16 -07001704win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001705 BOOL traverse)
1706{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001707 HANDLE hFile;
1708 BY_HANDLE_FILE_INFORMATION fileInfo;
1709 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1710 DWORD fileType, error;
1711 BOOL isUnhandledTag = FALSE;
1712 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001713
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001714 DWORD access = FILE_READ_ATTRIBUTES;
1715 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1716 if (!traverse) {
1717 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1718 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001719
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001720 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001721 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001722 /* Either the path doesn't exist, or the caller lacks access. */
1723 error = GetLastError();
1724 switch (error) {
1725 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1726 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1727 /* Try reading the parent directory. */
1728 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1729 /* Cannot read the parent directory. */
1730 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001731 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001732 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001733 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1734 if (traverse ||
1735 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1736 /* The stat call has to traverse but cannot, so fail. */
1737 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001738 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001739 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001740 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001741 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001742
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001743 case ERROR_INVALID_PARAMETER:
1744 /* \\.\con requires read or write access. */
1745 hFile = CreateFileW(path, access | GENERIC_READ,
1746 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1747 OPEN_EXISTING, flags, NULL);
1748 if (hFile == INVALID_HANDLE_VALUE) {
1749 SetLastError(error);
1750 return -1;
1751 }
1752 break;
1753
1754 case ERROR_CANT_ACCESS_FILE:
1755 /* bpo37834: open unhandled reparse points if traverse fails. */
1756 if (traverse) {
1757 traverse = FALSE;
1758 isUnhandledTag = TRUE;
1759 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1760 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1761 }
1762 if (hFile == INVALID_HANDLE_VALUE) {
1763 SetLastError(error);
1764 return -1;
1765 }
1766 break;
1767
1768 default:
1769 return -1;
1770 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001771 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001772
1773 if (hFile != INVALID_HANDLE_VALUE) {
1774 /* Handle types other than files on disk. */
1775 fileType = GetFileType(hFile);
1776 if (fileType != FILE_TYPE_DISK) {
1777 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1778 retval = -1;
1779 goto cleanup;
1780 }
1781 DWORD fileAttributes = GetFileAttributesW(path);
1782 memset(result, 0, sizeof(*result));
1783 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1784 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1785 /* \\.\pipe\ or \\.\mailslot\ */
1786 result->st_mode = _S_IFDIR;
1787 } else if (fileType == FILE_TYPE_CHAR) {
1788 /* \\.\nul */
1789 result->st_mode = _S_IFCHR;
1790 } else if (fileType == FILE_TYPE_PIPE) {
1791 /* \\.\pipe\spam */
1792 result->st_mode = _S_IFIFO;
1793 }
1794 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1795 goto cleanup;
1796 }
1797
1798 /* Query the reparse tag, and traverse a non-link. */
1799 if (!traverse) {
1800 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1801 &tagInfo, sizeof(tagInfo))) {
1802 /* Allow devices that do not support FileAttributeTagInfo. */
1803 switch (GetLastError()) {
1804 case ERROR_INVALID_PARAMETER:
1805 case ERROR_INVALID_FUNCTION:
1806 case ERROR_NOT_SUPPORTED:
1807 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1808 tagInfo.ReparseTag = 0;
1809 break;
1810 default:
1811 retval = -1;
1812 goto cleanup;
1813 }
1814 } else if (tagInfo.FileAttributes &
1815 FILE_ATTRIBUTE_REPARSE_POINT) {
1816 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1817 if (isUnhandledTag) {
1818 /* Traversing previously failed for either this link
1819 or its target. */
1820 SetLastError(ERROR_CANT_ACCESS_FILE);
1821 retval = -1;
1822 goto cleanup;
1823 }
1824 /* Traverse a non-link, but not if traversing already failed
1825 for an unhandled tag. */
1826 } else if (!isUnhandledTag) {
1827 CloseHandle(hFile);
1828 return win32_xstat_impl(path, result, TRUE);
1829 }
1830 }
1831 }
1832
1833 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
1834 switch (GetLastError()) {
1835 case ERROR_INVALID_PARAMETER:
1836 case ERROR_INVALID_FUNCTION:
1837 case ERROR_NOT_SUPPORTED:
Steve Dower772ec0f2019-09-04 14:42:54 -07001838 /* Volumes and physical disks are block devices, e.g.
1839 \\.\C: and \\.\PhysicalDrive0. */
1840 memset(result, 0, sizeof(*result));
1841 result->st_mode = 0x6000; /* S_IFBLK */
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001842 goto cleanup;
1843 }
Steve Dower772ec0f2019-09-04 14:42:54 -07001844 retval = -1;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001845 goto cleanup;
1846 }
1847 }
1848
1849 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
1850
1851 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
1852 /* Fix the file execute permissions. This hack sets S_IEXEC if
1853 the filename has an extension that is commonly used by files
1854 that CreateProcessW can execute. A real implementation calls
1855 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
1856 AccessCheck to check for generic read, write, and execute
1857 access. */
1858 const wchar_t *fileExtension = wcsrchr(path, '.');
1859 if (fileExtension) {
1860 if (_wcsicmp(fileExtension, L".exe") == 0 ||
1861 _wcsicmp(fileExtension, L".bat") == 0 ||
1862 _wcsicmp(fileExtension, L".cmd") == 0 ||
1863 _wcsicmp(fileExtension, L".com") == 0) {
1864 result->st_mode |= 0111;
1865 }
1866 }
1867 }
1868
1869cleanup:
1870 if (hFile != INVALID_HANDLE_VALUE) {
Steve Dower772ec0f2019-09-04 14:42:54 -07001871 /* Preserve last error if we are failing */
1872 error = retval ? GetLastError() : 0;
1873 if (!CloseHandle(hFile)) {
1874 retval = -1;
1875 } else if (retval) {
1876 /* Restore last error */
1877 SetLastError(error);
1878 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001879 }
1880
1881 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001882}
1883
1884static int
Steve Dowercc16be82016-09-08 10:35:16 -07001885win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001886{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001887 /* Protocol violation: we explicitly clear errno, instead of
1888 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001889 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001890 errno = 0;
1891 return code;
1892}
Brian Curtind25aef52011-06-13 15:16:04 -05001893/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001894
1895 In Posix, stat automatically traverses symlinks and returns the stat
1896 structure for the target. In Windows, the equivalent GetFileAttributes by
1897 default does not traverse symlinks and instead returns attributes for
1898 the symlink.
1899
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001900 Instead, we will open the file (which *does* traverse symlinks by default)
1901 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00001902
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001903static int
Steve Dowercc16be82016-09-08 10:35:16 -07001904win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001905{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001906 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001907}
1908
Victor Stinner8c62be82010-05-06 00:08:46 +00001909static int
Steve Dowercc16be82016-09-08 10:35:16 -07001910win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001911{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001912 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001913}
1914
Martin v. Löwis14694662006-02-03 12:54:16 +00001915#endif /* MS_WINDOWS */
1916
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001917PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001918"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001919This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001920 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001921or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1922\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001923Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1924or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001925\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001926See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001927
1928static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 {"st_mode", "protection bits"},
1930 {"st_ino", "inode"},
1931 {"st_dev", "device"},
1932 {"st_nlink", "number of hard links"},
1933 {"st_uid", "user ID of owner"},
1934 {"st_gid", "group ID of owner"},
1935 {"st_size", "total size, in bytes"},
1936 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1937 {NULL, "integer time of last access"},
1938 {NULL, "integer time of last modification"},
1939 {NULL, "integer time of last change"},
1940 {"st_atime", "time of last access"},
1941 {"st_mtime", "time of last modification"},
1942 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001943 {"st_atime_ns", "time of last access in nanoseconds"},
1944 {"st_mtime_ns", "time of last modification in nanoseconds"},
1945 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001946#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001947 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001948#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001949#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001950 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001951#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001952#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001953 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001954#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001955#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001956 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001957#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001958#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001959 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001960#endif
1961#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001963#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001964#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1965 {"st_file_attributes", "Windows file attribute bits"},
1966#endif
jcea6c51d512018-01-28 14:00:08 +01001967#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1968 {"st_fstype", "Type of filesystem"},
1969#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001970#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
1971 {"st_reparse_tag", "Windows reparse tag"},
1972#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001973 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001974};
1975
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001976#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001977#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001978#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001979#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001980#endif
1981
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001982#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001983#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1984#else
1985#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1986#endif
1987
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001988#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001989#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1990#else
1991#define ST_RDEV_IDX ST_BLOCKS_IDX
1992#endif
1993
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001994#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1995#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1996#else
1997#define ST_FLAGS_IDX ST_RDEV_IDX
1998#endif
1999
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002000#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002001#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002002#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002003#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002004#endif
2005
2006#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2007#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2008#else
2009#define ST_BIRTHTIME_IDX ST_GEN_IDX
2010#endif
2011
Zachary Ware63f277b2014-06-19 09:46:37 -05002012#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2013#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
2014#else
2015#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2016#endif
2017
jcea6c51d512018-01-28 14:00:08 +01002018#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2019#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2020#else
2021#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2022#endif
2023
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002024#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2025#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2026#else
2027#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2028#endif
2029
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002030static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 "stat_result", /* name */
2032 stat_result__doc__, /* doc */
2033 stat_result_fields,
2034 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002035};
2036
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002037PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002038"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2039This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002040 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002041or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002042\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002043See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002044
2045static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002046 {"f_bsize", },
2047 {"f_frsize", },
2048 {"f_blocks", },
2049 {"f_bfree", },
2050 {"f_bavail", },
2051 {"f_files", },
2052 {"f_ffree", },
2053 {"f_favail", },
2054 {"f_flag", },
2055 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002056 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002057 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002058};
2059
2060static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002061 "statvfs_result", /* name */
2062 statvfs_result__doc__, /* doc */
2063 statvfs_result_fields,
2064 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002065};
2066
Ross Lagerwall7807c352011-03-17 20:20:30 +02002067#if defined(HAVE_WAITID) && !defined(__APPLE__)
2068PyDoc_STRVAR(waitid_result__doc__,
2069"waitid_result: Result from waitid.\n\n\
2070This object may be accessed either as a tuple of\n\
2071 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2072or via the attributes si_pid, si_uid, and so on.\n\
2073\n\
2074See os.waitid for more information.");
2075
2076static PyStructSequence_Field waitid_result_fields[] = {
2077 {"si_pid", },
2078 {"si_uid", },
2079 {"si_signo", },
2080 {"si_status", },
2081 {"si_code", },
2082 {0}
2083};
2084
2085static PyStructSequence_Desc waitid_result_desc = {
2086 "waitid_result", /* name */
2087 waitid_result__doc__, /* doc */
2088 waitid_result_fields,
2089 5
2090};
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002091#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002092static newfunc structseq_new;
2093
2094static PyObject *
2095statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2096{
Victor Stinner8c62be82010-05-06 00:08:46 +00002097 PyStructSequence *result;
2098 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002099
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 result = (PyStructSequence*)structseq_new(type, args, kwds);
2101 if (!result)
2102 return NULL;
2103 /* If we have been initialized from a tuple,
2104 st_?time might be set to None. Initialize it
2105 from the int slots. */
2106 for (i = 7; i <= 9; i++) {
2107 if (result->ob_item[i+3] == Py_None) {
2108 Py_DECREF(Py_None);
2109 Py_INCREF(result->ob_item[i]);
2110 result->ob_item[i+3] = result->ob_item[i];
2111 }
2112 }
2113 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002114}
2115
Eddie Elizondob3966632019-11-05 07:16:14 -08002116static int
2117_posix_clear(PyObject *module)
2118{
2119 Py_CLEAR(_posixstate(module)->billion);
Victor Stinner623ed612020-01-21 19:25:32 +01002120#ifdef PY_PUTENV_DICT
2121 Py_CLEAR(_posixstate(module)->putenv_dict);
2122#endif
Eddie Elizondob3966632019-11-05 07:16:14 -08002123 Py_CLEAR(_posixstate(module)->DirEntryType);
2124 Py_CLEAR(_posixstate(module)->ScandirIteratorType);
2125#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
2126 Py_CLEAR(_posixstate(module)->SchedParamType);
2127#endif
2128 Py_CLEAR(_posixstate(module)->StatResultType);
2129 Py_CLEAR(_posixstate(module)->StatVFSResultType);
2130 Py_CLEAR(_posixstate(module)->TerminalSizeType);
2131 Py_CLEAR(_posixstate(module)->TimesResultType);
2132 Py_CLEAR(_posixstate(module)->UnameResultType);
2133#if defined(HAVE_WAITID) && !defined(__APPLE__)
2134 Py_CLEAR(_posixstate(module)->WaitidResultType);
2135#endif
2136#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
2137 Py_CLEAR(_posixstate(module)->struct_rusage);
2138#endif
2139 Py_CLEAR(_posixstate(module)->st_mode);
2140 return 0;
2141}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002142
Eddie Elizondob3966632019-11-05 07:16:14 -08002143static int
2144_posix_traverse(PyObject *module, visitproc visit, void *arg)
2145{
2146 Py_VISIT(_posixstate(module)->billion);
Victor Stinner623ed612020-01-21 19:25:32 +01002147#ifdef PY_PUTENV_DICT
2148 Py_VISIT(_posixstate(module)->putenv_dict);
2149#endif
Eddie Elizondob3966632019-11-05 07:16:14 -08002150 Py_VISIT(_posixstate(module)->DirEntryType);
2151 Py_VISIT(_posixstate(module)->ScandirIteratorType);
2152#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
2153 Py_VISIT(_posixstate(module)->SchedParamType);
2154#endif
2155 Py_VISIT(_posixstate(module)->StatResultType);
2156 Py_VISIT(_posixstate(module)->StatVFSResultType);
2157 Py_VISIT(_posixstate(module)->TerminalSizeType);
2158 Py_VISIT(_posixstate(module)->TimesResultType);
2159 Py_VISIT(_posixstate(module)->UnameResultType);
2160#if defined(HAVE_WAITID) && !defined(__APPLE__)
2161 Py_VISIT(_posixstate(module)->WaitidResultType);
2162#endif
2163#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
2164 Py_VISIT(_posixstate(module)->struct_rusage);
2165#endif
2166 Py_VISIT(_posixstate(module)->st_mode);
2167 return 0;
2168}
2169
2170static void
2171_posix_free(void *module)
2172{
2173 _posix_clear((PyObject *)module);
2174}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002175
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002176static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002177fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002178{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002179 PyObject *s = _PyLong_FromTime_t(sec);
2180 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2181 PyObject *s_in_ns = NULL;
2182 PyObject *ns_total = NULL;
2183 PyObject *float_s = NULL;
2184
2185 if (!(s && ns_fractional))
2186 goto exit;
2187
Eddie Elizondob3966632019-11-05 07:16:14 -08002188 s_in_ns = PyNumber_Multiply(s, _posixstate_global->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002189 if (!s_in_ns)
2190 goto exit;
2191
2192 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2193 if (!ns_total)
2194 goto exit;
2195
Victor Stinner01b5aab2017-10-24 02:02:00 -07002196 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2197 if (!float_s) {
2198 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002199 }
2200
2201 PyStructSequence_SET_ITEM(v, index, s);
2202 PyStructSequence_SET_ITEM(v, index+3, float_s);
2203 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2204 s = NULL;
2205 float_s = NULL;
2206 ns_total = NULL;
2207exit:
2208 Py_XDECREF(s);
2209 Py_XDECREF(ns_fractional);
2210 Py_XDECREF(s_in_ns);
2211 Py_XDECREF(ns_total);
2212 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002213}
2214
Tim Peters5aa91602002-01-30 05:46:57 +00002215/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002216 (used by posix_stat() and posix_fstat()) */
2217static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002218_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002219{
Victor Stinner8c62be82010-05-06 00:08:46 +00002220 unsigned long ansec, mnsec, cnsec;
Eddie Elizondob3966632019-11-05 07:16:14 -08002221 PyObject *StatResultType = _posixstate_global->StatResultType;
2222 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002223 if (v == NULL)
2224 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002225
Victor Stinner8c62be82010-05-06 00:08:46 +00002226 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002227 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002228 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002229#ifdef MS_WINDOWS
2230 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002231#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002232 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002233#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002234 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002235#if defined(MS_WINDOWS)
2236 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2237 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2238#else
2239 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2240 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2241#endif
xdegaye50e86032017-05-22 11:15:08 +02002242 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2243 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002244
Martin v. Löwis14694662006-02-03 12:54:16 +00002245#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002246 ansec = st->st_atim.tv_nsec;
2247 mnsec = st->st_mtim.tv_nsec;
2248 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002249#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002250 ansec = st->st_atimespec.tv_nsec;
2251 mnsec = st->st_mtimespec.tv_nsec;
2252 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002253#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002254 ansec = st->st_atime_nsec;
2255 mnsec = st->st_mtime_nsec;
2256 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002257#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002258 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002259#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002260 fill_time(v, 7, st->st_atime, ansec);
2261 fill_time(v, 8, st->st_mtime, mnsec);
2262 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002263
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002264#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002265 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2266 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002267#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002268#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002269 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2270 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002271#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002272#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002273 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2274 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002275#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002276#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002277 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2278 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002279#endif
2280#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002281 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002282 PyObject *val;
2283 unsigned long bsec,bnsec;
2284 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002285#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002286 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002287#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002288 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002289#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002290 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002291 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2292 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002293 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002294#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002295#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002296 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2297 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002298#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002299#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2300 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2301 PyLong_FromUnsignedLong(st->st_file_attributes));
2302#endif
jcea6c51d512018-01-28 14:00:08 +01002303#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2304 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2305 PyUnicode_FromString(st->st_fstype));
2306#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002307#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2308 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2309 PyLong_FromUnsignedLong(st->st_reparse_tag));
2310#endif
Fred Drake699f3522000-06-29 21:12:41 +00002311
Victor Stinner8c62be82010-05-06 00:08:46 +00002312 if (PyErr_Occurred()) {
2313 Py_DECREF(v);
2314 return NULL;
2315 }
Fred Drake699f3522000-06-29 21:12:41 +00002316
Victor Stinner8c62be82010-05-06 00:08:46 +00002317 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002318}
2319
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002320/* POSIX methods */
2321
Guido van Rossum94f6f721999-01-06 18:42:14 +00002322
2323static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002324posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002325 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002326{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002327 STRUCT_STAT st;
2328 int result;
2329
2330#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2331 if (follow_symlinks_specified(function_name, follow_symlinks))
2332 return NULL;
2333#endif
2334
2335 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2336 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2337 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2338 return NULL;
2339
2340 Py_BEGIN_ALLOW_THREADS
2341 if (path->fd != -1)
2342 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002343#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002344 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002345 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002346 else
Steve Dowercc16be82016-09-08 10:35:16 -07002347 result = win32_lstat(path->wide, &st);
2348#else
2349 else
2350#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002351 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2352 result = LSTAT(path->narrow, &st);
2353 else
Steve Dowercc16be82016-09-08 10:35:16 -07002354#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002355#ifdef HAVE_FSTATAT
2356 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2357 result = fstatat(dir_fd, path->narrow, &st,
2358 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2359 else
Steve Dowercc16be82016-09-08 10:35:16 -07002360#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002361 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002362#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002363 Py_END_ALLOW_THREADS
2364
Victor Stinner292c8352012-10-30 02:17:38 +01002365 if (result != 0) {
2366 return path_error(path);
2367 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002368
2369 return _pystat_fromstructstat(&st);
2370}
2371
Larry Hastings2f936352014-08-05 14:04:04 +10002372/*[python input]
2373
2374for s in """
2375
2376FACCESSAT
2377FCHMODAT
2378FCHOWNAT
2379FSTATAT
2380LINKAT
2381MKDIRAT
2382MKFIFOAT
2383MKNODAT
2384OPENAT
2385READLINKAT
2386SYMLINKAT
2387UNLINKAT
2388
2389""".strip().split():
2390 s = s.strip()
2391 print("""
2392#ifdef HAVE_{s}
2393 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002394#else
Larry Hastings2f936352014-08-05 14:04:04 +10002395 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002396#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002397""".rstrip().format(s=s))
2398
2399for s in """
2400
2401FCHDIR
2402FCHMOD
2403FCHOWN
2404FDOPENDIR
2405FEXECVE
2406FPATHCONF
2407FSTATVFS
2408FTRUNCATE
2409
2410""".strip().split():
2411 s = s.strip()
2412 print("""
2413#ifdef HAVE_{s}
2414 #define PATH_HAVE_{s} 1
2415#else
2416 #define PATH_HAVE_{s} 0
2417#endif
2418
2419""".rstrip().format(s=s))
2420[python start generated code]*/
2421
2422#ifdef HAVE_FACCESSAT
2423 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2424#else
2425 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2426#endif
2427
2428#ifdef HAVE_FCHMODAT
2429 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2430#else
2431 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2432#endif
2433
2434#ifdef HAVE_FCHOWNAT
2435 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2436#else
2437 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2438#endif
2439
2440#ifdef HAVE_FSTATAT
2441 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2442#else
2443 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2444#endif
2445
2446#ifdef HAVE_LINKAT
2447 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2448#else
2449 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2450#endif
2451
2452#ifdef HAVE_MKDIRAT
2453 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2454#else
2455 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2456#endif
2457
2458#ifdef HAVE_MKFIFOAT
2459 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2460#else
2461 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2462#endif
2463
2464#ifdef HAVE_MKNODAT
2465 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2466#else
2467 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2468#endif
2469
2470#ifdef HAVE_OPENAT
2471 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2472#else
2473 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2474#endif
2475
2476#ifdef HAVE_READLINKAT
2477 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2478#else
2479 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2480#endif
2481
2482#ifdef HAVE_SYMLINKAT
2483 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2484#else
2485 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2486#endif
2487
2488#ifdef HAVE_UNLINKAT
2489 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2490#else
2491 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2492#endif
2493
2494#ifdef HAVE_FCHDIR
2495 #define PATH_HAVE_FCHDIR 1
2496#else
2497 #define PATH_HAVE_FCHDIR 0
2498#endif
2499
2500#ifdef HAVE_FCHMOD
2501 #define PATH_HAVE_FCHMOD 1
2502#else
2503 #define PATH_HAVE_FCHMOD 0
2504#endif
2505
2506#ifdef HAVE_FCHOWN
2507 #define PATH_HAVE_FCHOWN 1
2508#else
2509 #define PATH_HAVE_FCHOWN 0
2510#endif
2511
2512#ifdef HAVE_FDOPENDIR
2513 #define PATH_HAVE_FDOPENDIR 1
2514#else
2515 #define PATH_HAVE_FDOPENDIR 0
2516#endif
2517
2518#ifdef HAVE_FEXECVE
2519 #define PATH_HAVE_FEXECVE 1
2520#else
2521 #define PATH_HAVE_FEXECVE 0
2522#endif
2523
2524#ifdef HAVE_FPATHCONF
2525 #define PATH_HAVE_FPATHCONF 1
2526#else
2527 #define PATH_HAVE_FPATHCONF 0
2528#endif
2529
2530#ifdef HAVE_FSTATVFS
2531 #define PATH_HAVE_FSTATVFS 1
2532#else
2533 #define PATH_HAVE_FSTATVFS 0
2534#endif
2535
2536#ifdef HAVE_FTRUNCATE
2537 #define PATH_HAVE_FTRUNCATE 1
2538#else
2539 #define PATH_HAVE_FTRUNCATE 0
2540#endif
2541/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002542
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002543#ifdef MS_WINDOWS
2544 #undef PATH_HAVE_FTRUNCATE
2545 #define PATH_HAVE_FTRUNCATE 1
2546#endif
Larry Hastings31826802013-10-19 00:09:25 -07002547
Larry Hastings61272b72014-01-07 12:41:53 -08002548/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002549
2550class path_t_converter(CConverter):
2551
2552 type = "path_t"
2553 impl_by_reference = True
2554 parse_by_reference = True
2555
2556 converter = 'path_converter'
2557
2558 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002559 # right now path_t doesn't support default values.
2560 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002561 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002562 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002563
Larry Hastings2f936352014-08-05 14:04:04 +10002564 if self.c_default not in (None, 'Py_None'):
2565 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002566
2567 self.nullable = nullable
2568 self.allow_fd = allow_fd
2569
Larry Hastings7726ac92014-01-31 22:03:12 -08002570 def pre_render(self):
2571 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002572 if isinstance(value, str):
2573 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002574 return str(int(bool(value)))
2575
2576 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002577 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002578 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002579 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002580 strify(self.nullable),
2581 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002582 )
2583
2584 def cleanup(self):
2585 return "path_cleanup(&" + self.name + ");\n"
2586
2587
2588class dir_fd_converter(CConverter):
2589 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002590
Larry Hastings2f936352014-08-05 14:04:04 +10002591 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002592 if self.default in (unspecified, None):
2593 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002594 if isinstance(requires, str):
2595 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2596 else:
2597 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002598
Larry Hastings2f936352014-08-05 14:04:04 +10002599class fildes_converter(CConverter):
2600 type = 'int'
2601 converter = 'fildes_converter'
2602
2603class uid_t_converter(CConverter):
2604 type = "uid_t"
2605 converter = '_Py_Uid_Converter'
2606
2607class gid_t_converter(CConverter):
2608 type = "gid_t"
2609 converter = '_Py_Gid_Converter'
2610
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002611class dev_t_converter(CConverter):
2612 type = 'dev_t'
2613 converter = '_Py_Dev_Converter'
2614
2615class dev_t_return_converter(unsigned_long_return_converter):
2616 type = 'dev_t'
2617 conversion_fn = '_PyLong_FromDev'
2618 unsigned_cast = '(dev_t)'
2619
Larry Hastings2f936352014-08-05 14:04:04 +10002620class FSConverter_converter(CConverter):
2621 type = 'PyObject *'
2622 converter = 'PyUnicode_FSConverter'
2623 def converter_init(self):
2624 if self.default is not unspecified:
2625 fail("FSConverter_converter does not support default values")
2626 self.c_default = 'NULL'
2627
2628 def cleanup(self):
2629 return "Py_XDECREF(" + self.name + ");\n"
2630
2631class pid_t_converter(CConverter):
2632 type = 'pid_t'
2633 format_unit = '" _Py_PARSE_PID "'
2634
2635class idtype_t_converter(int_converter):
2636 type = 'idtype_t'
2637
2638class id_t_converter(CConverter):
2639 type = 'id_t'
2640 format_unit = '" _Py_PARSE_PID "'
2641
Benjamin Petersonca470632016-09-06 13:47:26 -07002642class intptr_t_converter(CConverter):
2643 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002644 format_unit = '" _Py_PARSE_INTPTR "'
2645
2646class Py_off_t_converter(CConverter):
2647 type = 'Py_off_t'
2648 converter = 'Py_off_t_converter'
2649
2650class Py_off_t_return_converter(long_return_converter):
2651 type = 'Py_off_t'
2652 conversion_fn = 'PyLong_FromPy_off_t'
2653
2654class path_confname_converter(CConverter):
2655 type="int"
2656 converter="conv_path_confname"
2657
2658class confstr_confname_converter(path_confname_converter):
2659 converter='conv_confstr_confname'
2660
2661class sysconf_confname_converter(path_confname_converter):
2662 converter="conv_sysconf_confname"
2663
2664class sched_param_converter(CConverter):
2665 type = 'struct sched_param'
2666 converter = 'convert_sched_param'
2667 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002668
Larry Hastings61272b72014-01-07 12:41:53 -08002669[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002670/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002671
Larry Hastings61272b72014-01-07 12:41:53 -08002672/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002673
Larry Hastings2a727912014-01-16 11:32:01 -08002674os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002675
2676 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002677 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002678 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002679
2680 *
2681
Larry Hastings2f936352014-08-05 14:04:04 +10002682 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002683 If not None, it should be a file descriptor open to a directory,
2684 and path should be a relative string; path will then be relative to
2685 that directory.
2686
2687 follow_symlinks: bool = True
2688 If False, and the last element of the path is a symbolic link,
2689 stat will examine the symbolic link itself instead of the file
2690 the link points to.
2691
2692Perform a stat system call on the given path.
2693
2694dir_fd and follow_symlinks may not be implemented
2695 on your platform. If they are unavailable, using them will raise a
2696 NotImplementedError.
2697
2698It's an error to use dir_fd or follow_symlinks when specifying path as
2699 an open file descriptor.
2700
Larry Hastings61272b72014-01-07 12:41:53 -08002701[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002702
Larry Hastings31826802013-10-19 00:09:25 -07002703static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002704os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002705/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002706{
2707 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2708}
2709
Larry Hastings2f936352014-08-05 14:04:04 +10002710
2711/*[clinic input]
2712os.lstat
2713
2714 path : path_t
2715
2716 *
2717
2718 dir_fd : dir_fd(requires='fstatat') = None
2719
2720Perform a stat system call on the given path, without following symbolic links.
2721
2722Like stat(), but do not follow symbolic links.
2723Equivalent to stat(path, follow_symlinks=False).
2724[clinic start generated code]*/
2725
Larry Hastings2f936352014-08-05 14:04:04 +10002726static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002727os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2728/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002729{
2730 int follow_symlinks = 0;
2731 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2732}
Larry Hastings31826802013-10-19 00:09:25 -07002733
Larry Hastings2f936352014-08-05 14:04:04 +10002734
Larry Hastings61272b72014-01-07 12:41:53 -08002735/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002736os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002737
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002738 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002739 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002740
2741 mode: int
2742 Operating-system mode bitfield. Can be F_OK to test existence,
2743 or the inclusive-OR of R_OK, W_OK, and X_OK.
2744
2745 *
2746
Larry Hastings2f936352014-08-05 14:04:04 +10002747 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002748 If not None, it should be a file descriptor open to a directory,
2749 and path should be relative; path will then be relative to that
2750 directory.
2751
2752 effective_ids: bool = False
2753 If True, access will use the effective uid/gid instead of
2754 the real uid/gid.
2755
2756 follow_symlinks: bool = True
2757 If False, and the last element of the path is a symbolic link,
2758 access will examine the symbolic link itself instead of the file
2759 the link points to.
2760
2761Use the real uid/gid to test for access to a path.
2762
2763{parameters}
2764dir_fd, effective_ids, and follow_symlinks may not be implemented
2765 on your platform. If they are unavailable, using them will raise a
2766 NotImplementedError.
2767
2768Note that most operations will use the effective uid/gid, therefore this
2769 routine can be used in a suid/sgid environment to test if the invoking user
2770 has the specified access to the path.
2771
Larry Hastings61272b72014-01-07 12:41:53 -08002772[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002773
Larry Hastings2f936352014-08-05 14:04:04 +10002774static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002775os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002776 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002777/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002778{
Larry Hastings2f936352014-08-05 14:04:04 +10002779 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002780
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002781#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002782 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002783#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002784 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002785#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002786
Larry Hastings9cf065c2012-06-22 16:30:09 -07002787#ifndef HAVE_FACCESSAT
2788 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002789 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002790
2791 if (effective_ids) {
2792 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002793 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002794 }
2795#endif
2796
2797#ifdef MS_WINDOWS
2798 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002799 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800 Py_END_ALLOW_THREADS
2801
2802 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002803 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002804 * * we didn't get a -1, and
2805 * * write access wasn't requested,
2806 * * or the file isn't read-only,
2807 * * or it's a directory.
2808 * (Directories cannot be read-only on Windows.)
2809 */
Larry Hastings2f936352014-08-05 14:04:04 +10002810 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002811 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002812 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002813 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002814#else
2815
2816 Py_BEGIN_ALLOW_THREADS
2817#ifdef HAVE_FACCESSAT
2818 if ((dir_fd != DEFAULT_DIR_FD) ||
2819 effective_ids ||
2820 !follow_symlinks) {
2821 int flags = 0;
2822 if (!follow_symlinks)
2823 flags |= AT_SYMLINK_NOFOLLOW;
2824 if (effective_ids)
2825 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002826 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002827 }
2828 else
2829#endif
Larry Hastings31826802013-10-19 00:09:25 -07002830 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002832 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002833#endif
2834
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002836}
2837
Guido van Rossumd371ff11999-01-25 16:12:23 +00002838#ifndef F_OK
2839#define F_OK 0
2840#endif
2841#ifndef R_OK
2842#define R_OK 4
2843#endif
2844#ifndef W_OK
2845#define W_OK 2
2846#endif
2847#ifndef X_OK
2848#define X_OK 1
2849#endif
2850
Larry Hastings31826802013-10-19 00:09:25 -07002851
Guido van Rossumd371ff11999-01-25 16:12:23 +00002852#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002853/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002854os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002855
2856 fd: int
2857 Integer file descriptor handle.
2858
2859 /
2860
2861Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002862[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002863
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002864static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002865os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002866/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002867{
Guido van Rossum94f6f721999-01-06 18:42:14 +00002868
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002869 long size = sysconf(_SC_TTY_NAME_MAX);
2870 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002871 return posix_error();
2872 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002873 char *buffer = (char *)PyMem_RawMalloc(size);
2874 if (buffer == NULL) {
2875 return PyErr_NoMemory();
2876 }
2877 int ret = ttyname_r(fd, buffer, size);
2878 if (ret != 0) {
2879 PyMem_RawFree(buffer);
2880 errno = ret;
2881 return posix_error();
2882 }
2883 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
2884 PyMem_RawFree(buffer);
2885 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002886}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002887#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002888
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002889#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002890/*[clinic input]
2891os.ctermid
2892
2893Return the name of the controlling terminal for this process.
2894[clinic start generated code]*/
2895
Larry Hastings2f936352014-08-05 14:04:04 +10002896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002897os_ctermid_impl(PyObject *module)
2898/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002899{
Victor Stinner8c62be82010-05-06 00:08:46 +00002900 char *ret;
2901 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002902
Greg Wardb48bc172000-03-01 21:51:56 +00002903#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002904 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002905#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002906 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002907#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002908 if (ret == NULL)
2909 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002910 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002911}
Larry Hastings2f936352014-08-05 14:04:04 +10002912#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002913
Larry Hastings2f936352014-08-05 14:04:04 +10002914
2915/*[clinic input]
2916os.chdir
2917
2918 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2919
2920Change the current working directory to the specified path.
2921
2922path may always be specified as a string.
2923On some platforms, path may also be specified as an open file descriptor.
2924 If this functionality is unavailable, using it raises an exception.
2925[clinic start generated code]*/
2926
Larry Hastings2f936352014-08-05 14:04:04 +10002927static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002928os_chdir_impl(PyObject *module, path_t *path)
2929/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002930{
2931 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002932
2933 Py_BEGIN_ALLOW_THREADS
2934#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002935 /* on unix, success = 0, on windows, success = !0 */
2936 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002937#else
2938#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002939 if (path->fd != -1)
2940 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002941 else
2942#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002943 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002944#endif
2945 Py_END_ALLOW_THREADS
2946
2947 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002948 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002949 }
2950
Larry Hastings2f936352014-08-05 14:04:04 +10002951 Py_RETURN_NONE;
2952}
2953
2954
2955#ifdef HAVE_FCHDIR
2956/*[clinic input]
2957os.fchdir
2958
2959 fd: fildes
2960
2961Change to the directory of the given file descriptor.
2962
2963fd must be opened on a directory, not a file.
2964Equivalent to os.chdir(fd).
2965
2966[clinic start generated code]*/
2967
Fred Drake4d1e64b2002-04-15 19:40:07 +00002968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002969os_fchdir_impl(PyObject *module, int fd)
2970/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002971{
Larry Hastings2f936352014-08-05 14:04:04 +10002972 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002973}
2974#endif /* HAVE_FCHDIR */
2975
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002976
Larry Hastings2f936352014-08-05 14:04:04 +10002977/*[clinic input]
2978os.chmod
2979
2980 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002981 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002982 On some platforms, path may also be specified as an open file descriptor.
2983 If this functionality is unavailable, using it raises an exception.
2984
2985 mode: int
2986 Operating-system mode bitfield.
2987
2988 *
2989
2990 dir_fd : dir_fd(requires='fchmodat') = None
2991 If not None, it should be a file descriptor open to a directory,
2992 and path should be relative; path will then be relative to that
2993 directory.
2994
2995 follow_symlinks: bool = True
2996 If False, and the last element of the path is a symbolic link,
2997 chmod will modify the symbolic link itself instead of the file
2998 the link points to.
2999
3000Change the access permissions of a file.
3001
3002It is an error to use dir_fd or follow_symlinks when specifying path as
3003 an open file descriptor.
3004dir_fd and follow_symlinks may not be implemented on your platform.
3005 If they are unavailable, using them will raise a NotImplementedError.
3006
3007[clinic start generated code]*/
3008
Larry Hastings2f936352014-08-05 14:04:04 +10003009static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003010os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003011 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003012/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003013{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003014 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003015
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003016#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003017 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003018#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003019
Larry Hastings9cf065c2012-06-22 16:30:09 -07003020#ifdef HAVE_FCHMODAT
3021 int fchmodat_nofollow_unsupported = 0;
3022#endif
3023
Larry Hastings9cf065c2012-06-22 16:30:09 -07003024#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3025 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003026 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003027#endif
3028
3029#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003030 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003031 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003032 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003033 result = 0;
3034 else {
3035 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003036 attr &= ~FILE_ATTRIBUTE_READONLY;
3037 else
3038 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003039 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003040 }
3041 Py_END_ALLOW_THREADS
3042
3043 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003044 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003045 }
3046#else /* MS_WINDOWS */
3047 Py_BEGIN_ALLOW_THREADS
3048#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003049 if (path->fd != -1)
3050 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003051 else
3052#endif
3053#ifdef HAVE_LCHMOD
3054 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003055 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003056 else
3057#endif
3058#ifdef HAVE_FCHMODAT
3059 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
3060 /*
3061 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3062 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003063 * and then says it isn't implemented yet.
3064 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003065 *
3066 * Once it is supported, os.chmod will automatically
3067 * support dir_fd and follow_symlinks=False. (Hopefully.)
3068 * Until then, we need to be careful what exception we raise.
3069 */
Larry Hastings2f936352014-08-05 14:04:04 +10003070 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003071 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3072 /*
3073 * But wait! We can't throw the exception without allowing threads,
3074 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3075 */
3076 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003077 result &&
3078 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3079 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003080 }
3081 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003082#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003083 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003084 Py_END_ALLOW_THREADS
3085
3086 if (result) {
3087#ifdef HAVE_FCHMODAT
3088 if (fchmodat_nofollow_unsupported) {
3089 if (dir_fd != DEFAULT_DIR_FD)
3090 dir_fd_and_follow_symlinks_invalid("chmod",
3091 dir_fd, follow_symlinks);
3092 else
3093 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003094 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003095 }
3096 else
3097#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003098 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003099 }
3100#endif
3101
Larry Hastings2f936352014-08-05 14:04:04 +10003102 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003103}
3104
Larry Hastings9cf065c2012-06-22 16:30:09 -07003105
Christian Heimes4e30a842007-11-30 22:12:06 +00003106#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003107/*[clinic input]
3108os.fchmod
3109
3110 fd: int
3111 mode: int
3112
3113Change the access permissions of the file given by file descriptor fd.
3114
3115Equivalent to os.chmod(fd, mode).
3116[clinic start generated code]*/
3117
Larry Hastings2f936352014-08-05 14:04:04 +10003118static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003119os_fchmod_impl(PyObject *module, int fd, int mode)
3120/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003121{
3122 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003123 int async_err = 0;
3124
3125 do {
3126 Py_BEGIN_ALLOW_THREADS
3127 res = fchmod(fd, mode);
3128 Py_END_ALLOW_THREADS
3129 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3130 if (res != 0)
3131 return (!async_err) ? posix_error() : NULL;
3132
Victor Stinner8c62be82010-05-06 00:08:46 +00003133 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003134}
3135#endif /* HAVE_FCHMOD */
3136
Larry Hastings2f936352014-08-05 14:04:04 +10003137
Christian Heimes4e30a842007-11-30 22:12:06 +00003138#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003139/*[clinic input]
3140os.lchmod
3141
3142 path: path_t
3143 mode: int
3144
3145Change the access permissions of a file, without following symbolic links.
3146
3147If path is a symlink, this affects the link itself rather than the target.
3148Equivalent to chmod(path, mode, follow_symlinks=False)."
3149[clinic start generated code]*/
3150
Larry Hastings2f936352014-08-05 14:04:04 +10003151static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003152os_lchmod_impl(PyObject *module, path_t *path, int mode)
3153/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003154{
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 int res;
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
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003199#ifdef HAVE_LCHFLAGS
3200 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003201 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003202 else
3203#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003204 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003205 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003206
Larry Hastings2f936352014-08-05 14:04:04 +10003207 if (result)
3208 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003209
Larry Hastings2f936352014-08-05 14:04:04 +10003210 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003211}
3212#endif /* HAVE_CHFLAGS */
3213
Larry Hastings2f936352014-08-05 14:04:04 +10003214
Thomas Wouterscf297e42007-02-23 15:07:44 +00003215#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003216/*[clinic input]
3217os.lchflags
3218
3219 path: path_t
3220 flags: unsigned_long(bitwise=True)
3221
3222Set file flags.
3223
3224This function will not follow symbolic links.
3225Equivalent to chflags(path, flags, follow_symlinks=False).
3226[clinic start generated code]*/
3227
Larry Hastings2f936352014-08-05 14:04:04 +10003228static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003229os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3230/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003231{
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003233 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003234 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003236 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003237 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003238 }
Victor Stinner292c8352012-10-30 02:17:38 +01003239 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003240}
3241#endif /* HAVE_LCHFLAGS */
3242
Larry Hastings2f936352014-08-05 14:04:04 +10003243
Martin v. Löwis244edc82001-10-04 22:44:26 +00003244#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003245/*[clinic input]
3246os.chroot
3247 path: path_t
3248
3249Change root directory to path.
3250
3251[clinic start generated code]*/
3252
Larry Hastings2f936352014-08-05 14:04:04 +10003253static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003254os_chroot_impl(PyObject *module, path_t *path)
3255/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003256{
3257 int res;
3258 Py_BEGIN_ALLOW_THREADS
3259 res = chroot(path->narrow);
3260 Py_END_ALLOW_THREADS
3261 if (res < 0)
3262 return path_error(path);
3263 Py_RETURN_NONE;
3264}
3265#endif /* HAVE_CHROOT */
3266
Martin v. Löwis244edc82001-10-04 22:44:26 +00003267
Guido van Rossum21142a01999-01-08 21:05:37 +00003268#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003269/*[clinic input]
3270os.fsync
3271
3272 fd: fildes
3273
3274Force write of fd to disk.
3275[clinic start generated code]*/
3276
Larry Hastings2f936352014-08-05 14:04:04 +10003277static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003278os_fsync_impl(PyObject *module, int fd)
3279/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003280{
3281 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003282}
3283#endif /* HAVE_FSYNC */
3284
Larry Hastings2f936352014-08-05 14:04:04 +10003285
Ross Lagerwall7807c352011-03-17 20:20:30 +02003286#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003287/*[clinic input]
3288os.sync
3289
3290Force write of everything to disk.
3291[clinic start generated code]*/
3292
Larry Hastings2f936352014-08-05 14:04:04 +10003293static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003294os_sync_impl(PyObject *module)
3295/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003296{
3297 Py_BEGIN_ALLOW_THREADS
3298 sync();
3299 Py_END_ALLOW_THREADS
3300 Py_RETURN_NONE;
3301}
Larry Hastings2f936352014-08-05 14:04:04 +10003302#endif /* HAVE_SYNC */
3303
Ross Lagerwall7807c352011-03-17 20:20:30 +02003304
Guido van Rossum21142a01999-01-08 21:05:37 +00003305#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003306#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003307extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3308#endif
3309
Larry Hastings2f936352014-08-05 14:04:04 +10003310/*[clinic input]
3311os.fdatasync
3312
3313 fd: fildes
3314
3315Force write of fd to disk without forcing update of metadata.
3316[clinic start generated code]*/
3317
Larry Hastings2f936352014-08-05 14:04:04 +10003318static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003319os_fdatasync_impl(PyObject *module, int fd)
3320/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003321{
3322 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003323}
3324#endif /* HAVE_FDATASYNC */
3325
3326
Fredrik Lundh10723342000-07-10 16:38:09 +00003327#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003328/*[clinic input]
3329os.chown
3330
3331 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003332 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003333
3334 uid: uid_t
3335
3336 gid: gid_t
3337
3338 *
3339
3340 dir_fd : dir_fd(requires='fchownat') = None
3341 If not None, it should be a file descriptor open to a directory,
3342 and path should be relative; path will then be relative to that
3343 directory.
3344
3345 follow_symlinks: bool = True
3346 If False, and the last element of the path is a symbolic link,
3347 stat will examine the symbolic link itself instead of the file
3348 the link points to.
3349
3350Change the owner and group id of path to the numeric uid and gid.\
3351
3352path may always be specified as a string.
3353On some platforms, path may also be specified as an open file descriptor.
3354 If this functionality is unavailable, using it raises an exception.
3355If dir_fd is not None, it should be a file descriptor open to a directory,
3356 and path should be relative; path will then be relative to that directory.
3357If follow_symlinks is False, and the last element of the path is a symbolic
3358 link, chown will modify the symbolic link itself instead of the file the
3359 link points to.
3360It is an error to use dir_fd or follow_symlinks when specifying path as
3361 an open file descriptor.
3362dir_fd and follow_symlinks may not be implemented on your platform.
3363 If they are unavailable, using them will raise a NotImplementedError.
3364
3365[clinic start generated code]*/
3366
Larry Hastings2f936352014-08-05 14:04:04 +10003367static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003368os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003369 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003370/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003371{
3372 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003373
3374#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3375 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003376 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003377#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003378 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3379 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3380 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003381
3382#ifdef __APPLE__
3383 /*
3384 * This is for Mac OS X 10.3, which doesn't have lchown.
3385 * (But we still have an lchown symbol because of weak-linking.)
3386 * It doesn't have fchownat either. So there's no possibility
3387 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003388 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003389 if ((!follow_symlinks) && (lchown == NULL)) {
3390 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003391 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392 }
3393#endif
3394
Victor Stinner8c62be82010-05-06 00:08:46 +00003395 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003396#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003397 if (path->fd != -1)
3398 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003399 else
3400#endif
3401#ifdef HAVE_LCHOWN
3402 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003403 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003404 else
3405#endif
3406#ifdef HAVE_FCHOWNAT
3407 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003408 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003409 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3410 else
3411#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003412 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003413 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003414
Larry Hastings2f936352014-08-05 14:04:04 +10003415 if (result)
3416 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003417
Larry Hastings2f936352014-08-05 14:04:04 +10003418 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003419}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003420#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003421
Larry Hastings2f936352014-08-05 14:04:04 +10003422
Christian Heimes4e30a842007-11-30 22:12:06 +00003423#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003424/*[clinic input]
3425os.fchown
3426
3427 fd: int
3428 uid: uid_t
3429 gid: gid_t
3430
3431Change the owner and group id of the file specified by file descriptor.
3432
3433Equivalent to os.chown(fd, uid, gid).
3434
3435[clinic start generated code]*/
3436
Larry Hastings2f936352014-08-05 14:04:04 +10003437static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003438os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3439/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003440{
Victor Stinner8c62be82010-05-06 00:08:46 +00003441 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003442 int async_err = 0;
3443
3444 do {
3445 Py_BEGIN_ALLOW_THREADS
3446 res = fchown(fd, uid, gid);
3447 Py_END_ALLOW_THREADS
3448 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3449 if (res != 0)
3450 return (!async_err) ? posix_error() : NULL;
3451
Victor Stinner8c62be82010-05-06 00:08:46 +00003452 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003453}
3454#endif /* HAVE_FCHOWN */
3455
Larry Hastings2f936352014-08-05 14:04:04 +10003456
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003457#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003458/*[clinic input]
3459os.lchown
3460
3461 path : path_t
3462 uid: uid_t
3463 gid: gid_t
3464
3465Change the owner and group id of path to the numeric uid and gid.
3466
3467This function will not follow symbolic links.
3468Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3469[clinic start generated code]*/
3470
Larry Hastings2f936352014-08-05 14:04:04 +10003471static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003472os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3473/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003474{
Victor Stinner8c62be82010-05-06 00:08:46 +00003475 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003476 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003477 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003478 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003479 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003480 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003481 }
Larry Hastings2f936352014-08-05 14:04:04 +10003482 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003483}
3484#endif /* HAVE_LCHOWN */
3485
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003486
Barry Warsaw53699e91996-12-10 23:23:01 +00003487static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003488posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003489{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003490#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003491 wchar_t wbuf[MAXPATHLEN];
3492 wchar_t *wbuf2 = wbuf;
3493 DWORD len;
3494
3495 Py_BEGIN_ALLOW_THREADS
3496 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3497 /* If the buffer is large enough, len does not include the
3498 terminating \0. If the buffer is too small, len includes
3499 the space needed for the terminator. */
3500 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003501 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003502 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003503 }
Victor Stinner689830e2019-06-26 17:31:12 +02003504 else {
3505 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003506 }
Victor Stinner689830e2019-06-26 17:31:12 +02003507 if (wbuf2) {
3508 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003509 }
Victor Stinner689830e2019-06-26 17:31:12 +02003510 }
3511 Py_END_ALLOW_THREADS
3512
3513 if (!wbuf2) {
3514 PyErr_NoMemory();
3515 return NULL;
3516 }
3517 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003518 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003519 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003520 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003522
Victor Stinner689830e2019-06-26 17:31:12 +02003523 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3524 if (wbuf2 != wbuf) {
3525 PyMem_RawFree(wbuf2);
3526 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003527
Victor Stinner689830e2019-06-26 17:31:12 +02003528 if (use_bytes) {
3529 if (resobj == NULL) {
3530 return NULL;
3531 }
3532 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3533 }
3534
3535 return resobj;
3536#else
3537 const size_t chunk = 1024;
3538
3539 char *buf = NULL;
3540 char *cwd = NULL;
3541 size_t buflen = 0;
3542
Victor Stinner8c62be82010-05-06 00:08:46 +00003543 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003544 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003545 char *newbuf;
3546 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3547 buflen += chunk;
3548 newbuf = PyMem_RawRealloc(buf, buflen);
3549 }
3550 else {
3551 newbuf = NULL;
3552 }
3553 if (newbuf == NULL) {
3554 PyMem_RawFree(buf);
3555 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003556 break;
3557 }
Victor Stinner689830e2019-06-26 17:31:12 +02003558 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003559
Victor Stinner4403d7d2015-04-25 00:16:10 +02003560 cwd = getcwd(buf, buflen);
3561 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003563
Victor Stinner689830e2019-06-26 17:31:12 +02003564 if (buf == NULL) {
3565 return PyErr_NoMemory();
3566 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003567 if (cwd == NULL) {
3568 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003569 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003570 }
3571
Victor Stinner689830e2019-06-26 17:31:12 +02003572 PyObject *obj;
3573 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003574 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003575 }
3576 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003577 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003578 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003579 PyMem_RawFree(buf);
3580
3581 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003582#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003583}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003584
Larry Hastings2f936352014-08-05 14:04:04 +10003585
3586/*[clinic input]
3587os.getcwd
3588
3589Return a unicode string representing the current working directory.
3590[clinic start generated code]*/
3591
Larry Hastings2f936352014-08-05 14:04:04 +10003592static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003593os_getcwd_impl(PyObject *module)
3594/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003595{
3596 return posix_getcwd(0);
3597}
3598
Larry Hastings2f936352014-08-05 14:04:04 +10003599
3600/*[clinic input]
3601os.getcwdb
3602
3603Return a bytes string representing the current working directory.
3604[clinic start generated code]*/
3605
Larry Hastings2f936352014-08-05 14:04:04 +10003606static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003607os_getcwdb_impl(PyObject *module)
3608/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003609{
3610 return posix_getcwd(1);
3611}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003612
Larry Hastings2f936352014-08-05 14:04:04 +10003613
Larry Hastings9cf065c2012-06-22 16:30:09 -07003614#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3615#define HAVE_LINK 1
3616#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003617
Guido van Rossumb6775db1994-08-01 11:34:53 +00003618#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003619/*[clinic input]
3620
3621os.link
3622
3623 src : path_t
3624 dst : path_t
3625 *
3626 src_dir_fd : dir_fd = None
3627 dst_dir_fd : dir_fd = None
3628 follow_symlinks: bool = True
3629
3630Create a hard link to a file.
3631
3632If either src_dir_fd or dst_dir_fd is not None, it should be a file
3633 descriptor open to a directory, and the respective path string (src or dst)
3634 should be relative; the path will then be relative to that directory.
3635If follow_symlinks is False, and the last element of src is a symbolic
3636 link, link will create a link to the symbolic link itself instead of the
3637 file the link points to.
3638src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3639 platform. If they are unavailable, using them will raise a
3640 NotImplementedError.
3641[clinic start generated code]*/
3642
Larry Hastings2f936352014-08-05 14:04:04 +10003643static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003644os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003645 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003646/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003647{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003648#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003649 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003650#else
3651 int result;
3652#endif
3653
Larry Hastings9cf065c2012-06-22 16:30:09 -07003654#ifndef HAVE_LINKAT
3655 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3656 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003657 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003658 }
3659#endif
3660
Steve Dowercc16be82016-09-08 10:35:16 -07003661#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003662 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003663 PyErr_SetString(PyExc_NotImplementedError,
3664 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003665 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003666 }
Steve Dowercc16be82016-09-08 10:35:16 -07003667#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003668
Brian Curtin1b9df392010-11-24 20:24:31 +00003669#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003670 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003671 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003672 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003673
Larry Hastings2f936352014-08-05 14:04:04 +10003674 if (!result)
3675 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003676#else
3677 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003678#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3680 (dst_dir_fd != DEFAULT_DIR_FD) ||
3681 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003682 result = linkat(src_dir_fd, src->narrow,
3683 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003684 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3685 else
Steve Dowercc16be82016-09-08 10:35:16 -07003686#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003687 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003688 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003689
Larry Hastings2f936352014-08-05 14:04:04 +10003690 if (result)
3691 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003692#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003693
Larry Hastings2f936352014-08-05 14:04:04 +10003694 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003695}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003696#endif
3697
Brian Curtin1b9df392010-11-24 20:24:31 +00003698
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003699#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003700static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003701_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003702{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003703 PyObject *v;
3704 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3705 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003706 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003707 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003708 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003709 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710
Steve Dowercc16be82016-09-08 10:35:16 -07003711 WIN32_FIND_DATAW wFileData;
3712 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003713
Steve Dowercc16be82016-09-08 10:35:16 -07003714 if (!path->wide) { /* Default arg: "." */
3715 po_wchars = L".";
3716 len = 1;
3717 } else {
3718 po_wchars = path->wide;
3719 len = wcslen(path->wide);
3720 }
3721 /* The +5 is so we can append "\\*.*\0" */
3722 wnamebuf = PyMem_New(wchar_t, len + 5);
3723 if (!wnamebuf) {
3724 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003725 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003726 }
Steve Dowercc16be82016-09-08 10:35:16 -07003727 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003728 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003729 wchar_t wch = wnamebuf[len-1];
3730 if (wch != SEP && wch != ALTSEP && wch != L':')
3731 wnamebuf[len++] = SEP;
3732 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003733 }
Steve Dowercc16be82016-09-08 10:35:16 -07003734 if ((list = PyList_New(0)) == NULL) {
3735 goto exit;
3736 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003737 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003738 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003739 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003740 if (hFindFile == INVALID_HANDLE_VALUE) {
3741 int error = GetLastError();
3742 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003743 goto exit;
3744 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003745 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003746 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003747 }
3748 do {
3749 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003750 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3751 wcscmp(wFileData.cFileName, L"..") != 0) {
3752 v = PyUnicode_FromWideChar(wFileData.cFileName,
3753 wcslen(wFileData.cFileName));
3754 if (path->narrow && v) {
3755 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3756 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003757 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003758 Py_DECREF(list);
3759 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003760 break;
3761 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003762 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003763 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003764 Py_DECREF(list);
3765 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003766 break;
3767 }
3768 Py_DECREF(v);
3769 }
3770 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003771 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003772 Py_END_ALLOW_THREADS
3773 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3774 it got to the end of the directory. */
3775 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003776 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003777 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003778 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003779 }
3780 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003781
Larry Hastings9cf065c2012-06-22 16:30:09 -07003782exit:
3783 if (hFindFile != INVALID_HANDLE_VALUE) {
3784 if (FindClose(hFindFile) == FALSE) {
3785 if (list != NULL) {
3786 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003787 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003788 }
3789 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003791 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003792
Larry Hastings9cf065c2012-06-22 16:30:09 -07003793 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003794} /* end of _listdir_windows_no_opendir */
3795
3796#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3797
3798static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003799_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003800{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003801 PyObject *v;
3802 DIR *dirp = NULL;
3803 struct dirent *ep;
3804 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003805#ifdef HAVE_FDOPENDIR
3806 int fd = -1;
3807#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003808
Victor Stinner8c62be82010-05-06 00:08:46 +00003809 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003810#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003811 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003812 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003813 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003814 if (fd == -1)
3815 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003816
Larry Hastingsfdaea062012-06-25 04:42:23 -07003817 return_str = 1;
3818
Larry Hastings9cf065c2012-06-22 16:30:09 -07003819 Py_BEGIN_ALLOW_THREADS
3820 dirp = fdopendir(fd);
3821 Py_END_ALLOW_THREADS
3822 }
3823 else
3824#endif
3825 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003826 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003827 if (path->narrow) {
3828 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003829 /* only return bytes if they specified a bytes-like object */
3830 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003831 }
3832 else {
3833 name = ".";
3834 return_str = 1;
3835 }
3836
Larry Hastings9cf065c2012-06-22 16:30:09 -07003837 Py_BEGIN_ALLOW_THREADS
3838 dirp = opendir(name);
3839 Py_END_ALLOW_THREADS
3840 }
3841
3842 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003843 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003844#ifdef HAVE_FDOPENDIR
3845 if (fd != -1) {
3846 Py_BEGIN_ALLOW_THREADS
3847 close(fd);
3848 Py_END_ALLOW_THREADS
3849 }
3850#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003851 goto exit;
3852 }
3853 if ((list = PyList_New(0)) == NULL) {
3854 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003855 }
3856 for (;;) {
3857 errno = 0;
3858 Py_BEGIN_ALLOW_THREADS
3859 ep = readdir(dirp);
3860 Py_END_ALLOW_THREADS
3861 if (ep == NULL) {
3862 if (errno == 0) {
3863 break;
3864 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003865 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003866 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003867 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003868 }
3869 }
3870 if (ep->d_name[0] == '.' &&
3871 (NAMLEN(ep) == 1 ||
3872 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3873 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003874 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003875 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3876 else
3877 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003878 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003879 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003880 break;
3881 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003882 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003883 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003884 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 break;
3886 }
3887 Py_DECREF(v);
3888 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003889
Larry Hastings9cf065c2012-06-22 16:30:09 -07003890exit:
3891 if (dirp != NULL) {
3892 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003893#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003894 if (fd > -1)
3895 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003896#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003897 closedir(dirp);
3898 Py_END_ALLOW_THREADS
3899 }
3900
Larry Hastings9cf065c2012-06-22 16:30:09 -07003901 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003902} /* end of _posix_listdir */
3903#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003904
Larry Hastings2f936352014-08-05 14:04:04 +10003905
3906/*[clinic input]
3907os.listdir
3908
3909 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3910
3911Return a list containing the names of the files in the directory.
3912
BNMetricsb9427072018-11-02 15:20:19 +00003913path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003914 the filenames returned will also be bytes; in all other circumstances
3915 the filenames returned will be str.
3916If path is None, uses the path='.'.
3917On some platforms, path may also be specified as an open file descriptor;\
3918 the file descriptor must refer to a directory.
3919 If this functionality is unavailable, using it raises NotImplementedError.
3920
3921The list is in arbitrary order. It does not include the special
3922entries '.' and '..' even if they are present in the directory.
3923
3924
3925[clinic start generated code]*/
3926
Larry Hastings2f936352014-08-05 14:04:04 +10003927static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003928os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003929/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003930{
Steve Dower60419a72019-06-24 08:42:54 -07003931 if (PySys_Audit("os.listdir", "O",
3932 path->object ? path->object : Py_None) < 0) {
3933 return NULL;
3934 }
Larry Hastings2f936352014-08-05 14:04:04 +10003935#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3936 return _listdir_windows_no_opendir(path, NULL);
3937#else
3938 return _posix_listdir(path, NULL);
3939#endif
3940}
3941
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003942#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003943/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003944/*[clinic input]
3945os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003946
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003947 path: path_t
3948 /
3949
3950[clinic start generated code]*/
3951
3952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003953os__getfullpathname_impl(PyObject *module, path_t *path)
3954/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003955{
Victor Stinner3939c322019-06-25 15:02:43 +02003956 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003957
Victor Stinner3939c322019-06-25 15:02:43 +02003958 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
3959 if (_Py_abspath(path->wide, &abspath) < 0) {
3960 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 }
Victor Stinner3939c322019-06-25 15:02:43 +02003962 if (abspath == NULL) {
3963 return PyErr_NoMemory();
3964 }
3965
3966 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
3967 PyMem_RawFree(abspath);
3968 if (str == NULL) {
3969 return NULL;
3970 }
3971 if (path->narrow) {
3972 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
3973 }
3974 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10003975}
Brian Curtind40e6f72010-07-08 21:39:08 +00003976
Brian Curtind25aef52011-06-13 15:16:04 -05003977
Larry Hastings2f936352014-08-05 14:04:04 +10003978/*[clinic input]
3979os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003980
Steve Dower23ad6d02018-02-22 10:39:10 -08003981 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003982 /
3983
3984A helper function for samepath on windows.
3985[clinic start generated code]*/
3986
Larry Hastings2f936352014-08-05 14:04:04 +10003987static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003988os__getfinalpathname_impl(PyObject *module, path_t *path)
3989/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003990{
3991 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003992 wchar_t buf[MAXPATHLEN], *target_path = buf;
3993 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003994 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003995 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003996
Steve Dower23ad6d02018-02-22 10:39:10 -08003997 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003998 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003999 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004000 0, /* desired access */
4001 0, /* share mode */
4002 NULL, /* security attributes */
4003 OPEN_EXISTING,
4004 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4005 FILE_FLAG_BACKUP_SEMANTICS,
4006 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004007 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004008
Steve Dower23ad6d02018-02-22 10:39:10 -08004009 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004010 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004011 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004012
4013 /* We have a good handle to the target, use it to determine the
4014 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004015 while (1) {
4016 Py_BEGIN_ALLOW_THREADS
4017 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4018 buf_size, VOLUME_NAME_DOS);
4019 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004020
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004021 if (!result_length) {
4022 result = win32_error_object("GetFinalPathNameByHandleW",
4023 path->object);
4024 goto cleanup;
4025 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004026
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004027 if (result_length < buf_size) {
4028 break;
4029 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004030
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004031 wchar_t *tmp;
4032 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4033 result_length * sizeof(*tmp));
4034 if (!tmp) {
4035 result = PyErr_NoMemory();
4036 goto cleanup;
4037 }
4038
4039 buf_size = result_length;
4040 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004041 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004042
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004043 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004044 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004045 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004046 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004047
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004048cleanup:
4049 if (target_path != buf) {
4050 PyMem_Free(target_path);
4051 }
4052 CloseHandle(hFile);
4053 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004054}
Brian Curtin62857742010-09-06 17:07:27 +00004055
Tim Golden6b528062013-08-01 12:44:00 +01004056
Larry Hastings2f936352014-08-05 14:04:04 +10004057/*[clinic input]
4058os._getvolumepathname
4059
Steve Dower23ad6d02018-02-22 10:39:10 -08004060 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004061
4062A helper function for ismount on Win32.
4063[clinic start generated code]*/
4064
Larry Hastings2f936352014-08-05 14:04:04 +10004065static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004066os__getvolumepathname_impl(PyObject *module, path_t *path)
4067/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004068{
4069 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004070 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004071 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004072 BOOL ret;
4073
Tim Golden6b528062013-08-01 12:44:00 +01004074 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004075 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004076
Victor Stinner850a18e2017-10-24 16:53:32 -07004077 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004078 PyErr_SetString(PyExc_OverflowError, "path too long");
4079 return NULL;
4080 }
4081
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004082 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004083 if (mountpath == NULL)
4084 return PyErr_NoMemory();
4085
4086 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004087 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004088 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004089 Py_END_ALLOW_THREADS
4090
4091 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004092 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004093 goto exit;
4094 }
4095 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004096 if (path->narrow)
4097 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004098
4099exit:
4100 PyMem_Free(mountpath);
4101 return result;
4102}
Tim Golden6b528062013-08-01 12:44:00 +01004103
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004104#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004105
Larry Hastings2f936352014-08-05 14:04:04 +10004106
4107/*[clinic input]
4108os.mkdir
4109
4110 path : path_t
4111
4112 mode: int = 0o777
4113
4114 *
4115
4116 dir_fd : dir_fd(requires='mkdirat') = None
4117
4118# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4119
4120Create a directory.
4121
4122If dir_fd is not None, it should be a file descriptor open to a directory,
4123 and path should be relative; path will then be relative to that directory.
4124dir_fd may not be implemented on your platform.
4125 If it is unavailable, using it will raise a NotImplementedError.
4126
4127The mode argument is ignored on Windows.
4128[clinic start generated code]*/
4129
Larry Hastings2f936352014-08-05 14:04:04 +10004130static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004131os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4132/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004133{
4134 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004135
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004136#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004137 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004138 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004139 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004140
Larry Hastings2f936352014-08-05 14:04:04 +10004141 if (!result)
4142 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004143#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004144 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004145#if HAVE_MKDIRAT
4146 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004147 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004148 else
4149#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004150#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004151 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004152#else
Larry Hastings2f936352014-08-05 14:04:04 +10004153 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004154#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004155 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004156 if (result < 0)
4157 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004158#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004159 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004160}
4161
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004162
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004163/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4164#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004165#include <sys/resource.h>
4166#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004167
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004168
4169#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004170/*[clinic input]
4171os.nice
4172
4173 increment: int
4174 /
4175
4176Add increment to the priority of process and return the new priority.
4177[clinic start generated code]*/
4178
Larry Hastings2f936352014-08-05 14:04:04 +10004179static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004180os_nice_impl(PyObject *module, int increment)
4181/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004182{
4183 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004184
Victor Stinner8c62be82010-05-06 00:08:46 +00004185 /* There are two flavours of 'nice': one that returns the new
4186 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004187 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004188 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004189
Victor Stinner8c62be82010-05-06 00:08:46 +00004190 If we are of the nice family that returns the new priority, we
4191 need to clear errno before the call, and check if errno is filled
4192 before calling posix_error() on a returnvalue of -1, because the
4193 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004194
Victor Stinner8c62be82010-05-06 00:08:46 +00004195 errno = 0;
4196 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004197#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004198 if (value == 0)
4199 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004200#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004201 if (value == -1 && errno != 0)
4202 /* either nice() or getpriority() returned an error */
4203 return posix_error();
4204 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004205}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004206#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004207
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004208
4209#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004210/*[clinic input]
4211os.getpriority
4212
4213 which: int
4214 who: int
4215
4216Return program scheduling priority.
4217[clinic start generated code]*/
4218
Larry Hastings2f936352014-08-05 14:04:04 +10004219static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004220os_getpriority_impl(PyObject *module, int which, int who)
4221/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004222{
4223 int retval;
4224
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004225 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004226 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004227 if (errno != 0)
4228 return posix_error();
4229 return PyLong_FromLong((long)retval);
4230}
4231#endif /* HAVE_GETPRIORITY */
4232
4233
4234#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004235/*[clinic input]
4236os.setpriority
4237
4238 which: int
4239 who: int
4240 priority: int
4241
4242Set program scheduling priority.
4243[clinic start generated code]*/
4244
Larry Hastings2f936352014-08-05 14:04:04 +10004245static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004246os_setpriority_impl(PyObject *module, int which, int who, int priority)
4247/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004248{
4249 int retval;
4250
4251 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004252 if (retval == -1)
4253 return posix_error();
4254 Py_RETURN_NONE;
4255}
4256#endif /* HAVE_SETPRIORITY */
4257
4258
Barry Warsaw53699e91996-12-10 23:23:01 +00004259static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004260internal_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 +00004261{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004262 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004263 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004264
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004265#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004266 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004267 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004268#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004269 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004270#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004271
Larry Hastings9cf065c2012-06-22 16:30:09 -07004272 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4273 (dst_dir_fd != DEFAULT_DIR_FD);
4274#ifndef HAVE_RENAMEAT
4275 if (dir_fd_specified) {
4276 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004277 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004278 }
4279#endif
4280
Larry Hastings9cf065c2012-06-22 16:30:09 -07004281#ifdef MS_WINDOWS
4282 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004283 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004284 Py_END_ALLOW_THREADS
4285
Larry Hastings2f936352014-08-05 14:04:04 +10004286 if (!result)
4287 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004288
4289#else
Steve Dowercc16be82016-09-08 10:35:16 -07004290 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4291 PyErr_Format(PyExc_ValueError,
4292 "%s: src and dst must be the same type", function_name);
4293 return NULL;
4294 }
4295
Larry Hastings9cf065c2012-06-22 16:30:09 -07004296 Py_BEGIN_ALLOW_THREADS
4297#ifdef HAVE_RENAMEAT
4298 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004299 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004300 else
4301#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004302 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004303 Py_END_ALLOW_THREADS
4304
Larry Hastings2f936352014-08-05 14:04:04 +10004305 if (result)
4306 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004307#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004308 Py_RETURN_NONE;
4309}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004310
Larry Hastings2f936352014-08-05 14:04:04 +10004311
4312/*[clinic input]
4313os.rename
4314
4315 src : path_t
4316 dst : path_t
4317 *
4318 src_dir_fd : dir_fd = None
4319 dst_dir_fd : dir_fd = None
4320
4321Rename a file or directory.
4322
4323If either src_dir_fd or dst_dir_fd is not None, it should be a file
4324 descriptor open to a directory, and the respective path string (src or dst)
4325 should be relative; the path will then be relative to that directory.
4326src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4327 If they are unavailable, using them will raise a NotImplementedError.
4328[clinic start generated code]*/
4329
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004330static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004331os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004332 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004333/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004334{
Larry Hastings2f936352014-08-05 14:04:04 +10004335 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004336}
4337
Larry Hastings2f936352014-08-05 14:04:04 +10004338
4339/*[clinic input]
4340os.replace = os.rename
4341
4342Rename a file or directory, overwriting the destination.
4343
4344If either src_dir_fd or dst_dir_fd is not None, it should be a file
4345 descriptor open to a directory, and the respective path string (src or dst)
4346 should be relative; the path will then be relative to that directory.
4347src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004348 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004349[clinic start generated code]*/
4350
Larry Hastings2f936352014-08-05 14:04:04 +10004351static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004352os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4353 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004354/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004355{
4356 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4357}
4358
4359
4360/*[clinic input]
4361os.rmdir
4362
4363 path: path_t
4364 *
4365 dir_fd: dir_fd(requires='unlinkat') = None
4366
4367Remove a directory.
4368
4369If dir_fd is not None, it should be a file descriptor open to a directory,
4370 and path should be relative; path will then be relative to that directory.
4371dir_fd may not be implemented on your platform.
4372 If it is unavailable, using it will raise a NotImplementedError.
4373[clinic start generated code]*/
4374
Larry Hastings2f936352014-08-05 14:04:04 +10004375static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004376os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4377/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004378{
4379 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004380
4381 Py_BEGIN_ALLOW_THREADS
4382#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004383 /* Windows, success=1, UNIX, success=0 */
4384 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004385#else
4386#ifdef HAVE_UNLINKAT
4387 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004388 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004389 else
4390#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004391 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004392#endif
4393 Py_END_ALLOW_THREADS
4394
Larry Hastings2f936352014-08-05 14:04:04 +10004395 if (result)
4396 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004397
Larry Hastings2f936352014-08-05 14:04:04 +10004398 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004399}
4400
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004401
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004402#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004403#ifdef MS_WINDOWS
4404/*[clinic input]
4405os.system -> long
4406
4407 command: Py_UNICODE
4408
4409Execute the command in a subshell.
4410[clinic start generated code]*/
4411
Larry Hastings2f936352014-08-05 14:04:04 +10004412static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004413os_system_impl(PyObject *module, const Py_UNICODE *command)
4414/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004415{
4416 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004417
Steve Dowerfbe3c762019-10-18 00:52:15 -07004418 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004419 return -1;
4420 }
4421
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004423 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004424 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004425 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004426 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004427 return result;
4428}
4429#else /* MS_WINDOWS */
4430/*[clinic input]
4431os.system -> long
4432
4433 command: FSConverter
4434
4435Execute the command in a subshell.
4436[clinic start generated code]*/
4437
Larry Hastings2f936352014-08-05 14:04:04 +10004438static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004439os_system_impl(PyObject *module, PyObject *command)
4440/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004441{
4442 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004443 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004444
Steve Dowerfbe3c762019-10-18 00:52:15 -07004445 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004446 return -1;
4447 }
4448
Larry Hastings2f936352014-08-05 14:04:04 +10004449 Py_BEGIN_ALLOW_THREADS
4450 result = system(bytes);
4451 Py_END_ALLOW_THREADS
4452 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004453}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004454#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004455#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004456
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004457
Larry Hastings2f936352014-08-05 14:04:04 +10004458/*[clinic input]
4459os.umask
4460
4461 mask: int
4462 /
4463
4464Set the current numeric umask and return the previous umask.
4465[clinic start generated code]*/
4466
Larry Hastings2f936352014-08-05 14:04:04 +10004467static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004468os_umask_impl(PyObject *module, int mask)
4469/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004470{
4471 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004472 if (i < 0)
4473 return posix_error();
4474 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004475}
4476
Brian Curtind40e6f72010-07-08 21:39:08 +00004477#ifdef MS_WINDOWS
4478
4479/* override the default DeleteFileW behavior so that directory
4480symlinks can be removed with this function, the same as with
4481Unix symlinks */
4482BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4483{
4484 WIN32_FILE_ATTRIBUTE_DATA info;
4485 WIN32_FIND_DATAW find_data;
4486 HANDLE find_data_handle;
4487 int is_directory = 0;
4488 int is_link = 0;
4489
4490 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4491 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004492
Brian Curtind40e6f72010-07-08 21:39:08 +00004493 /* Get WIN32_FIND_DATA structure for the path to determine if
4494 it is a symlink */
4495 if(is_directory &&
4496 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4497 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4498
4499 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004500 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4501 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4502 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4503 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004504 FindClose(find_data_handle);
4505 }
4506 }
4507 }
4508
4509 if (is_directory && is_link)
4510 return RemoveDirectoryW(lpFileName);
4511
4512 return DeleteFileW(lpFileName);
4513}
4514#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004515
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004516
Larry Hastings2f936352014-08-05 14:04:04 +10004517/*[clinic input]
4518os.unlink
4519
4520 path: path_t
4521 *
4522 dir_fd: dir_fd(requires='unlinkat')=None
4523
4524Remove a file (same as remove()).
4525
4526If dir_fd is not None, it should be a file descriptor open to a directory,
4527 and path should be relative; path will then be relative to that directory.
4528dir_fd may not be implemented on your platform.
4529 If it is unavailable, using it will raise a NotImplementedError.
4530
4531[clinic start generated code]*/
4532
Larry Hastings2f936352014-08-05 14:04:04 +10004533static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004534os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4535/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004536{
4537 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538
4539 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004540 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004541#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004542 /* Windows, success=1, UNIX, success=0 */
4543 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004544#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004545#ifdef HAVE_UNLINKAT
4546 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004547 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004548 else
4549#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004550 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004551#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004552 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004553 Py_END_ALLOW_THREADS
4554
Larry Hastings2f936352014-08-05 14:04:04 +10004555 if (result)
4556 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004557
Larry Hastings2f936352014-08-05 14:04:04 +10004558 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004559}
4560
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004561
Larry Hastings2f936352014-08-05 14:04:04 +10004562/*[clinic input]
4563os.remove = os.unlink
4564
4565Remove a file (same as unlink()).
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[clinic start generated code]*/
4572
Larry Hastings2f936352014-08-05 14:04:04 +10004573static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004574os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4575/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004576{
4577 return os_unlink_impl(module, path, dir_fd);
4578}
4579
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004580
Larry Hastings605a62d2012-06-24 04:33:36 -07004581static PyStructSequence_Field uname_result_fields[] = {
4582 {"sysname", "operating system name"},
4583 {"nodename", "name of machine on network (implementation-defined)"},
4584 {"release", "operating system release"},
4585 {"version", "operating system version"},
4586 {"machine", "hardware identifier"},
4587 {NULL}
4588};
4589
4590PyDoc_STRVAR(uname_result__doc__,
4591"uname_result: Result from os.uname().\n\n\
4592This object may be accessed either as a tuple of\n\
4593 (sysname, nodename, release, version, machine),\n\
4594or via the attributes sysname, nodename, release, version, and machine.\n\
4595\n\
4596See os.uname for more information.");
4597
4598static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08004599 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07004600 uname_result__doc__, /* doc */
4601 uname_result_fields,
4602 5
4603};
4604
Larry Hastings605a62d2012-06-24 04:33:36 -07004605#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004606/*[clinic input]
4607os.uname
4608
4609Return an object identifying the current operating system.
4610
4611The object behaves like a named tuple with the following fields:
4612 (sysname, nodename, release, version, machine)
4613
4614[clinic start generated code]*/
4615
Larry Hastings2f936352014-08-05 14:04:04 +10004616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004617os_uname_impl(PyObject *module)
4618/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004619{
Victor Stinner8c62be82010-05-06 00:08:46 +00004620 struct utsname u;
4621 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004622 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004623
Victor Stinner8c62be82010-05-06 00:08:46 +00004624 Py_BEGIN_ALLOW_THREADS
4625 res = uname(&u);
4626 Py_END_ALLOW_THREADS
4627 if (res < 0)
4628 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004629
Eddie Elizondob3966632019-11-05 07:16:14 -08004630 PyObject *UnameResultType = _posixstate(module)->UnameResultType;
4631 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004632 if (value == NULL)
4633 return NULL;
4634
4635#define SET(i, field) \
4636 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004637 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004638 if (!o) { \
4639 Py_DECREF(value); \
4640 return NULL; \
4641 } \
4642 PyStructSequence_SET_ITEM(value, i, o); \
4643 } \
4644
4645 SET(0, u.sysname);
4646 SET(1, u.nodename);
4647 SET(2, u.release);
4648 SET(3, u.version);
4649 SET(4, u.machine);
4650
4651#undef SET
4652
4653 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004654}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004655#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004656
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004657
Larry Hastings9cf065c2012-06-22 16:30:09 -07004658
4659typedef struct {
4660 int now;
4661 time_t atime_s;
4662 long atime_ns;
4663 time_t mtime_s;
4664 long mtime_ns;
4665} utime_t;
4666
4667/*
Victor Stinner484df002014-10-09 13:52:31 +02004668 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004669 * they also intentionally leak the declaration of a pointer named "time"
4670 */
4671#define UTIME_TO_TIMESPEC \
4672 struct timespec ts[2]; \
4673 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004674 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675 time = NULL; \
4676 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004677 ts[0].tv_sec = ut->atime_s; \
4678 ts[0].tv_nsec = ut->atime_ns; \
4679 ts[1].tv_sec = ut->mtime_s; \
4680 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004681 time = ts; \
4682 } \
4683
4684#define UTIME_TO_TIMEVAL \
4685 struct timeval tv[2]; \
4686 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004687 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004688 time = NULL; \
4689 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004690 tv[0].tv_sec = ut->atime_s; \
4691 tv[0].tv_usec = ut->atime_ns / 1000; \
4692 tv[1].tv_sec = ut->mtime_s; \
4693 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004694 time = tv; \
4695 } \
4696
4697#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004698 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004699 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004700 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004701 time = NULL; \
4702 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004703 u.actime = ut->atime_s; \
4704 u.modtime = ut->mtime_s; \
4705 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706 }
4707
4708#define UTIME_TO_TIME_T \
4709 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004710 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004711 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712 time = NULL; \
4713 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004714 timet[0] = ut->atime_s; \
4715 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004716 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004717 } \
4718
4719
Victor Stinner528a9ab2015-09-03 21:30:26 +02004720#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004721
4722static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004723utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004724{
4725#ifdef HAVE_UTIMENSAT
4726 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4727 UTIME_TO_TIMESPEC;
4728 return utimensat(dir_fd, path, time, flags);
4729#elif defined(HAVE_FUTIMESAT)
4730 UTIME_TO_TIMEVAL;
4731 /*
4732 * follow_symlinks will never be false here;
4733 * we only allow !follow_symlinks and dir_fd together
4734 * if we have utimensat()
4735 */
4736 assert(follow_symlinks);
4737 return futimesat(dir_fd, path, time);
4738#endif
4739}
4740
Larry Hastings2f936352014-08-05 14:04:04 +10004741 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4742#else
4743 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744#endif
4745
Victor Stinner528a9ab2015-09-03 21:30:26 +02004746#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747
4748static int
Victor Stinner484df002014-10-09 13:52:31 +02004749utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004750{
4751#ifdef HAVE_FUTIMENS
4752 UTIME_TO_TIMESPEC;
4753 return futimens(fd, time);
4754#else
4755 UTIME_TO_TIMEVAL;
4756 return futimes(fd, time);
4757#endif
4758}
4759
Larry Hastings2f936352014-08-05 14:04:04 +10004760 #define PATH_UTIME_HAVE_FD 1
4761#else
4762 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763#endif
4764
Victor Stinner5ebae872015-09-22 01:29:33 +02004765#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4766# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4767#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004768
Victor Stinner4552ced2015-09-21 22:37:15 +02004769#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770
4771static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004772utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004773{
4774#ifdef HAVE_UTIMENSAT
4775 UTIME_TO_TIMESPEC;
4776 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4777#else
4778 UTIME_TO_TIMEVAL;
4779 return lutimes(path, time);
4780#endif
4781}
4782
4783#endif
4784
4785#ifndef MS_WINDOWS
4786
4787static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004788utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004789{
4790#ifdef HAVE_UTIMENSAT
4791 UTIME_TO_TIMESPEC;
4792 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4793#elif defined(HAVE_UTIMES)
4794 UTIME_TO_TIMEVAL;
4795 return utimes(path, time);
4796#elif defined(HAVE_UTIME_H)
4797 UTIME_TO_UTIMBUF;
4798 return utime(path, time);
4799#else
4800 UTIME_TO_TIME_T;
4801 return utime(path, time);
4802#endif
4803}
4804
4805#endif
4806
Larry Hastings76ad59b2012-05-03 00:30:07 -07004807static int
4808split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4809{
4810 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004811 PyObject *divmod;
Eddie Elizondob3966632019-11-05 07:16:14 -08004812 divmod = PyNumber_Divmod(py_long, _posixstate_global->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07004813 if (!divmod)
4814 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004815 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4816 PyErr_Format(PyExc_TypeError,
4817 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08004818 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004819 goto exit;
4820 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004821 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4822 if ((*s == -1) && PyErr_Occurred())
4823 goto exit;
4824 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004825 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004826 goto exit;
4827
4828 result = 1;
4829exit:
4830 Py_XDECREF(divmod);
4831 return result;
4832}
4833
Larry Hastings2f936352014-08-05 14:04:04 +10004834
4835/*[clinic input]
4836os.utime
4837
4838 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004839 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10004840 *
4841 ns: object = NULL
4842 dir_fd: dir_fd(requires='futimensat') = None
4843 follow_symlinks: bool=True
4844
Martin Panter0ff89092015-09-09 01:56:53 +00004845# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004846
4847Set the access and modified time of path.
4848
4849path may always be specified as a string.
4850On some platforms, path may also be specified as an open file descriptor.
4851 If this functionality is unavailable, using it raises an exception.
4852
4853If times is not None, it must be a tuple (atime, mtime);
4854 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004855If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004856 atime_ns and mtime_ns should be expressed as integer nanoseconds
4857 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004858If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004859Specifying tuples for both times and ns is an error.
4860
4861If dir_fd is not None, it should be a file descriptor open to a directory,
4862 and path should be relative; path will then be relative to that directory.
4863If follow_symlinks is False, and the last element of the path is a symbolic
4864 link, utime will modify the symbolic link itself instead of the file the
4865 link points to.
4866It is an error to use dir_fd or follow_symlinks when specifying path
4867 as an open file descriptor.
4868dir_fd and follow_symlinks may not be available on your platform.
4869 If they are unavailable, using them will raise a NotImplementedError.
4870
4871[clinic start generated code]*/
4872
Larry Hastings2f936352014-08-05 14:04:04 +10004873static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004874os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4875 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004876/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004877{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004878#ifdef MS_WINDOWS
4879 HANDLE hFile;
4880 FILETIME atime, mtime;
4881#else
4882 int result;
4883#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004884
Larry Hastings2f936352014-08-05 14:04:04 +10004885 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004886
Christian Heimesb3c87242013-08-01 00:08:16 +02004887 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004888
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004889 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004890 PyErr_SetString(PyExc_ValueError,
4891 "utime: you may specify either 'times'"
4892 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004893 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004894 }
4895
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004896 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004897 time_t a_sec, m_sec;
4898 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004899 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004900 PyErr_SetString(PyExc_TypeError,
4901 "utime: 'times' must be either"
4902 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004903 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004904 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004905 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004906 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004907 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004908 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004909 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004910 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004911 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004912 utime.atime_s = a_sec;
4913 utime.atime_ns = a_nsec;
4914 utime.mtime_s = m_sec;
4915 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004916 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004917 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004918 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004919 PyErr_SetString(PyExc_TypeError,
4920 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004921 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004922 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004923 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004924 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004925 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004926 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004927 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004928 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004929 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004930 }
4931 else {
4932 /* times and ns are both None/unspecified. use "now". */
4933 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004934 }
4935
Victor Stinner4552ced2015-09-21 22:37:15 +02004936#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004937 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004938 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004939#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004940
Larry Hastings2f936352014-08-05 14:04:04 +10004941 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4942 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4943 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004944 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004945
Larry Hastings9cf065c2012-06-22 16:30:09 -07004946#if !defined(HAVE_UTIMENSAT)
4947 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004948 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004949 "utime: cannot use dir_fd and follow_symlinks "
4950 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004951 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004952 }
4953#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004954
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004955#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004956 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004957 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4958 NULL, OPEN_EXISTING,
4959 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004960 Py_END_ALLOW_THREADS
4961 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004962 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004963 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004964 }
4965
Larry Hastings9cf065c2012-06-22 16:30:09 -07004966 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004967 GetSystemTimeAsFileTime(&mtime);
4968 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004970 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004971 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4972 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 }
4974 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4975 /* Avoid putting the file name into the error here,
4976 as that may confuse the user into believing that
4977 something is wrong with the file, when it also
4978 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004979 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004980 CloseHandle(hFile);
4981 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004982 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004983 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004984#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004986
Victor Stinner4552ced2015-09-21 22:37:15 +02004987#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004988 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004989 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004990 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004991#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004992
Victor Stinner528a9ab2015-09-03 21:30:26 +02004993#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004994 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004995 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004996 else
4997#endif
4998
Victor Stinner528a9ab2015-09-03 21:30:26 +02004999#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005000 if (path->fd != -1)
5001 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005002 else
5003#endif
5004
Larry Hastings2f936352014-08-05 14:04:04 +10005005 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005006
5007 Py_END_ALLOW_THREADS
5008
5009 if (result < 0) {
5010 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005011 posix_error();
5012 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005013 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005014
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005015#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005016
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005017 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005018}
5019
Guido van Rossum3b066191991-06-04 19:40:25 +00005020/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005021
Larry Hastings2f936352014-08-05 14:04:04 +10005022
5023/*[clinic input]
5024os._exit
5025
5026 status: int
5027
5028Exit to the system with specified status, without normal exit processing.
5029[clinic start generated code]*/
5030
Larry Hastings2f936352014-08-05 14:04:04 +10005031static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005032os__exit_impl(PyObject *module, int status)
5033/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005034{
5035 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005036 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005037}
5038
Steve Dowercc16be82016-09-08 10:35:16 -07005039#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5040#define EXECV_CHAR wchar_t
5041#else
5042#define EXECV_CHAR char
5043#endif
5044
pxinwrf2d7ac72019-05-21 18:46:37 +08005045#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005046static void
Steve Dowercc16be82016-09-08 10:35:16 -07005047free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005048{
Victor Stinner8c62be82010-05-06 00:08:46 +00005049 Py_ssize_t i;
5050 for (i = 0; i < count; i++)
5051 PyMem_Free(array[i]);
5052 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005053}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005054
Berker Peksag81816462016-09-15 20:19:47 +03005055static int
5056fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005057{
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005059 PyObject *ub;
5060 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005061#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005062 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005063 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005064 *out = PyUnicode_AsWideCharString(ub, &size);
5065 if (*out)
5066 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005067#else
Berker Peksag81816462016-09-15 20:19:47 +03005068 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005069 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005070 size = PyBytes_GET_SIZE(ub);
5071 *out = PyMem_Malloc(size + 1);
5072 if (*out) {
5073 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5074 result = 1;
5075 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005076 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005077#endif
Berker Peksag81816462016-09-15 20:19:47 +03005078 Py_DECREF(ub);
5079 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005080}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005081#endif
5082
pxinwrf2d7ac72019-05-21 18:46:37 +08005083#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005084static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005085parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5086{
Victor Stinner8c62be82010-05-06 00:08:46 +00005087 Py_ssize_t i, pos, envc;
5088 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005089 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005090 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005091
Victor Stinner8c62be82010-05-06 00:08:46 +00005092 i = PyMapping_Size(env);
5093 if (i < 0)
5094 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005095 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005096 if (envlist == NULL) {
5097 PyErr_NoMemory();
5098 return NULL;
5099 }
5100 envc = 0;
5101 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005102 if (!keys)
5103 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005104 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005105 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005106 goto error;
5107 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5108 PyErr_Format(PyExc_TypeError,
5109 "env.keys() or env.values() is not a list");
5110 goto error;
5111 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005112
Victor Stinner8c62be82010-05-06 00:08:46 +00005113 for (pos = 0; pos < i; pos++) {
5114 key = PyList_GetItem(keys, pos);
5115 val = PyList_GetItem(vals, pos);
5116 if (!key || !val)
5117 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005118
Berker Peksag81816462016-09-15 20:19:47 +03005119#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5120 if (!PyUnicode_FSDecoder(key, &key2))
5121 goto error;
5122 if (!PyUnicode_FSDecoder(val, &val2)) {
5123 Py_DECREF(key2);
5124 goto error;
5125 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005126 /* Search from index 1 because on Windows starting '=' is allowed for
5127 defining hidden environment variables. */
5128 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5129 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5130 {
5131 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005132 Py_DECREF(key2);
5133 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005134 goto error;
5135 }
Berker Peksag81816462016-09-15 20:19:47 +03005136 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5137#else
5138 if (!PyUnicode_FSConverter(key, &key2))
5139 goto error;
5140 if (!PyUnicode_FSConverter(val, &val2)) {
5141 Py_DECREF(key2);
5142 goto error;
5143 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005144 if (PyBytes_GET_SIZE(key2) == 0 ||
5145 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5146 {
5147 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005148 Py_DECREF(key2);
5149 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005150 goto error;
5151 }
Berker Peksag81816462016-09-15 20:19:47 +03005152 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5153 PyBytes_AS_STRING(val2));
5154#endif
5155 Py_DECREF(key2);
5156 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005157 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005158 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005159
5160 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5161 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005162 goto error;
5163 }
Berker Peksag81816462016-09-15 20:19:47 +03005164
Steve Dowercc16be82016-09-08 10:35:16 -07005165 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 }
5167 Py_DECREF(vals);
5168 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005169
Victor Stinner8c62be82010-05-06 00:08:46 +00005170 envlist[envc] = 0;
5171 *envc_ptr = envc;
5172 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005173
5174error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 Py_XDECREF(keys);
5176 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005177 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005178 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005179}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005180
Steve Dowercc16be82016-09-08 10:35:16 -07005181static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005182parse_arglist(PyObject* argv, Py_ssize_t *argc)
5183{
5184 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005185 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005186 if (argvlist == NULL) {
5187 PyErr_NoMemory();
5188 return NULL;
5189 }
5190 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005191 PyObject* item = PySequence_ITEM(argv, i);
5192 if (item == NULL)
5193 goto fail;
5194 if (!fsconvert_strdup(item, &argvlist[i])) {
5195 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005196 goto fail;
5197 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005198 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005199 }
5200 argvlist[*argc] = NULL;
5201 return argvlist;
5202fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005203 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005204 free_string_array(argvlist, *argc);
5205 return NULL;
5206}
Steve Dowercc16be82016-09-08 10:35:16 -07005207
Ross Lagerwall7807c352011-03-17 20:20:30 +02005208#endif
5209
Larry Hastings2f936352014-08-05 14:04:04 +10005210
Ross Lagerwall7807c352011-03-17 20:20:30 +02005211#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005212/*[clinic input]
5213os.execv
5214
Steve Dowercc16be82016-09-08 10:35:16 -07005215 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005216 Path of executable file.
5217 argv: object
5218 Tuple or list of strings.
5219 /
5220
5221Execute an executable path with arguments, replacing current process.
5222[clinic start generated code]*/
5223
Larry Hastings2f936352014-08-05 14:04:04 +10005224static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005225os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5226/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005227{
Steve Dowercc16be82016-09-08 10:35:16 -07005228 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005229 Py_ssize_t argc;
5230
5231 /* execv has two arguments: (path, argv), where
5232 argv is a list or tuple of strings. */
5233
Ross Lagerwall7807c352011-03-17 20:20:30 +02005234 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5235 PyErr_SetString(PyExc_TypeError,
5236 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005237 return NULL;
5238 }
5239 argc = PySequence_Size(argv);
5240 if (argc < 1) {
5241 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005242 return NULL;
5243 }
5244
5245 argvlist = parse_arglist(argv, &argc);
5246 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005247 return NULL;
5248 }
Steve Dowerbce26262016-11-19 19:17:26 -08005249 if (!argvlist[0][0]) {
5250 PyErr_SetString(PyExc_ValueError,
5251 "execv() arg 2 first element cannot be empty");
5252 free_string_array(argvlist, argc);
5253 return NULL;
5254 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005255
Steve Dowerbce26262016-11-19 19:17:26 -08005256 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005257#ifdef HAVE_WEXECV
5258 _wexecv(path->wide, argvlist);
5259#else
5260 execv(path->narrow, argvlist);
5261#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005262 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005263
5264 /* If we get here it's definitely an error */
5265
5266 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005267 return posix_error();
5268}
5269
Larry Hastings2f936352014-08-05 14:04:04 +10005270
5271/*[clinic input]
5272os.execve
5273
5274 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5275 Path of executable file.
5276 argv: object
5277 Tuple or list of strings.
5278 env: object
5279 Dictionary of strings mapping to strings.
5280
5281Execute an executable path with arguments, replacing current process.
5282[clinic start generated code]*/
5283
Larry Hastings2f936352014-08-05 14:04:04 +10005284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005285os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5286/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005287{
Steve Dowercc16be82016-09-08 10:35:16 -07005288 EXECV_CHAR **argvlist = NULL;
5289 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005290 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005291
Victor Stinner8c62be82010-05-06 00:08:46 +00005292 /* execve has three arguments: (path, argv, env), where
5293 argv is a list or tuple of strings and env is a dictionary
5294 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005295
Ross Lagerwall7807c352011-03-17 20:20:30 +02005296 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005298 "execve: argv must be a tuple or list");
5299 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005300 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005301 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005302 if (argc < 1) {
5303 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5304 return NULL;
5305 }
5306
Victor Stinner8c62be82010-05-06 00:08:46 +00005307 if (!PyMapping_Check(env)) {
5308 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005309 "execve: environment must be a mapping object");
5310 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005311 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005312
Ross Lagerwall7807c352011-03-17 20:20:30 +02005313 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005315 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005316 }
Steve Dowerbce26262016-11-19 19:17:26 -08005317 if (!argvlist[0][0]) {
5318 PyErr_SetString(PyExc_ValueError,
5319 "execve: argv first element cannot be empty");
5320 goto fail;
5321 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005322
Victor Stinner8c62be82010-05-06 00:08:46 +00005323 envlist = parse_envlist(env, &envc);
5324 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005325 goto fail;
5326
Steve Dowerbce26262016-11-19 19:17:26 -08005327 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005328#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005329 if (path->fd > -1)
5330 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005331 else
5332#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005333#ifdef HAVE_WEXECV
5334 _wexecve(path->wide, argvlist, envlist);
5335#else
Larry Hastings2f936352014-08-05 14:04:04 +10005336 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005337#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005338 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005339
5340 /* If we get here it's definitely an error */
5341
Alexey Izbyshev83460312018-10-20 03:28:22 +03005342 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005343
Steve Dowercc16be82016-09-08 10:35:16 -07005344 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005345 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005346 if (argvlist)
5347 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005348 return NULL;
5349}
Steve Dowercc16be82016-09-08 10:35:16 -07005350
Larry Hastings9cf065c2012-06-22 16:30:09 -07005351#endif /* HAVE_EXECV */
5352
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005353#ifdef HAVE_POSIX_SPAWN
5354
5355enum posix_spawn_file_actions_identifier {
5356 POSIX_SPAWN_OPEN,
5357 POSIX_SPAWN_CLOSE,
5358 POSIX_SPAWN_DUP2
5359};
5360
William Orr81574b82018-10-01 22:19:56 -07005361#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005362static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005363convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005364#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005365
5366static int
Victor Stinner325e4ba2019-02-01 15:47:24 +01005367parse_posix_spawn_flags(const char *func_name, PyObject *setpgroup,
5368 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005369 PyObject *setsigdef, PyObject *scheduler,
5370 posix_spawnattr_t *attrp)
5371{
5372 long all_flags = 0;
5373
5374 errno = posix_spawnattr_init(attrp);
5375 if (errno) {
5376 posix_error();
5377 return -1;
5378 }
5379
5380 if (setpgroup) {
5381 pid_t pgid = PyLong_AsPid(setpgroup);
5382 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5383 goto fail;
5384 }
5385 errno = posix_spawnattr_setpgroup(attrp, pgid);
5386 if (errno) {
5387 posix_error();
5388 goto fail;
5389 }
5390 all_flags |= POSIX_SPAWN_SETPGROUP;
5391 }
5392
5393 if (resetids) {
5394 all_flags |= POSIX_SPAWN_RESETIDS;
5395 }
5396
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005397 if (setsid) {
5398#ifdef POSIX_SPAWN_SETSID
5399 all_flags |= POSIX_SPAWN_SETSID;
5400#elif defined(POSIX_SPAWN_SETSID_NP)
5401 all_flags |= POSIX_SPAWN_SETSID_NP;
5402#else
5403 argument_unavailable_error(func_name, "setsid");
5404 return -1;
5405#endif
5406 }
5407
Pablo Galindo254a4662018-09-07 16:44:24 +01005408 if (setsigmask) {
5409 sigset_t set;
5410 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5411 goto fail;
5412 }
5413 errno = posix_spawnattr_setsigmask(attrp, &set);
5414 if (errno) {
5415 posix_error();
5416 goto fail;
5417 }
5418 all_flags |= POSIX_SPAWN_SETSIGMASK;
5419 }
5420
5421 if (setsigdef) {
5422 sigset_t set;
5423 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5424 goto fail;
5425 }
5426 errno = posix_spawnattr_setsigdefault(attrp, &set);
5427 if (errno) {
5428 posix_error();
5429 goto fail;
5430 }
5431 all_flags |= POSIX_SPAWN_SETSIGDEF;
5432 }
5433
5434 if (scheduler) {
5435#ifdef POSIX_SPAWN_SETSCHEDULER
5436 PyObject *py_schedpolicy;
5437 struct sched_param schedparam;
5438
5439 if (!PyArg_ParseTuple(scheduler, "OO&"
5440 ";A scheduler tuple must have two elements",
5441 &py_schedpolicy, convert_sched_param, &schedparam)) {
5442 goto fail;
5443 }
5444 if (py_schedpolicy != Py_None) {
5445 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5446
5447 if (schedpolicy == -1 && PyErr_Occurred()) {
5448 goto fail;
5449 }
5450 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5451 if (errno) {
5452 posix_error();
5453 goto fail;
5454 }
5455 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5456 }
5457 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5458 if (errno) {
5459 posix_error();
5460 goto fail;
5461 }
5462 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5463#else
5464 PyErr_SetString(PyExc_NotImplementedError,
5465 "The scheduler option is not supported in this system.");
5466 goto fail;
5467#endif
5468 }
5469
5470 errno = posix_spawnattr_setflags(attrp, all_flags);
5471 if (errno) {
5472 posix_error();
5473 goto fail;
5474 }
5475
5476 return 0;
5477
5478fail:
5479 (void)posix_spawnattr_destroy(attrp);
5480 return -1;
5481}
5482
5483static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005484parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005485 posix_spawn_file_actions_t *file_actionsp,
5486 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005487{
5488 PyObject *seq;
5489 PyObject *file_action = NULL;
5490 PyObject *tag_obj;
5491
5492 seq = PySequence_Fast(file_actions,
5493 "file_actions must be a sequence or None");
5494 if (seq == NULL) {
5495 return -1;
5496 }
5497
5498 errno = posix_spawn_file_actions_init(file_actionsp);
5499 if (errno) {
5500 posix_error();
5501 Py_DECREF(seq);
5502 return -1;
5503 }
5504
Zackery Spytzd52a83a2019-06-26 14:54:20 -06005505 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03005506 file_action = PySequence_Fast_GET_ITEM(seq, i);
5507 Py_INCREF(file_action);
5508 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5509 PyErr_SetString(PyExc_TypeError,
5510 "Each file_actions element must be a non-empty tuple");
5511 goto fail;
5512 }
5513 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5514 if (tag == -1 && PyErr_Occurred()) {
5515 goto fail;
5516 }
5517
5518 /* Populate the file_actions object */
5519 switch (tag) {
5520 case POSIX_SPAWN_OPEN: {
5521 int fd, oflag;
5522 PyObject *path;
5523 unsigned long mode;
5524 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5525 ";A open file_action tuple must have 5 elements",
5526 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5527 &oflag, &mode))
5528 {
5529 goto fail;
5530 }
Pablo Galindocb970732018-06-19 09:19:50 +01005531 if (PyList_Append(temp_buffer, path)) {
5532 Py_DECREF(path);
5533 goto fail;
5534 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005535 errno = posix_spawn_file_actions_addopen(file_actionsp,
5536 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005537 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005538 if (errno) {
5539 posix_error();
5540 goto fail;
5541 }
5542 break;
5543 }
5544 case POSIX_SPAWN_CLOSE: {
5545 int fd;
5546 if (!PyArg_ParseTuple(file_action, "Oi"
5547 ";A close file_action tuple must have 2 elements",
5548 &tag_obj, &fd))
5549 {
5550 goto fail;
5551 }
5552 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5553 if (errno) {
5554 posix_error();
5555 goto fail;
5556 }
5557 break;
5558 }
5559 case POSIX_SPAWN_DUP2: {
5560 int fd1, fd2;
5561 if (!PyArg_ParseTuple(file_action, "Oii"
5562 ";A dup2 file_action tuple must have 3 elements",
5563 &tag_obj, &fd1, &fd2))
5564 {
5565 goto fail;
5566 }
5567 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5568 fd1, fd2);
5569 if (errno) {
5570 posix_error();
5571 goto fail;
5572 }
5573 break;
5574 }
5575 default: {
5576 PyErr_SetString(PyExc_TypeError,
5577 "Unknown file_actions identifier");
5578 goto fail;
5579 }
5580 }
5581 Py_DECREF(file_action);
5582 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005583
Serhiy Storchakaef347532018-05-01 16:45:04 +03005584 Py_DECREF(seq);
5585 return 0;
5586
5587fail:
5588 Py_DECREF(seq);
5589 Py_DECREF(file_action);
5590 (void)posix_spawn_file_actions_destroy(file_actionsp);
5591 return -1;
5592}
5593
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005594
5595static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005596py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5597 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005598 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005599 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005600{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005601 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005602 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005603 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005604 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005605 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005606 posix_spawnattr_t attr;
5607 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005608 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005609 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005610 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005611 pid_t pid;
5612 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005613
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005614 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005615 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005616 like posix.environ. */
5617
Serhiy Storchakaef347532018-05-01 16:45:04 +03005618 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005619 PyErr_Format(PyExc_TypeError,
5620 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005621 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005622 }
5623 argc = PySequence_Size(argv);
5624 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005625 PyErr_Format(PyExc_ValueError,
5626 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005627 return NULL;
5628 }
5629
5630 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005631 PyErr_Format(PyExc_TypeError,
5632 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005633 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005634 }
5635
5636 argvlist = parse_arglist(argv, &argc);
5637 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005638 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005639 }
5640 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005641 PyErr_Format(PyExc_ValueError,
5642 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005643 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005644 }
5645
5646 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005647 if (envlist == NULL) {
5648 goto exit;
5649 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005650
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005651 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005652 /* There is a bug in old versions of glibc that makes some of the
5653 * helper functions for manipulating file actions not copy the provided
5654 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5655 * copy the value of path for some old versions of glibc (<2.20).
5656 * The use of temp_buffer here is a workaround that keeps the
5657 * python objects that own the buffers alive until posix_spawn gets called.
5658 * Check https://bugs.python.org/issue33630 and
5659 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5660 temp_buffer = PyList_New(0);
5661 if (!temp_buffer) {
5662 goto exit;
5663 }
5664 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005665 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005666 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005667 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005668 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005669
Victor Stinner325e4ba2019-02-01 15:47:24 +01005670 if (parse_posix_spawn_flags(func_name, setpgroup, resetids, setsid,
5671 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005672 goto exit;
5673 }
5674 attrp = &attr;
5675
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005676 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005677#ifdef HAVE_POSIX_SPAWNP
5678 if (use_posix_spawnp) {
5679 err_code = posix_spawnp(&pid, path->narrow,
5680 file_actionsp, attrp, argvlist, envlist);
5681 }
5682 else
5683#endif /* HAVE_POSIX_SPAWNP */
5684 {
5685 err_code = posix_spawn(&pid, path->narrow,
5686 file_actionsp, attrp, argvlist, envlist);
5687 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005688 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005689
Serhiy Storchakaef347532018-05-01 16:45:04 +03005690 if (err_code) {
5691 errno = err_code;
5692 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005693 goto exit;
5694 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005695#ifdef _Py_MEMORY_SANITIZER
5696 __msan_unpoison(&pid, sizeof(pid));
5697#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005698 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005699
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005700exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005701 if (file_actionsp) {
5702 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005703 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005704 if (attrp) {
5705 (void)posix_spawnattr_destroy(attrp);
5706 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005707 if (envlist) {
5708 free_string_array(envlist, envc);
5709 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005710 if (argvlist) {
5711 free_string_array(argvlist, argc);
5712 }
Pablo Galindocb970732018-06-19 09:19:50 +01005713 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005714 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005715}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005716
5717
5718/*[clinic input]
5719
5720os.posix_spawn
5721 path: path_t
5722 Path of executable file.
5723 argv: object
5724 Tuple or list of strings.
5725 env: object
5726 Dictionary of strings mapping to strings.
5727 /
5728 *
5729 file_actions: object(c_default='NULL') = ()
5730 A sequence of file action tuples.
5731 setpgroup: object = NULL
5732 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5733 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005734 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5735 setsid: bool(accept={int}) = False
5736 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005737 setsigmask: object(c_default='NULL') = ()
5738 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5739 setsigdef: object(c_default='NULL') = ()
5740 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5741 scheduler: object = NULL
5742 A tuple with the scheduler policy (optional) and parameters.
5743
5744Execute the program specified by path in a new process.
5745[clinic start generated code]*/
5746
5747static PyObject *
5748os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5749 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005750 PyObject *setpgroup, int resetids, int setsid,
5751 PyObject *setsigmask, PyObject *setsigdef,
5752 PyObject *scheduler)
5753/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005754{
5755 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005756 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005757 scheduler);
5758}
5759 #endif /* HAVE_POSIX_SPAWN */
5760
5761
5762
5763#ifdef HAVE_POSIX_SPAWNP
5764/*[clinic input]
5765
5766os.posix_spawnp
5767 path: path_t
5768 Path of executable file.
5769 argv: object
5770 Tuple or list of strings.
5771 env: object
5772 Dictionary of strings mapping to strings.
5773 /
5774 *
5775 file_actions: object(c_default='NULL') = ()
5776 A sequence of file action tuples.
5777 setpgroup: object = NULL
5778 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5779 resetids: bool(accept={int}) = False
5780 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005781 setsid: bool(accept={int}) = False
5782 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005783 setsigmask: object(c_default='NULL') = ()
5784 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5785 setsigdef: object(c_default='NULL') = ()
5786 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5787 scheduler: object = NULL
5788 A tuple with the scheduler policy (optional) and parameters.
5789
5790Execute the program specified by path in a new process.
5791[clinic start generated code]*/
5792
5793static PyObject *
5794os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5795 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005796 PyObject *setpgroup, int resetids, int setsid,
5797 PyObject *setsigmask, PyObject *setsigdef,
5798 PyObject *scheduler)
5799/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005800{
5801 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005802 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005803 scheduler);
5804}
5805#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005806
pxinwrf2d7ac72019-05-21 18:46:37 +08005807#ifdef HAVE_RTPSPAWN
5808static intptr_t
5809_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5810 const char *envp[])
5811{
5812 RTP_ID rtpid;
5813 int status;
5814 pid_t res;
5815 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005816
pxinwrf2d7ac72019-05-21 18:46:37 +08005817 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5818 uStackSize=0 cannot be used, the default stack size is too small for
5819 Python. */
5820 if (envp) {
5821 rtpid = rtpSpawn(rtpFileName, argv, envp,
5822 100, 0x1000000, 0, VX_FP_TASK);
5823 }
5824 else {
5825 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5826 100, 0x1000000, 0, VX_FP_TASK);
5827 }
5828 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5829 do {
5830 res = waitpid((pid_t)rtpid, &status, 0);
5831 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5832
5833 if (res < 0)
5834 return RTP_ID_ERROR;
5835 return ((intptr_t)status);
5836 }
5837 return ((intptr_t)rtpid);
5838}
5839#endif
5840
5841#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10005842/*[clinic input]
5843os.spawnv
5844
5845 mode: int
5846 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005847 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005848 Path of executable file.
5849 argv: object
5850 Tuple or list of strings.
5851 /
5852
5853Execute the program specified by path in a new process.
5854[clinic start generated code]*/
5855
Larry Hastings2f936352014-08-05 14:04:04 +10005856static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005857os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5858/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005859{
Steve Dowercc16be82016-09-08 10:35:16 -07005860 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005861 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005862 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005863 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005864 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005865
Victor Stinner8c62be82010-05-06 00:08:46 +00005866 /* spawnv has three arguments: (mode, path, argv), where
5867 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005868
Victor Stinner8c62be82010-05-06 00:08:46 +00005869 if (PyList_Check(argv)) {
5870 argc = PyList_Size(argv);
5871 getitem = PyList_GetItem;
5872 }
5873 else if (PyTuple_Check(argv)) {
5874 argc = PyTuple_Size(argv);
5875 getitem = PyTuple_GetItem;
5876 }
5877 else {
5878 PyErr_SetString(PyExc_TypeError,
5879 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005880 return NULL;
5881 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005882 if (argc == 0) {
5883 PyErr_SetString(PyExc_ValueError,
5884 "spawnv() arg 2 cannot be empty");
5885 return NULL;
5886 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005887
Steve Dowercc16be82016-09-08 10:35:16 -07005888 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005889 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005890 return PyErr_NoMemory();
5891 }
5892 for (i = 0; i < argc; i++) {
5893 if (!fsconvert_strdup((*getitem)(argv, i),
5894 &argvlist[i])) {
5895 free_string_array(argvlist, i);
5896 PyErr_SetString(
5897 PyExc_TypeError,
5898 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005899 return NULL;
5900 }
Steve Dower93ff8722016-11-19 19:03:54 -08005901 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005902 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005903 PyErr_SetString(
5904 PyExc_ValueError,
5905 "spawnv() arg 2 first element cannot be empty");
5906 return NULL;
5907 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005908 }
5909 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005910
pxinwrf2d7ac72019-05-21 18:46:37 +08005911#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 if (mode == _OLD_P_OVERLAY)
5913 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005914#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005915
Victor Stinner8c62be82010-05-06 00:08:46 +00005916 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005917 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005918#ifdef HAVE_WSPAWNV
5919 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005920#elif defined(HAVE_RTPSPAWN)
5921 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07005922#else
5923 spawnval = _spawnv(mode, path->narrow, argvlist);
5924#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005925 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005926 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005927
Victor Stinner8c62be82010-05-06 00:08:46 +00005928 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005929
Victor Stinner8c62be82010-05-06 00:08:46 +00005930 if (spawnval == -1)
5931 return posix_error();
5932 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005933 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005934}
5935
Larry Hastings2f936352014-08-05 14:04:04 +10005936/*[clinic input]
5937os.spawnve
5938
5939 mode: int
5940 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005941 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005942 Path of executable file.
5943 argv: object
5944 Tuple or list of strings.
5945 env: object
5946 Dictionary of strings mapping to strings.
5947 /
5948
5949Execute the program specified by path in a new process.
5950[clinic start generated code]*/
5951
Larry Hastings2f936352014-08-05 14:04:04 +10005952static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005953os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005954 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005955/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005956{
Steve Dowercc16be82016-09-08 10:35:16 -07005957 EXECV_CHAR **argvlist;
5958 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005959 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005960 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005961 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005962 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005963 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005964
Victor Stinner8c62be82010-05-06 00:08:46 +00005965 /* spawnve has four arguments: (mode, path, argv, env), where
5966 argv is a list or tuple of strings and env is a dictionary
5967 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005968
Victor Stinner8c62be82010-05-06 00:08:46 +00005969 if (PyList_Check(argv)) {
5970 argc = PyList_Size(argv);
5971 getitem = PyList_GetItem;
5972 }
5973 else if (PyTuple_Check(argv)) {
5974 argc = PyTuple_Size(argv);
5975 getitem = PyTuple_GetItem;
5976 }
5977 else {
5978 PyErr_SetString(PyExc_TypeError,
5979 "spawnve() arg 2 must be a tuple or list");
5980 goto fail_0;
5981 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005982 if (argc == 0) {
5983 PyErr_SetString(PyExc_ValueError,
5984 "spawnve() arg 2 cannot be empty");
5985 goto fail_0;
5986 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005987 if (!PyMapping_Check(env)) {
5988 PyErr_SetString(PyExc_TypeError,
5989 "spawnve() arg 3 must be a mapping object");
5990 goto fail_0;
5991 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005992
Steve Dowercc16be82016-09-08 10:35:16 -07005993 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005994 if (argvlist == NULL) {
5995 PyErr_NoMemory();
5996 goto fail_0;
5997 }
5998 for (i = 0; i < argc; i++) {
5999 if (!fsconvert_strdup((*getitem)(argv, i),
6000 &argvlist[i]))
6001 {
6002 lastarg = i;
6003 goto fail_1;
6004 }
Steve Dowerbce26262016-11-19 19:17:26 -08006005 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006006 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006007 PyErr_SetString(
6008 PyExc_ValueError,
6009 "spawnv() arg 2 first element cannot be empty");
6010 goto fail_1;
6011 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006012 }
6013 lastarg = argc;
6014 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006015
Victor Stinner8c62be82010-05-06 00:08:46 +00006016 envlist = parse_envlist(env, &envc);
6017 if (envlist == NULL)
6018 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006019
pxinwrf2d7ac72019-05-21 18:46:37 +08006020#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006021 if (mode == _OLD_P_OVERLAY)
6022 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006023#endif
Tim Peters25059d32001-12-07 20:35:43 +00006024
Victor Stinner8c62be82010-05-06 00:08:46 +00006025 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006026 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006027#ifdef HAVE_WSPAWNV
6028 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006029#elif defined(HAVE_RTPSPAWN)
6030 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6031 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006032#else
6033 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6034#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006035 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006037
Victor Stinner8c62be82010-05-06 00:08:46 +00006038 if (spawnval == -1)
6039 (void) posix_error();
6040 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006041 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006042
Victor Stinner8c62be82010-05-06 00:08:46 +00006043 while (--envc >= 0)
6044 PyMem_DEL(envlist[envc]);
6045 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006046 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006047 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006048 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006049 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006050}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006051
Guido van Rossuma1065681999-01-25 23:20:23 +00006052#endif /* HAVE_SPAWNV */
6053
6054
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006055#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006056
6057/* Helper function to validate arguments.
6058 Returns 0 on success. non-zero on failure with a TypeError raised.
6059 If obj is non-NULL it must be callable. */
6060static int
6061check_null_or_callable(PyObject *obj, const char* obj_name)
6062{
6063 if (obj && !PyCallable_Check(obj)) {
6064 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006065 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006066 return -1;
6067 }
6068 return 0;
6069}
6070
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006071/*[clinic input]
6072os.register_at_fork
6073
Gregory P. Smith163468a2017-05-29 10:03:41 -07006074 *
6075 before: object=NULL
6076 A callable to be called in the parent before the fork() syscall.
6077 after_in_child: object=NULL
6078 A callable to be called in the child after fork().
6079 after_in_parent: object=NULL
6080 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006081
Gregory P. Smith163468a2017-05-29 10:03:41 -07006082Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006083
Gregory P. Smith163468a2017-05-29 10:03:41 -07006084'before' callbacks are called in reverse order.
6085'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006086
6087[clinic start generated code]*/
6088
6089static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006090os_register_at_fork_impl(PyObject *module, PyObject *before,
6091 PyObject *after_in_child, PyObject *after_in_parent)
6092/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006093{
6094 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006095
Gregory P. Smith163468a2017-05-29 10:03:41 -07006096 if (!before && !after_in_child && !after_in_parent) {
6097 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6098 return NULL;
6099 }
6100 if (check_null_or_callable(before, "before") ||
6101 check_null_or_callable(after_in_child, "after_in_child") ||
6102 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006103 return NULL;
6104 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02006105 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006106
Gregory P. Smith163468a2017-05-29 10:03:41 -07006107 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006108 return NULL;
6109 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006110 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006111 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006112 }
6113 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6114 return NULL;
6115 }
6116 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006117}
6118#endif /* HAVE_FORK */
6119
6120
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006121#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006122/*[clinic input]
6123os.fork1
6124
6125Fork a child process with a single multiplexed (i.e., not bound) thread.
6126
6127Return 0 to child process and PID of child to parent process.
6128[clinic start generated code]*/
6129
Larry Hastings2f936352014-08-05 14:04:04 +10006130static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006131os_fork1_impl(PyObject *module)
6132/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006133{
Victor Stinner8c62be82010-05-06 00:08:46 +00006134 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006135
Eric Snow59032962018-09-14 14:17:20 -07006136 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6137 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6138 return NULL;
6139 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006140 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006141 pid = fork1();
6142 if (pid == 0) {
6143 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006144 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006145 } else {
6146 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006147 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006148 }
6149 if (pid == -1)
6150 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006151 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006152}
Larry Hastings2f936352014-08-05 14:04:04 +10006153#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006154
6155
Guido van Rossumad0ee831995-03-01 10:34:45 +00006156#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006157/*[clinic input]
6158os.fork
6159
6160Fork a child process.
6161
6162Return 0 to child process and PID of child to parent process.
6163[clinic start generated code]*/
6164
Larry Hastings2f936352014-08-05 14:04:04 +10006165static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006166os_fork_impl(PyObject *module)
6167/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006168{
Victor Stinner8c62be82010-05-06 00:08:46 +00006169 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006170
Eric Snow59032962018-09-14 14:17:20 -07006171 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6172 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6173 return NULL;
6174 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006175 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006176 pid = fork();
6177 if (pid == 0) {
6178 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006179 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006180 } else {
6181 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006182 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006183 }
6184 if (pid == -1)
6185 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006186 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006187}
Larry Hastings2f936352014-08-05 14:04:04 +10006188#endif /* HAVE_FORK */
6189
Guido van Rossum85e3b011991-06-03 12:42:10 +00006190
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006191#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006192#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006193/*[clinic input]
6194os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006195
Larry Hastings2f936352014-08-05 14:04:04 +10006196 policy: int
6197
6198Get the maximum scheduling priority for policy.
6199[clinic start generated code]*/
6200
Larry Hastings2f936352014-08-05 14:04:04 +10006201static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006202os_sched_get_priority_max_impl(PyObject *module, int policy)
6203/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006204{
6205 int max;
6206
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006207 max = sched_get_priority_max(policy);
6208 if (max < 0)
6209 return posix_error();
6210 return PyLong_FromLong(max);
6211}
6212
Larry Hastings2f936352014-08-05 14:04:04 +10006213
6214/*[clinic input]
6215os.sched_get_priority_min
6216
6217 policy: int
6218
6219Get the minimum scheduling priority for policy.
6220[clinic start generated code]*/
6221
Larry Hastings2f936352014-08-05 14:04:04 +10006222static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006223os_sched_get_priority_min_impl(PyObject *module, int policy)
6224/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006225{
6226 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006227 if (min < 0)
6228 return posix_error();
6229 return PyLong_FromLong(min);
6230}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006231#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6232
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006233
Larry Hastings2f936352014-08-05 14:04:04 +10006234#ifdef HAVE_SCHED_SETSCHEDULER
6235/*[clinic input]
6236os.sched_getscheduler
6237 pid: pid_t
6238 /
6239
Min ho Kimc4cacc82019-07-31 08:16:13 +10006240Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006241
6242Passing 0 for pid returns the scheduling policy for the calling process.
6243[clinic start generated code]*/
6244
Larry Hastings2f936352014-08-05 14:04:04 +10006245static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006246os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006247/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006248{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006249 int policy;
6250
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006251 policy = sched_getscheduler(pid);
6252 if (policy < 0)
6253 return posix_error();
6254 return PyLong_FromLong(policy);
6255}
Larry Hastings2f936352014-08-05 14:04:04 +10006256#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006257
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006258
William Orr81574b82018-10-01 22:19:56 -07006259#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006260/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006261class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006262
6263@classmethod
6264os.sched_param.__new__
6265
6266 sched_priority: object
6267 A scheduling parameter.
6268
Eddie Elizondob3966632019-11-05 07:16:14 -08006269Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006270[clinic start generated code]*/
6271
Larry Hastings2f936352014-08-05 14:04:04 +10006272static PyObject *
6273os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006274/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006275{
6276 PyObject *res;
6277
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006278 res = PyStructSequence_New(type);
6279 if (!res)
6280 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006281 Py_INCREF(sched_priority);
6282 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006283 return res;
6284}
6285
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006286PyDoc_VAR(os_sched_param__doc__);
6287
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006288static PyStructSequence_Field sched_param_fields[] = {
6289 {"sched_priority", "the scheduling priority"},
6290 {0}
6291};
6292
6293static PyStructSequence_Desc sched_param_desc = {
6294 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006295 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006296 sched_param_fields,
6297 1
6298};
6299
6300static int
6301convert_sched_param(PyObject *param, struct sched_param *res)
6302{
6303 long priority;
6304
Eddie Elizondob3966632019-11-05 07:16:14 -08006305 PyObject *SchedParamType = _posixstate_global->SchedParamType;
6306 if (Py_TYPE(param) != (PyTypeObject *)SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006307 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6308 return 0;
6309 }
6310 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6311 if (priority == -1 && PyErr_Occurred())
6312 return 0;
6313 if (priority > INT_MAX || priority < INT_MIN) {
6314 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6315 return 0;
6316 }
6317 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6318 return 1;
6319}
William Orr81574b82018-10-01 22:19:56 -07006320#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006321
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006322
6323#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006324/*[clinic input]
6325os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006326
Larry Hastings2f936352014-08-05 14:04:04 +10006327 pid: pid_t
6328 policy: int
6329 param: sched_param
6330 /
6331
6332Set the scheduling policy for the process identified by pid.
6333
6334If pid is 0, the calling process is changed.
6335param is an instance of sched_param.
6336[clinic start generated code]*/
6337
Larry Hastings2f936352014-08-05 14:04:04 +10006338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006339os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006340 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006341/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006342{
Jesus Cea9c822272011-09-10 01:40:52 +02006343 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006344 ** sched_setscheduler() returns 0 in Linux, but the previous
6345 ** scheduling policy under Solaris/Illumos, and others.
6346 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006347 */
Larry Hastings2f936352014-08-05 14:04:04 +10006348 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006349 return posix_error();
6350 Py_RETURN_NONE;
6351}
Larry Hastings2f936352014-08-05 14:04:04 +10006352#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006353
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006354
6355#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006356/*[clinic input]
6357os.sched_getparam
6358 pid: pid_t
6359 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006360
Larry Hastings2f936352014-08-05 14:04:04 +10006361Returns scheduling parameters for the process identified by pid.
6362
6363If pid is 0, returns parameters for the calling process.
6364Return value is an instance of sched_param.
6365[clinic start generated code]*/
6366
Larry Hastings2f936352014-08-05 14:04:04 +10006367static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006368os_sched_getparam_impl(PyObject *module, pid_t pid)
6369/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006370{
6371 struct sched_param param;
6372 PyObject *result;
6373 PyObject *priority;
6374
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006375 if (sched_getparam(pid, &param))
6376 return posix_error();
Eddie Elizondob3966632019-11-05 07:16:14 -08006377 PyObject *SchedParamType = _posixstate_global->SchedParamType;
6378 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006379 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006380 return NULL;
6381 priority = PyLong_FromLong(param.sched_priority);
6382 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006383 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006384 return NULL;
6385 }
Larry Hastings2f936352014-08-05 14:04:04 +10006386 PyStructSequence_SET_ITEM(result, 0, priority);
6387 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006388}
6389
Larry Hastings2f936352014-08-05 14:04:04 +10006390
6391/*[clinic input]
6392os.sched_setparam
6393 pid: pid_t
6394 param: sched_param
6395 /
6396
6397Set scheduling parameters for the process identified by pid.
6398
6399If pid is 0, sets parameters for the calling process.
6400param should be an instance of sched_param.
6401[clinic start generated code]*/
6402
Larry Hastings2f936352014-08-05 14:04:04 +10006403static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006404os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006405 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006406/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006407{
6408 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006409 return posix_error();
6410 Py_RETURN_NONE;
6411}
Larry Hastings2f936352014-08-05 14:04:04 +10006412#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006413
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006414
6415#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006416/*[clinic input]
6417os.sched_rr_get_interval -> double
6418 pid: pid_t
6419 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006420
Larry Hastings2f936352014-08-05 14:04:04 +10006421Return the round-robin quantum for the process identified by pid, in seconds.
6422
6423Value returned is a float.
6424[clinic start generated code]*/
6425
Larry Hastings2f936352014-08-05 14:04:04 +10006426static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006427os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6428/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006429{
6430 struct timespec interval;
6431 if (sched_rr_get_interval(pid, &interval)) {
6432 posix_error();
6433 return -1.0;
6434 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006435#ifdef _Py_MEMORY_SANITIZER
6436 __msan_unpoison(&interval, sizeof(interval));
6437#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006438 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6439}
6440#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006441
Larry Hastings2f936352014-08-05 14:04:04 +10006442
6443/*[clinic input]
6444os.sched_yield
6445
6446Voluntarily relinquish the CPU.
6447[clinic start generated code]*/
6448
Larry Hastings2f936352014-08-05 14:04:04 +10006449static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006450os_sched_yield_impl(PyObject *module)
6451/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006452{
6453 if (sched_yield())
6454 return posix_error();
6455 Py_RETURN_NONE;
6456}
6457
Benjamin Peterson2740af82011-08-02 17:41:34 -05006458#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006459/* The minimum number of CPUs allocated in a cpu_set_t */
6460static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006461
Larry Hastings2f936352014-08-05 14:04:04 +10006462/*[clinic input]
6463os.sched_setaffinity
6464 pid: pid_t
6465 mask : object
6466 /
6467
6468Set the CPU affinity of the process identified by pid to mask.
6469
6470mask should be an iterable of integers identifying CPUs.
6471[clinic start generated code]*/
6472
Larry Hastings2f936352014-08-05 14:04:04 +10006473static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006474os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6475/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006476{
Antoine Pitrou84869872012-08-04 16:16:35 +02006477 int ncpus;
6478 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006479 cpu_set_t *cpu_set = NULL;
6480 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006481
Larry Hastings2f936352014-08-05 14:04:04 +10006482 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006483 if (iterator == NULL)
6484 return NULL;
6485
6486 ncpus = NCPUS_START;
6487 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006488 cpu_set = CPU_ALLOC(ncpus);
6489 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006490 PyErr_NoMemory();
6491 goto error;
6492 }
Larry Hastings2f936352014-08-05 14:04:04 +10006493 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006494
6495 while ((item = PyIter_Next(iterator))) {
6496 long cpu;
6497 if (!PyLong_Check(item)) {
6498 PyErr_Format(PyExc_TypeError,
6499 "expected an iterator of ints, "
6500 "but iterator yielded %R",
6501 Py_TYPE(item));
6502 Py_DECREF(item);
6503 goto error;
6504 }
6505 cpu = PyLong_AsLong(item);
6506 Py_DECREF(item);
6507 if (cpu < 0) {
6508 if (!PyErr_Occurred())
6509 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6510 goto error;
6511 }
6512 if (cpu > INT_MAX - 1) {
6513 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6514 goto error;
6515 }
6516 if (cpu >= ncpus) {
6517 /* Grow CPU mask to fit the CPU number */
6518 int newncpus = ncpus;
6519 cpu_set_t *newmask;
6520 size_t newsetsize;
6521 while (newncpus <= cpu) {
6522 if (newncpus > INT_MAX / 2)
6523 newncpus = cpu + 1;
6524 else
6525 newncpus = newncpus * 2;
6526 }
6527 newmask = CPU_ALLOC(newncpus);
6528 if (newmask == NULL) {
6529 PyErr_NoMemory();
6530 goto error;
6531 }
6532 newsetsize = CPU_ALLOC_SIZE(newncpus);
6533 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006534 memcpy(newmask, cpu_set, setsize);
6535 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006536 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006537 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006538 ncpus = newncpus;
6539 }
Larry Hastings2f936352014-08-05 14:04:04 +10006540 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006541 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07006542 if (PyErr_Occurred()) {
6543 goto error;
6544 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006545 Py_CLEAR(iterator);
6546
Larry Hastings2f936352014-08-05 14:04:04 +10006547 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006548 posix_error();
6549 goto error;
6550 }
Larry Hastings2f936352014-08-05 14:04:04 +10006551 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006552 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006553
6554error:
Larry Hastings2f936352014-08-05 14:04:04 +10006555 if (cpu_set)
6556 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006557 Py_XDECREF(iterator);
6558 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006559}
6560
Larry Hastings2f936352014-08-05 14:04:04 +10006561
6562/*[clinic input]
6563os.sched_getaffinity
6564 pid: pid_t
6565 /
6566
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006567Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006568
6569The affinity is returned as a set of CPU identifiers.
6570[clinic start generated code]*/
6571
Larry Hastings2f936352014-08-05 14:04:04 +10006572static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006573os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006574/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006575{
Antoine Pitrou84869872012-08-04 16:16:35 +02006576 int cpu, ncpus, count;
6577 size_t setsize;
6578 cpu_set_t *mask = NULL;
6579 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006580
Antoine Pitrou84869872012-08-04 16:16:35 +02006581 ncpus = NCPUS_START;
6582 while (1) {
6583 setsize = CPU_ALLOC_SIZE(ncpus);
6584 mask = CPU_ALLOC(ncpus);
6585 if (mask == NULL)
6586 return PyErr_NoMemory();
6587 if (sched_getaffinity(pid, setsize, mask) == 0)
6588 break;
6589 CPU_FREE(mask);
6590 if (errno != EINVAL)
6591 return posix_error();
6592 if (ncpus > INT_MAX / 2) {
6593 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6594 "a large enough CPU set");
6595 return NULL;
6596 }
6597 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006598 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006599
6600 res = PySet_New(NULL);
6601 if (res == NULL)
6602 goto error;
6603 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6604 if (CPU_ISSET_S(cpu, setsize, mask)) {
6605 PyObject *cpu_num = PyLong_FromLong(cpu);
6606 --count;
6607 if (cpu_num == NULL)
6608 goto error;
6609 if (PySet_Add(res, cpu_num)) {
6610 Py_DECREF(cpu_num);
6611 goto error;
6612 }
6613 Py_DECREF(cpu_num);
6614 }
6615 }
6616 CPU_FREE(mask);
6617 return res;
6618
6619error:
6620 if (mask)
6621 CPU_FREE(mask);
6622 Py_XDECREF(res);
6623 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006624}
6625
Benjamin Peterson2740af82011-08-02 17:41:34 -05006626#endif /* HAVE_SCHED_SETAFFINITY */
6627
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006628#endif /* HAVE_SCHED_H */
6629
Larry Hastings2f936352014-08-05 14:04:04 +10006630
Neal Norwitzb59798b2003-03-21 01:43:31 +00006631/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006632/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6633#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006634#define DEV_PTY_FILE "/dev/ptc"
6635#define HAVE_DEV_PTMX
6636#else
6637#define DEV_PTY_FILE "/dev/ptmx"
6638#endif
6639
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006640#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006641#ifdef HAVE_PTY_H
6642#include <pty.h>
6643#else
6644#ifdef HAVE_LIBUTIL_H
6645#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006646#else
6647#ifdef HAVE_UTIL_H
6648#include <util.h>
6649#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006650#endif /* HAVE_LIBUTIL_H */
6651#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006652#ifdef HAVE_STROPTS_H
6653#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006654#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006655#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006656
Larry Hastings2f936352014-08-05 14:04:04 +10006657
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006658#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006659/*[clinic input]
6660os.openpty
6661
6662Open a pseudo-terminal.
6663
6664Return a tuple of (master_fd, slave_fd) containing open file descriptors
6665for both the master and slave ends.
6666[clinic start generated code]*/
6667
Larry Hastings2f936352014-08-05 14:04:04 +10006668static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006669os_openpty_impl(PyObject *module)
6670/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006671{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006672 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006673#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006674 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006675#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006676#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006677 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006678#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006680#endif
6681#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006682
Thomas Wouters70c21a12000-07-14 14:28:33 +00006683#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006684 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006685 goto posix_error;
6686
6687 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6688 goto error;
6689 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6690 goto error;
6691
Neal Norwitzb59798b2003-03-21 01:43:31 +00006692#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006693 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6694 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006695 goto posix_error;
6696 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6697 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006698
Victor Stinnerdaf45552013-08-28 00:53:59 +02006699 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006701 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006702
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006703#else
Victor Stinner000de532013-11-25 23:19:58 +01006704 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006705 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006706 goto posix_error;
6707
Victor Stinner8c62be82010-05-06 00:08:46 +00006708 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006709
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 /* change permission of slave */
6711 if (grantpt(master_fd) < 0) {
6712 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006713 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006715
Victor Stinner8c62be82010-05-06 00:08:46 +00006716 /* unlock slave */
6717 if (unlockpt(master_fd) < 0) {
6718 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006719 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006720 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006721
Victor Stinner8c62be82010-05-06 00:08:46 +00006722 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006723
Victor Stinner8c62be82010-05-06 00:08:46 +00006724 slave_name = ptsname(master_fd); /* get name of slave */
6725 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006726 goto posix_error;
6727
6728 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006729 if (slave_fd == -1)
6730 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006731
6732 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6733 goto posix_error;
6734
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006735#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006736 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6737 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006738#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006740#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006741#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006742#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006743
Victor Stinner8c62be82010-05-06 00:08:46 +00006744 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006745
Victor Stinnerdaf45552013-08-28 00:53:59 +02006746posix_error:
6747 posix_error();
6748error:
6749 if (master_fd != -1)
6750 close(master_fd);
6751 if (slave_fd != -1)
6752 close(slave_fd);
6753 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006754}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006755#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006756
Larry Hastings2f936352014-08-05 14:04:04 +10006757
Fred Drake8cef4cf2000-06-28 16:40:38 +00006758#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006759/*[clinic input]
6760os.forkpty
6761
6762Fork a new process with a new pseudo-terminal as controlling tty.
6763
6764Returns a tuple of (pid, master_fd).
6765Like fork(), return pid of 0 to the child process,
6766and pid of child to the parent process.
6767To both, return fd of newly opened pseudo-terminal.
6768[clinic start generated code]*/
6769
Larry Hastings2f936352014-08-05 14:04:04 +10006770static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006771os_forkpty_impl(PyObject *module)
6772/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006773{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006774 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006776
Eric Snow59032962018-09-14 14:17:20 -07006777 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6778 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6779 return NULL;
6780 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006781 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 pid = forkpty(&master_fd, NULL, NULL, NULL);
6783 if (pid == 0) {
6784 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006785 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006786 } else {
6787 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006788 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 }
6790 if (pid == -1)
6791 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006792 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006793}
Larry Hastings2f936352014-08-05 14:04:04 +10006794#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006795
Ross Lagerwall7807c352011-03-17 20:20:30 +02006796
Guido van Rossumad0ee831995-03-01 10:34:45 +00006797#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006798/*[clinic input]
6799os.getegid
6800
6801Return the current process's effective group id.
6802[clinic start generated code]*/
6803
Larry Hastings2f936352014-08-05 14:04:04 +10006804static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006805os_getegid_impl(PyObject *module)
6806/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006807{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006808 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006809}
Larry Hastings2f936352014-08-05 14:04:04 +10006810#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006812
Guido van Rossumad0ee831995-03-01 10:34:45 +00006813#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006814/*[clinic input]
6815os.geteuid
6816
6817Return the current process's effective user id.
6818[clinic start generated code]*/
6819
Larry Hastings2f936352014-08-05 14:04:04 +10006820static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006821os_geteuid_impl(PyObject *module)
6822/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006823{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006824 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006825}
Larry Hastings2f936352014-08-05 14:04:04 +10006826#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006828
Guido van Rossumad0ee831995-03-01 10:34:45 +00006829#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006830/*[clinic input]
6831os.getgid
6832
6833Return the current process's group id.
6834[clinic start generated code]*/
6835
Larry Hastings2f936352014-08-05 14:04:04 +10006836static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006837os_getgid_impl(PyObject *module)
6838/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006839{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006840 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006841}
Larry Hastings2f936352014-08-05 14:04:04 +10006842#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006843
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006844
Berker Peksag39404992016-09-15 20:45:16 +03006845#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006846/*[clinic input]
6847os.getpid
6848
6849Return the current process id.
6850[clinic start generated code]*/
6851
Larry Hastings2f936352014-08-05 14:04:04 +10006852static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006853os_getpid_impl(PyObject *module)
6854/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006855{
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006857}
Berker Peksag39404992016-09-15 20:45:16 +03006858#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006859
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006860#ifdef NGROUPS_MAX
6861#define MAX_GROUPS NGROUPS_MAX
6862#else
6863 /* defined to be 16 on Solaris7, so this should be a small number */
6864#define MAX_GROUPS 64
6865#endif
6866
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006867#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006868
6869/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006870PyDoc_STRVAR(posix_getgrouplist__doc__,
6871"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6872Returns a list of groups to which a user belongs.\n\n\
6873 user: username to lookup\n\
6874 group: base group id of the user");
6875
6876static PyObject *
6877posix_getgrouplist(PyObject *self, PyObject *args)
6878{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006879 const char *user;
6880 int i, ngroups;
6881 PyObject *list;
6882#ifdef __APPLE__
6883 int *groups, basegid;
6884#else
6885 gid_t *groups, basegid;
6886#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006887
6888 /*
6889 * NGROUPS_MAX is defined by POSIX.1 as the maximum
6890 * number of supplimental groups a users can belong to.
6891 * We have to increment it by one because
6892 * getgrouplist() returns both the supplemental groups
6893 * and the primary group, i.e. all of the groups the
6894 * user belongs to.
6895 */
6896 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006897
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006898#ifdef __APPLE__
6899 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006900 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006901#else
6902 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6903 _Py_Gid_Converter, &basegid))
6904 return NULL;
6905#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006906
6907#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006908 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006909#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006910 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006911#endif
6912 if (groups == NULL)
6913 return PyErr_NoMemory();
6914
6915 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6916 PyMem_Del(groups);
6917 return posix_error();
6918 }
6919
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006920#ifdef _Py_MEMORY_SANITIZER
6921 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6922 __msan_unpoison(&ngroups, sizeof(ngroups));
6923 __msan_unpoison(groups, ngroups*sizeof(*groups));
6924#endif
6925
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006926 list = PyList_New(ngroups);
6927 if (list == NULL) {
6928 PyMem_Del(groups);
6929 return NULL;
6930 }
6931
6932 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006933#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006934 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006935#else
6936 PyObject *o = _PyLong_FromGid(groups[i]);
6937#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006938 if (o == NULL) {
6939 Py_DECREF(list);
6940 PyMem_Del(groups);
6941 return NULL;
6942 }
6943 PyList_SET_ITEM(list, i, o);
6944 }
6945
6946 PyMem_Del(groups);
6947
6948 return list;
6949}
Larry Hastings2f936352014-08-05 14:04:04 +10006950#endif /* HAVE_GETGROUPLIST */
6951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006952
Fred Drakec9680921999-12-13 16:37:25 +00006953#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006954/*[clinic input]
6955os.getgroups
6956
6957Return list of supplemental group IDs for the process.
6958[clinic start generated code]*/
6959
Larry Hastings2f936352014-08-05 14:04:04 +10006960static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006961os_getgroups_impl(PyObject *module)
6962/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006963{
6964 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006965 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006966
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006967 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006968 * This is a helper variable to store the intermediate result when
6969 * that happens.
6970 *
6971 * To keep the code readable the OSX behaviour is unconditional,
6972 * according to the POSIX spec this should be safe on all unix-y
6973 * systems.
6974 */
6975 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006977
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006978#ifdef __APPLE__
6979 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6980 * there are more groups than can fit in grouplist. Therefore, on OS X
6981 * always first call getgroups with length 0 to get the actual number
6982 * of groups.
6983 */
6984 n = getgroups(0, NULL);
6985 if (n < 0) {
6986 return posix_error();
6987 } else if (n <= MAX_GROUPS) {
6988 /* groups will fit in existing array */
6989 alt_grouplist = grouplist;
6990 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006991 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006992 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006993 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006994 }
6995 }
6996
6997 n = getgroups(n, alt_grouplist);
6998 if (n == -1) {
6999 if (alt_grouplist != grouplist) {
7000 PyMem_Free(alt_grouplist);
7001 }
7002 return posix_error();
7003 }
7004#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007005 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007006 if (n < 0) {
7007 if (errno == EINVAL) {
7008 n = getgroups(0, NULL);
7009 if (n == -1) {
7010 return posix_error();
7011 }
7012 if (n == 0) {
7013 /* Avoid malloc(0) */
7014 alt_grouplist = grouplist;
7015 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007016 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007017 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007018 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007019 }
7020 n = getgroups(n, alt_grouplist);
7021 if (n == -1) {
7022 PyMem_Free(alt_grouplist);
7023 return posix_error();
7024 }
7025 }
7026 } else {
7027 return posix_error();
7028 }
7029 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007030#endif
7031
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007032 result = PyList_New(n);
7033 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 int i;
7035 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007036 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007037 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007038 Py_DECREF(result);
7039 result = NULL;
7040 break;
Fred Drakec9680921999-12-13 16:37:25 +00007041 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007043 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007044 }
7045
7046 if (alt_grouplist != grouplist) {
7047 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007048 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007049
Fred Drakec9680921999-12-13 16:37:25 +00007050 return result;
7051}
Larry Hastings2f936352014-08-05 14:04:04 +10007052#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007053
Antoine Pitroub7572f02009-12-02 20:46:48 +00007054#ifdef HAVE_INITGROUPS
7055PyDoc_STRVAR(posix_initgroups__doc__,
7056"initgroups(username, gid) -> None\n\n\
7057Call the system initgroups() to initialize the group access list with all of\n\
7058the groups of which the specified username is a member, plus the specified\n\
7059group id.");
7060
Larry Hastings2f936352014-08-05 14:04:04 +10007061/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007062static PyObject *
7063posix_initgroups(PyObject *self, PyObject *args)
7064{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00007065 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007066 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00007067 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007068#ifdef __APPLE__
7069 int gid;
7070#else
7071 gid_t gid;
7072#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007073
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007074#ifdef __APPLE__
7075 if (!PyArg_ParseTuple(args, "O&i:initgroups",
7076 PyUnicode_FSConverter, &oname,
7077 &gid))
7078#else
7079 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
7080 PyUnicode_FSConverter, &oname,
7081 _Py_Gid_Converter, &gid))
7082#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007083 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00007084 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007085
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007086 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00007087 Py_DECREF(oname);
7088 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007089 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007090
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007091 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007092}
Larry Hastings2f936352014-08-05 14:04:04 +10007093#endif /* HAVE_INITGROUPS */
7094
Antoine Pitroub7572f02009-12-02 20:46:48 +00007095
Martin v. Löwis606edc12002-06-13 21:09:11 +00007096#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007097/*[clinic input]
7098os.getpgid
7099
7100 pid: pid_t
7101
7102Call the system call getpgid(), and return the result.
7103[clinic start generated code]*/
7104
Larry Hastings2f936352014-08-05 14:04:04 +10007105static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007106os_getpgid_impl(PyObject *module, pid_t pid)
7107/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007108{
7109 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007110 if (pgid < 0)
7111 return posix_error();
7112 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007113}
7114#endif /* HAVE_GETPGID */
7115
7116
Guido van Rossumb6775db1994-08-01 11:34:53 +00007117#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007118/*[clinic input]
7119os.getpgrp
7120
7121Return the current process group id.
7122[clinic start generated code]*/
7123
Larry Hastings2f936352014-08-05 14:04:04 +10007124static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007125os_getpgrp_impl(PyObject *module)
7126/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007127{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007128#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007130#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007131 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007132#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007133}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007134#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007135
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007136
Guido van Rossumb6775db1994-08-01 11:34:53 +00007137#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007138/*[clinic input]
7139os.setpgrp
7140
7141Make the current process the leader of its process group.
7142[clinic start generated code]*/
7143
Larry Hastings2f936352014-08-05 14:04:04 +10007144static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007145os_setpgrp_impl(PyObject *module)
7146/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007147{
Guido van Rossum64933891994-10-20 21:56:42 +00007148#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007149 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007150#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007151 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007152#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007153 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007154 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007155}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007156#endif /* HAVE_SETPGRP */
7157
Guido van Rossumad0ee831995-03-01 10:34:45 +00007158#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007159
7160#ifdef MS_WINDOWS
7161#include <tlhelp32.h>
7162
7163static PyObject*
7164win32_getppid()
7165{
7166 HANDLE snapshot;
7167 pid_t mypid;
7168 PyObject* result = NULL;
7169 BOOL have_record;
7170 PROCESSENTRY32 pe;
7171
7172 mypid = getpid(); /* This function never fails */
7173
7174 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7175 if (snapshot == INVALID_HANDLE_VALUE)
7176 return PyErr_SetFromWindowsErr(GetLastError());
7177
7178 pe.dwSize = sizeof(pe);
7179 have_record = Process32First(snapshot, &pe);
7180 while (have_record) {
7181 if (mypid == (pid_t)pe.th32ProcessID) {
7182 /* We could cache the ulong value in a static variable. */
7183 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7184 break;
7185 }
7186
7187 have_record = Process32Next(snapshot, &pe);
7188 }
7189
7190 /* If our loop exits and our pid was not found (result will be NULL)
7191 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7192 * error anyway, so let's raise it. */
7193 if (!result)
7194 result = PyErr_SetFromWindowsErr(GetLastError());
7195
7196 CloseHandle(snapshot);
7197
7198 return result;
7199}
7200#endif /*MS_WINDOWS*/
7201
Larry Hastings2f936352014-08-05 14:04:04 +10007202
7203/*[clinic input]
7204os.getppid
7205
7206Return the parent's process id.
7207
7208If the parent process has already exited, Windows machines will still
7209return its id; others systems will return the id of the 'init' process (1).
7210[clinic start generated code]*/
7211
Larry Hastings2f936352014-08-05 14:04:04 +10007212static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007213os_getppid_impl(PyObject *module)
7214/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007215{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007216#ifdef MS_WINDOWS
7217 return win32_getppid();
7218#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007219 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007220#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007221}
7222#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007223
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007224
Fred Drake12c6e2d1999-12-14 21:25:03 +00007225#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007226/*[clinic input]
7227os.getlogin
7228
7229Return the actual login name.
7230[clinic start generated code]*/
7231
Larry Hastings2f936352014-08-05 14:04:04 +10007232static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007233os_getlogin_impl(PyObject *module)
7234/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007235{
Victor Stinner8c62be82010-05-06 00:08:46 +00007236 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007237#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007238 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007239 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007240
7241 if (GetUserNameW(user_name, &num_chars)) {
7242 /* num_chars is the number of unicode chars plus null terminator */
7243 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007244 }
7245 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007246 result = PyErr_SetFromWindowsErr(GetLastError());
7247#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007248 char *name;
7249 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007250
Victor Stinner8c62be82010-05-06 00:08:46 +00007251 errno = 0;
7252 name = getlogin();
7253 if (name == NULL) {
7254 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007255 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007256 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007257 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007258 }
7259 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007260 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007261 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007262#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007263 return result;
7264}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007265#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007266
Larry Hastings2f936352014-08-05 14:04:04 +10007267
Guido van Rossumad0ee831995-03-01 10:34:45 +00007268#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007269/*[clinic input]
7270os.getuid
7271
7272Return the current process's user id.
7273[clinic start generated code]*/
7274
Larry Hastings2f936352014-08-05 14:04:04 +10007275static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007276os_getuid_impl(PyObject *module)
7277/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007278{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007279 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007280}
Larry Hastings2f936352014-08-05 14:04:04 +10007281#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007282
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007283
Brian Curtineb24d742010-04-12 17:16:38 +00007284#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007285#define HAVE_KILL
7286#endif /* MS_WINDOWS */
7287
7288#ifdef HAVE_KILL
7289/*[clinic input]
7290os.kill
7291
7292 pid: pid_t
7293 signal: Py_ssize_t
7294 /
7295
7296Kill a process with a signal.
7297[clinic start generated code]*/
7298
Larry Hastings2f936352014-08-05 14:04:04 +10007299static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007300os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7301/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007302#ifndef MS_WINDOWS
7303{
7304 if (kill(pid, (int)signal) == -1)
7305 return posix_error();
7306 Py_RETURN_NONE;
7307}
7308#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00007309{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007310 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007311 DWORD sig = (DWORD)signal;
7312 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007313 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007314
Victor Stinner8c62be82010-05-06 00:08:46 +00007315 /* Console processes which share a common console can be sent CTRL+C or
7316 CTRL+BREAK events, provided they handle said events. */
7317 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007318 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007319 err = GetLastError();
7320 PyErr_SetFromWindowsErr(err);
7321 }
7322 else
7323 Py_RETURN_NONE;
7324 }
Brian Curtineb24d742010-04-12 17:16:38 +00007325
Victor Stinner8c62be82010-05-06 00:08:46 +00007326 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7327 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007328 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007329 if (handle == NULL) {
7330 err = GetLastError();
7331 return PyErr_SetFromWindowsErr(err);
7332 }
Brian Curtineb24d742010-04-12 17:16:38 +00007333
Victor Stinner8c62be82010-05-06 00:08:46 +00007334 if (TerminateProcess(handle, sig) == 0) {
7335 err = GetLastError();
7336 result = PyErr_SetFromWindowsErr(err);
7337 } else {
7338 Py_INCREF(Py_None);
7339 result = Py_None;
7340 }
Brian Curtineb24d742010-04-12 17:16:38 +00007341
Victor Stinner8c62be82010-05-06 00:08:46 +00007342 CloseHandle(handle);
7343 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00007344}
Larry Hastings2f936352014-08-05 14:04:04 +10007345#endif /* !MS_WINDOWS */
7346#endif /* HAVE_KILL */
7347
7348
7349#ifdef HAVE_KILLPG
7350/*[clinic input]
7351os.killpg
7352
7353 pgid: pid_t
7354 signal: int
7355 /
7356
7357Kill a process group with a signal.
7358[clinic start generated code]*/
7359
Larry Hastings2f936352014-08-05 14:04:04 +10007360static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007361os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7362/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007363{
7364 /* XXX some man pages make the `pgid` parameter an int, others
7365 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7366 take the same type. Moreover, pid_t is always at least as wide as
7367 int (else compilation of this module fails), which is safe. */
7368 if (killpg(pgid, signal) == -1)
7369 return posix_error();
7370 Py_RETURN_NONE;
7371}
7372#endif /* HAVE_KILLPG */
7373
Brian Curtineb24d742010-04-12 17:16:38 +00007374
Guido van Rossumc0125471996-06-28 18:55:32 +00007375#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007376#ifdef HAVE_SYS_LOCK_H
7377#include <sys/lock.h>
7378#endif
7379
Larry Hastings2f936352014-08-05 14:04:04 +10007380/*[clinic input]
7381os.plock
7382 op: int
7383 /
7384
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007385Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007386[clinic start generated code]*/
7387
Larry Hastings2f936352014-08-05 14:04:04 +10007388static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007389os_plock_impl(PyObject *module, int op)
7390/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007391{
Victor Stinner8c62be82010-05-06 00:08:46 +00007392 if (plock(op) == -1)
7393 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007394 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007395}
Larry Hastings2f936352014-08-05 14:04:04 +10007396#endif /* HAVE_PLOCK */
7397
Guido van Rossumc0125471996-06-28 18:55:32 +00007398
Guido van Rossumb6775db1994-08-01 11:34:53 +00007399#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007400/*[clinic input]
7401os.setuid
7402
7403 uid: uid_t
7404 /
7405
7406Set the current process's user id.
7407[clinic start generated code]*/
7408
Larry Hastings2f936352014-08-05 14:04:04 +10007409static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007410os_setuid_impl(PyObject *module, uid_t uid)
7411/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007412{
Victor Stinner8c62be82010-05-06 00:08:46 +00007413 if (setuid(uid) < 0)
7414 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007415 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007416}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007417#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007419
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007420#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007421/*[clinic input]
7422os.seteuid
7423
7424 euid: uid_t
7425 /
7426
7427Set the current process's effective user id.
7428[clinic start generated code]*/
7429
Larry Hastings2f936352014-08-05 14:04:04 +10007430static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007431os_seteuid_impl(PyObject *module, uid_t euid)
7432/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007433{
7434 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007435 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007436 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007437}
7438#endif /* HAVE_SETEUID */
7439
Larry Hastings2f936352014-08-05 14:04:04 +10007440
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007441#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007442/*[clinic input]
7443os.setegid
7444
7445 egid: gid_t
7446 /
7447
7448Set the current process's effective group id.
7449[clinic start generated code]*/
7450
Larry Hastings2f936352014-08-05 14:04:04 +10007451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007452os_setegid_impl(PyObject *module, gid_t egid)
7453/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007454{
7455 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007456 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007457 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007458}
7459#endif /* HAVE_SETEGID */
7460
Larry Hastings2f936352014-08-05 14:04:04 +10007461
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007462#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007463/*[clinic input]
7464os.setreuid
7465
7466 ruid: uid_t
7467 euid: uid_t
7468 /
7469
7470Set the current process's real and effective user ids.
7471[clinic start generated code]*/
7472
Larry Hastings2f936352014-08-05 14:04:04 +10007473static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007474os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7475/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007476{
Victor Stinner8c62be82010-05-06 00:08:46 +00007477 if (setreuid(ruid, euid) < 0) {
7478 return posix_error();
7479 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007480 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007481 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007482}
7483#endif /* HAVE_SETREUID */
7484
Larry Hastings2f936352014-08-05 14:04:04 +10007485
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007486#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007487/*[clinic input]
7488os.setregid
7489
7490 rgid: gid_t
7491 egid: gid_t
7492 /
7493
7494Set the current process's real and effective group ids.
7495[clinic start generated code]*/
7496
Larry Hastings2f936352014-08-05 14:04:04 +10007497static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007498os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7499/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007500{
7501 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007502 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007503 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007504}
7505#endif /* HAVE_SETREGID */
7506
Larry Hastings2f936352014-08-05 14:04:04 +10007507
Guido van Rossumb6775db1994-08-01 11:34:53 +00007508#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007509/*[clinic input]
7510os.setgid
7511 gid: gid_t
7512 /
7513
7514Set the current process's group id.
7515[clinic start generated code]*/
7516
Larry Hastings2f936352014-08-05 14:04:04 +10007517static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007518os_setgid_impl(PyObject *module, gid_t gid)
7519/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007520{
Victor Stinner8c62be82010-05-06 00:08:46 +00007521 if (setgid(gid) < 0)
7522 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007523 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007524}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007525#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007526
Larry Hastings2f936352014-08-05 14:04:04 +10007527
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007528#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007529/*[clinic input]
7530os.setgroups
7531
7532 groups: object
7533 /
7534
7535Set the groups of the current process to list.
7536[clinic start generated code]*/
7537
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007538static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007539os_setgroups(PyObject *module, PyObject *groups)
7540/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007541{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007542 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007543 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007544
Victor Stinner8c62be82010-05-06 00:08:46 +00007545 if (!PySequence_Check(groups)) {
7546 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7547 return NULL;
7548 }
7549 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007550 if (len < 0) {
7551 return NULL;
7552 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007553 if (len > MAX_GROUPS) {
7554 PyErr_SetString(PyExc_ValueError, "too many groups");
7555 return NULL;
7556 }
7557 for(i = 0; i < len; i++) {
7558 PyObject *elem;
7559 elem = PySequence_GetItem(groups, i);
7560 if (!elem)
7561 return NULL;
7562 if (!PyLong_Check(elem)) {
7563 PyErr_SetString(PyExc_TypeError,
7564 "groups must be integers");
7565 Py_DECREF(elem);
7566 return NULL;
7567 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007568 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007569 Py_DECREF(elem);
7570 return NULL;
7571 }
7572 }
7573 Py_DECREF(elem);
7574 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007575
Victor Stinner8c62be82010-05-06 00:08:46 +00007576 if (setgroups(len, grouplist) < 0)
7577 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007578 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007579}
7580#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007581
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007582#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7583static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007584wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007585{
Victor Stinner8c62be82010-05-06 00:08:46 +00007586 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08007587 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007588
Victor Stinner8c62be82010-05-06 00:08:46 +00007589 if (pid == -1)
7590 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007591
Zackery Spytz682107c2019-09-09 09:48:32 -06007592 // If wait succeeded but no child was ready to report status, ru will not
7593 // have been populated.
7594 if (pid == 0) {
7595 memset(ru, 0, sizeof(*ru));
7596 }
7597
Eddie Elizondob3966632019-11-05 07:16:14 -08007598 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7599 if (m == NULL)
7600 return NULL;
7601 struct_rusage = PyObject_GetAttr(m, _posixstate_global->struct_rusage);
7602 Py_DECREF(m);
7603 if (struct_rusage == NULL)
7604 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007605
Victor Stinner8c62be82010-05-06 00:08:46 +00007606 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7607 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08007608 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007609 if (!result)
7610 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007611
7612#ifndef doubletime
7613#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7614#endif
7615
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007617 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007619 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007620#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007621 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7622 SET_INT(result, 2, ru->ru_maxrss);
7623 SET_INT(result, 3, ru->ru_ixrss);
7624 SET_INT(result, 4, ru->ru_idrss);
7625 SET_INT(result, 5, ru->ru_isrss);
7626 SET_INT(result, 6, ru->ru_minflt);
7627 SET_INT(result, 7, ru->ru_majflt);
7628 SET_INT(result, 8, ru->ru_nswap);
7629 SET_INT(result, 9, ru->ru_inblock);
7630 SET_INT(result, 10, ru->ru_oublock);
7631 SET_INT(result, 11, ru->ru_msgsnd);
7632 SET_INT(result, 12, ru->ru_msgrcv);
7633 SET_INT(result, 13, ru->ru_nsignals);
7634 SET_INT(result, 14, ru->ru_nvcsw);
7635 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007636#undef SET_INT
7637
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 if (PyErr_Occurred()) {
7639 Py_DECREF(result);
7640 return NULL;
7641 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007642
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007644}
7645#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7646
Larry Hastings2f936352014-08-05 14:04:04 +10007647
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007648#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007649/*[clinic input]
7650os.wait3
7651
7652 options: int
7653Wait for completion of a child process.
7654
7655Returns a tuple of information about the child process:
7656 (pid, status, rusage)
7657[clinic start generated code]*/
7658
Larry Hastings2f936352014-08-05 14:04:04 +10007659static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007660os_wait3_impl(PyObject *module, int options)
7661/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007662{
Victor Stinner8c62be82010-05-06 00:08:46 +00007663 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007664 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007665 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007666 WAIT_TYPE status;
7667 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007668
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007669 do {
7670 Py_BEGIN_ALLOW_THREADS
7671 pid = wait3(&status, options, &ru);
7672 Py_END_ALLOW_THREADS
7673 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7674 if (pid < 0)
7675 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007676
Victor Stinner4195b5c2012-02-08 23:03:19 +01007677 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007678}
7679#endif /* HAVE_WAIT3 */
7680
Larry Hastings2f936352014-08-05 14:04:04 +10007681
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007682#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007683/*[clinic input]
7684
7685os.wait4
7686
7687 pid: pid_t
7688 options: int
7689
7690Wait for completion of a specific child process.
7691
7692Returns a tuple of information about the child process:
7693 (pid, status, rusage)
7694[clinic start generated code]*/
7695
Larry Hastings2f936352014-08-05 14:04:04 +10007696static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007697os_wait4_impl(PyObject *module, pid_t pid, int options)
7698/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007699{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007700 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007701 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007702 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007703 WAIT_TYPE status;
7704 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007705
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007706 do {
7707 Py_BEGIN_ALLOW_THREADS
7708 res = wait4(pid, &status, options, &ru);
7709 Py_END_ALLOW_THREADS
7710 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7711 if (res < 0)
7712 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007713
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007714 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007715}
7716#endif /* HAVE_WAIT4 */
7717
Larry Hastings2f936352014-08-05 14:04:04 +10007718
Ross Lagerwall7807c352011-03-17 20:20:30 +02007719#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007720/*[clinic input]
7721os.waitid
7722
7723 idtype: idtype_t
7724 Must be one of be P_PID, P_PGID or P_ALL.
7725 id: id_t
7726 The id to wait on.
7727 options: int
7728 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7729 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7730 /
7731
7732Returns the result of waiting for a process or processes.
7733
7734Returns either waitid_result or None if WNOHANG is specified and there are
7735no children in a waitable state.
7736[clinic start generated code]*/
7737
Larry Hastings2f936352014-08-05 14:04:04 +10007738static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007739os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7740/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007741{
7742 PyObject *result;
7743 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007744 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007745 siginfo_t si;
7746 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007747
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007748 do {
7749 Py_BEGIN_ALLOW_THREADS
7750 res = waitid(idtype, id, &si, options);
7751 Py_END_ALLOW_THREADS
7752 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7753 if (res < 0)
7754 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007755
7756 if (si.si_pid == 0)
7757 Py_RETURN_NONE;
7758
Eddie Elizondob3966632019-11-05 07:16:14 -08007759 PyObject *WaitidResultType = _posixstate(module)->WaitidResultType;
7760 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007761 if (!result)
7762 return NULL;
7763
7764 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007765 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007766 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7767 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7768 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7769 if (PyErr_Occurred()) {
7770 Py_DECREF(result);
7771 return NULL;
7772 }
7773
7774 return result;
7775}
Larry Hastings2f936352014-08-05 14:04:04 +10007776#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007777
Larry Hastings2f936352014-08-05 14:04:04 +10007778
7779#if defined(HAVE_WAITPID)
7780/*[clinic input]
7781os.waitpid
7782 pid: pid_t
7783 options: int
7784 /
7785
7786Wait for completion of a given child process.
7787
7788Returns a tuple of information regarding the child process:
7789 (pid, status)
7790
7791The options argument is ignored on Windows.
7792[clinic start generated code]*/
7793
Larry Hastings2f936352014-08-05 14:04:04 +10007794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007795os_waitpid_impl(PyObject *module, pid_t pid, int options)
7796/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007797{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007798 pid_t res;
7799 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007800 WAIT_TYPE status;
7801 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007802
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007803 do {
7804 Py_BEGIN_ALLOW_THREADS
7805 res = waitpid(pid, &status, options);
7806 Py_END_ALLOW_THREADS
7807 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7808 if (res < 0)
7809 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007810
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007811 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007812}
Tim Petersab034fa2002-02-01 11:27:43 +00007813#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007814/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007815/*[clinic input]
7816os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007817 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007818 options: int
7819 /
7820
7821Wait for completion of a given process.
7822
7823Returns a tuple of information regarding the process:
7824 (pid, status << 8)
7825
7826The options argument is ignored on Windows.
7827[clinic start generated code]*/
7828
Larry Hastings2f936352014-08-05 14:04:04 +10007829static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007830os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007831/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007832{
7833 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007834 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007835 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007836
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007837 do {
7838 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007839 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007840 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007841 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007842 Py_END_ALLOW_THREADS
7843 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007844 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007845 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007846
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007848 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007849}
Larry Hastings2f936352014-08-05 14:04:04 +10007850#endif
7851
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007852
Guido van Rossumad0ee831995-03-01 10:34:45 +00007853#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007854/*[clinic input]
7855os.wait
7856
7857Wait for completion of a child process.
7858
7859Returns a tuple of information about the child process:
7860 (pid, status)
7861[clinic start generated code]*/
7862
Larry Hastings2f936352014-08-05 14:04:04 +10007863static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007864os_wait_impl(PyObject *module)
7865/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007866{
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007868 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 WAIT_TYPE status;
7870 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007871
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007872 do {
7873 Py_BEGIN_ALLOW_THREADS
7874 pid = wait(&status);
7875 Py_END_ALLOW_THREADS
7876 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7877 if (pid < 0)
7878 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007879
Victor Stinner8c62be82010-05-06 00:08:46 +00007880 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007881}
Larry Hastings2f936352014-08-05 14:04:04 +10007882#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007883
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08007884#if defined(__linux__) && defined(__NR_pidfd_open)
7885/*[clinic input]
7886os.pidfd_open
7887 pid: pid_t
7888 flags: unsigned_int = 0
7889
7890Return a file descriptor referring to the process *pid*.
7891
7892The descriptor can be used to perform process management without races and
7893signals.
7894[clinic start generated code]*/
7895
7896static PyObject *
7897os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
7898/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
7899{
7900 int fd = syscall(__NR_pidfd_open, pid, flags);
7901 if (fd < 0) {
7902 return posix_error();
7903 }
7904 return PyLong_FromLong(fd);
7905}
7906#endif
7907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007908
Larry Hastings9cf065c2012-06-22 16:30:09 -07007909#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007910/*[clinic input]
7911os.readlink
7912
7913 path: path_t
7914 *
7915 dir_fd: dir_fd(requires='readlinkat') = None
7916
7917Return a string representing the path to which the symbolic link points.
7918
7919If dir_fd is not None, it should be a file descriptor open to a directory,
7920and path should be relative; path will then be relative to that directory.
7921
7922dir_fd may not be implemented on your platform. If it is unavailable,
7923using it will raise a NotImplementedError.
7924[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007925
Barry Warsaw53699e91996-12-10 23:23:01 +00007926static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007927os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7928/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007929{
Berker Peksage0b5b202018-08-15 13:03:41 +03007930#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007931 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007932 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007933
7934 Py_BEGIN_ALLOW_THREADS
7935#ifdef HAVE_READLINKAT
7936 if (dir_fd != DEFAULT_DIR_FD)
7937 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7938 else
7939#endif
7940 length = readlink(path->narrow, buffer, MAXPATHLEN);
7941 Py_END_ALLOW_THREADS
7942
7943 if (length < 0) {
7944 return path_error(path);
7945 }
7946 buffer[length] = '\0';
7947
7948 if (PyUnicode_Check(path->object))
7949 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7950 else
7951 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007952#elif defined(MS_WINDOWS)
7953 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07007954 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03007955 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007956 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7957 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07007958 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007959
Larry Hastings2f936352014-08-05 14:04:04 +10007960 /* First get a handle to the reparse point */
7961 Py_BEGIN_ALLOW_THREADS
7962 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007963 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007964 0,
7965 0,
7966 0,
7967 OPEN_EXISTING,
7968 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7969 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07007970 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
7971 /* New call DeviceIoControl to read the reparse point */
7972 io_result = DeviceIoControl(
7973 reparse_point_handle,
7974 FSCTL_GET_REPARSE_POINT,
7975 0, 0, /* in buffer */
7976 target_buffer, sizeof(target_buffer),
7977 &n_bytes_returned,
7978 0 /* we're not using OVERLAPPED_IO */
7979 );
7980 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03007981 }
Larry Hastings2f936352014-08-05 14:04:04 +10007982 Py_END_ALLOW_THREADS
7983
Berker Peksage0b5b202018-08-15 13:03:41 +03007984 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007985 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007986 }
Larry Hastings2f936352014-08-05 14:04:04 +10007987
Steve Dowerdf2d4a62019-08-21 15:27:33 -07007988 wchar_t *name = NULL;
7989 Py_ssize_t nameLen = 0;
7990 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10007991 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07007992 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7993 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
7994 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10007995 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07007996 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
7997 {
7998 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
7999 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8000 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8001 }
8002 else
8003 {
8004 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8005 }
8006 if (name) {
8007 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8008 /* Our buffer is mutable, so this is okay */
8009 name[1] = L'\\';
8010 }
8011 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008012 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008013 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8014 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008015 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008016 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008017#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008018}
Berker Peksage0b5b202018-08-15 13:03:41 +03008019#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008020
Larry Hastings9cf065c2012-06-22 16:30:09 -07008021#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07008022
8023#if defined(MS_WINDOWS)
8024
Steve Dower6921e732018-03-05 14:26:08 -08008025/* Remove the last portion of the path - return 0 on success */
8026static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008027_dirnameW(WCHAR *path)
8028{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008029 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008030 size_t length = wcsnlen_s(path, MAX_PATH);
8031 if (length == MAX_PATH) {
8032 return -1;
8033 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008034
8035 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008036 for(ptr = path + length; ptr != path; ptr--) {
8037 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008038 break;
Steve Dower6921e732018-03-05 14:26:08 -08008039 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008040 }
8041 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008042 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008043}
8044
Victor Stinner31b3b922013-06-05 01:49:17 +02008045/* Is this path absolute? */
8046static int
8047_is_absW(const WCHAR *path)
8048{
Steve Dower6921e732018-03-05 14:26:08 -08008049 return path[0] == L'\\' || path[0] == L'/' ||
8050 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008051}
8052
Steve Dower6921e732018-03-05 14:26:08 -08008053/* join root and rest with a backslash - return 0 on success */
8054static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008055_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8056{
Victor Stinner31b3b922013-06-05 01:49:17 +02008057 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008058 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008059 }
8060
Steve Dower6921e732018-03-05 14:26:08 -08008061 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8062 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008063 }
Steve Dower6921e732018-03-05 14:26:08 -08008064
8065 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8066 return -1;
8067 }
8068
8069 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008070}
8071
Victor Stinner31b3b922013-06-05 01:49:17 +02008072/* Return True if the path at src relative to dest is a directory */
8073static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008074_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008075{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008076 WIN32_FILE_ATTRIBUTE_DATA src_info;
8077 WCHAR dest_parent[MAX_PATH];
8078 WCHAR src_resolved[MAX_PATH] = L"";
8079
8080 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008081 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8082 _dirnameW(dest_parent)) {
8083 return 0;
8084 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008085 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008086 if (_joinW(src_resolved, dest_parent, src)) {
8087 return 0;
8088 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008089 return (
8090 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8091 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8092 );
8093}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008094#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008095
Larry Hastings2f936352014-08-05 14:04:04 +10008096
8097/*[clinic input]
8098os.symlink
8099 src: path_t
8100 dst: path_t
8101 target_is_directory: bool = False
8102 *
8103 dir_fd: dir_fd(requires='symlinkat')=None
8104
8105# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8106
8107Create a symbolic link pointing to src named dst.
8108
8109target_is_directory is required on Windows if the target is to be
8110 interpreted as a directory. (On Windows, symlink requires
8111 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8112 target_is_directory is ignored on non-Windows platforms.
8113
8114If dir_fd is not None, it should be a file descriptor open to a directory,
8115 and path should be relative; path will then be relative to that directory.
8116dir_fd may not be implemented on your platform.
8117 If it is unavailable, using it will raise a NotImplementedError.
8118
8119[clinic start generated code]*/
8120
Larry Hastings2f936352014-08-05 14:04:04 +10008121static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008122os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008123 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008124/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008125{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008126#ifdef MS_WINDOWS
8127 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008128 DWORD flags = 0;
8129
8130 /* Assumed true, set to false if detected to not be available. */
8131 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008132#else
8133 int result;
8134#endif
8135
Larry Hastings9cf065c2012-06-22 16:30:09 -07008136#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008137
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008138 if (windows_has_symlink_unprivileged_flag) {
8139 /* Allow non-admin symlinks if system allows it. */
8140 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8141 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008142
Larry Hastings9cf065c2012-06-22 16:30:09 -07008143 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008144 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008145 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8146 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8147 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8148 }
8149
8150 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008151 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008152 Py_END_ALLOW_THREADS
8153
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008154 if (windows_has_symlink_unprivileged_flag && !result &&
8155 ERROR_INVALID_PARAMETER == GetLastError()) {
8156
8157 Py_BEGIN_ALLOW_THREADS
8158 _Py_BEGIN_SUPPRESS_IPH
8159 /* This error might be caused by
8160 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8161 Try again, and update windows_has_symlink_unprivileged_flag if we
8162 are successful this time.
8163
8164 NOTE: There is a risk of a race condition here if there are other
8165 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8166 another process (or thread) changes that condition in between our
8167 calls to CreateSymbolicLink.
8168 */
8169 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8170 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8171 _Py_END_SUPPRESS_IPH
8172 Py_END_ALLOW_THREADS
8173
8174 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8175 windows_has_symlink_unprivileged_flag = FALSE;
8176 }
8177 }
8178
Larry Hastings2f936352014-08-05 14:04:04 +10008179 if (!result)
8180 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008181
8182#else
8183
Steve Dower6921e732018-03-05 14:26:08 -08008184 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8185 PyErr_SetString(PyExc_ValueError,
8186 "symlink: src and dst must be the same type");
8187 return NULL;
8188 }
8189
Larry Hastings9cf065c2012-06-22 16:30:09 -07008190 Py_BEGIN_ALLOW_THREADS
8191#if HAVE_SYMLINKAT
8192 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10008193 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008194 else
8195#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008196 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008197 Py_END_ALLOW_THREADS
8198
Larry Hastings2f936352014-08-05 14:04:04 +10008199 if (result)
8200 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008201#endif
8202
Larry Hastings2f936352014-08-05 14:04:04 +10008203 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008204}
8205#endif /* HAVE_SYMLINK */
8206
Larry Hastings9cf065c2012-06-22 16:30:09 -07008207
Brian Curtind40e6f72010-07-08 21:39:08 +00008208
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008209
Larry Hastings605a62d2012-06-24 04:33:36 -07008210static PyStructSequence_Field times_result_fields[] = {
8211 {"user", "user time"},
8212 {"system", "system time"},
8213 {"children_user", "user time of children"},
8214 {"children_system", "system time of children"},
8215 {"elapsed", "elapsed time since an arbitrary point in the past"},
8216 {NULL}
8217};
8218
8219PyDoc_STRVAR(times_result__doc__,
8220"times_result: Result from os.times().\n\n\
8221This object may be accessed either as a tuple of\n\
8222 (user, system, children_user, children_system, elapsed),\n\
8223or via the attributes user, system, children_user, children_system,\n\
8224and elapsed.\n\
8225\n\
8226See os.times for more information.");
8227
8228static PyStructSequence_Desc times_result_desc = {
8229 "times_result", /* name */
8230 times_result__doc__, /* doc */
8231 times_result_fields,
8232 5
8233};
8234
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008235#ifdef MS_WINDOWS
8236#define HAVE_TIMES /* mandatory, for the method table */
8237#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008238
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008239#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008240
8241static PyObject *
8242build_times_result(double user, double system,
8243 double children_user, double children_system,
8244 double elapsed)
8245{
Eddie Elizondob3966632019-11-05 07:16:14 -08008246 PyObject *TimesResultType = _posixstate_global->TimesResultType;
8247 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008248 if (value == NULL)
8249 return NULL;
8250
8251#define SET(i, field) \
8252 { \
8253 PyObject *o = PyFloat_FromDouble(field); \
8254 if (!o) { \
8255 Py_DECREF(value); \
8256 return NULL; \
8257 } \
8258 PyStructSequence_SET_ITEM(value, i, o); \
8259 } \
8260
8261 SET(0, user);
8262 SET(1, system);
8263 SET(2, children_user);
8264 SET(3, children_system);
8265 SET(4, elapsed);
8266
8267#undef SET
8268
8269 return value;
8270}
8271
Larry Hastings605a62d2012-06-24 04:33:36 -07008272
Larry Hastings2f936352014-08-05 14:04:04 +10008273#ifndef MS_WINDOWS
8274#define NEED_TICKS_PER_SECOND
8275static long ticks_per_second = -1;
8276#endif /* MS_WINDOWS */
8277
8278/*[clinic input]
8279os.times
8280
8281Return a collection containing process timing information.
8282
8283The object returned behaves like a named tuple with these fields:
8284 (utime, stime, cutime, cstime, elapsed_time)
8285All fields are floating point numbers.
8286[clinic start generated code]*/
8287
Larry Hastings2f936352014-08-05 14:04:04 +10008288static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008289os_times_impl(PyObject *module)
8290/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008291#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008292{
Victor Stinner8c62be82010-05-06 00:08:46 +00008293 FILETIME create, exit, kernel, user;
8294 HANDLE hProc;
8295 hProc = GetCurrentProcess();
8296 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8297 /* The fields of a FILETIME structure are the hi and lo part
8298 of a 64-bit value expressed in 100 nanosecond units.
8299 1e7 is one second in such units; 1e-7 the inverse.
8300 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8301 */
Larry Hastings605a62d2012-06-24 04:33:36 -07008302 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00008303 (double)(user.dwHighDateTime*429.4967296 +
8304 user.dwLowDateTime*1e-7),
8305 (double)(kernel.dwHighDateTime*429.4967296 +
8306 kernel.dwLowDateTime*1e-7),
8307 (double)0,
8308 (double)0,
8309 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008310}
Larry Hastings2f936352014-08-05 14:04:04 +10008311#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008312{
Larry Hastings2f936352014-08-05 14:04:04 +10008313
8314
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008315 struct tms t;
8316 clock_t c;
8317 errno = 0;
8318 c = times(&t);
8319 if (c == (clock_t) -1)
8320 return posix_error();
8321 return build_times_result(
8322 (double)t.tms_utime / ticks_per_second,
8323 (double)t.tms_stime / ticks_per_second,
8324 (double)t.tms_cutime / ticks_per_second,
8325 (double)t.tms_cstime / ticks_per_second,
8326 (double)c / ticks_per_second);
8327}
Larry Hastings2f936352014-08-05 14:04:04 +10008328#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008329#endif /* HAVE_TIMES */
8330
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008331
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008332#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008333/*[clinic input]
8334os.getsid
8335
8336 pid: pid_t
8337 /
8338
8339Call the system call getsid(pid) and return the result.
8340[clinic start generated code]*/
8341
Larry Hastings2f936352014-08-05 14:04:04 +10008342static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008343os_getsid_impl(PyObject *module, pid_t pid)
8344/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008345{
Victor Stinner8c62be82010-05-06 00:08:46 +00008346 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008347 sid = getsid(pid);
8348 if (sid < 0)
8349 return posix_error();
8350 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008351}
8352#endif /* HAVE_GETSID */
8353
8354
Guido van Rossumb6775db1994-08-01 11:34:53 +00008355#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008356/*[clinic input]
8357os.setsid
8358
8359Call the system call setsid().
8360[clinic start generated code]*/
8361
Larry Hastings2f936352014-08-05 14:04:04 +10008362static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008363os_setsid_impl(PyObject *module)
8364/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008365{
Victor Stinner8c62be82010-05-06 00:08:46 +00008366 if (setsid() < 0)
8367 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008368 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008369}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008370#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008371
Larry Hastings2f936352014-08-05 14:04:04 +10008372
Guido van Rossumb6775db1994-08-01 11:34:53 +00008373#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008374/*[clinic input]
8375os.setpgid
8376
8377 pid: pid_t
8378 pgrp: pid_t
8379 /
8380
8381Call the system call setpgid(pid, pgrp).
8382[clinic start generated code]*/
8383
Larry Hastings2f936352014-08-05 14:04:04 +10008384static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008385os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8386/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008387{
Victor Stinner8c62be82010-05-06 00:08:46 +00008388 if (setpgid(pid, pgrp) < 0)
8389 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008390 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008391}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008392#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008393
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008394
Guido van Rossumb6775db1994-08-01 11:34:53 +00008395#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008396/*[clinic input]
8397os.tcgetpgrp
8398
8399 fd: int
8400 /
8401
8402Return the process group associated with the terminal specified by fd.
8403[clinic start generated code]*/
8404
Larry Hastings2f936352014-08-05 14:04:04 +10008405static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008406os_tcgetpgrp_impl(PyObject *module, int fd)
8407/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008408{
8409 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008410 if (pgid < 0)
8411 return posix_error();
8412 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008413}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008414#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008415
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008416
Guido van Rossumb6775db1994-08-01 11:34:53 +00008417#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008418/*[clinic input]
8419os.tcsetpgrp
8420
8421 fd: int
8422 pgid: pid_t
8423 /
8424
8425Set the process group associated with the terminal specified by fd.
8426[clinic start generated code]*/
8427
Larry Hastings2f936352014-08-05 14:04:04 +10008428static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008429os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8430/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008431{
Victor Stinner8c62be82010-05-06 00:08:46 +00008432 if (tcsetpgrp(fd, pgid) < 0)
8433 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008434 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008435}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008436#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008437
Guido van Rossum687dd131993-05-17 08:34:16 +00008438/* Functions acting on file descriptors */
8439
Victor Stinnerdaf45552013-08-28 00:53:59 +02008440#ifdef O_CLOEXEC
8441extern int _Py_open_cloexec_works;
8442#endif
8443
Larry Hastings2f936352014-08-05 14:04:04 +10008444
8445/*[clinic input]
8446os.open -> int
8447 path: path_t
8448 flags: int
8449 mode: int = 0o777
8450 *
8451 dir_fd: dir_fd(requires='openat') = None
8452
8453# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8454
8455Open a file for low level IO. Returns a file descriptor (integer).
8456
8457If dir_fd is not None, it should be a file descriptor open to a directory,
8458 and path should be relative; path will then be relative to that directory.
8459dir_fd may not be implemented on your platform.
8460 If it is unavailable, using it will raise a NotImplementedError.
8461[clinic start generated code]*/
8462
Larry Hastings2f936352014-08-05 14:04:04 +10008463static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008464os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8465/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008466{
8467 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008468 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008469
Victor Stinnerdaf45552013-08-28 00:53:59 +02008470#ifdef O_CLOEXEC
8471 int *atomic_flag_works = &_Py_open_cloexec_works;
8472#elif !defined(MS_WINDOWS)
8473 int *atomic_flag_works = NULL;
8474#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008475
Victor Stinnerdaf45552013-08-28 00:53:59 +02008476#ifdef MS_WINDOWS
8477 flags |= O_NOINHERIT;
8478#elif defined(O_CLOEXEC)
8479 flags |= O_CLOEXEC;
8480#endif
8481
Steve Dowerb82e17e2019-05-23 08:45:22 -07008482 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
8483 return -1;
8484 }
8485
Steve Dower8fc89802015-04-12 00:26:27 -04008486 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008487 do {
8488 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008489#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008490 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008491#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008492#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008493 if (dir_fd != DEFAULT_DIR_FD)
8494 fd = openat(dir_fd, path->narrow, flags, mode);
8495 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008496#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008497 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008498#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008499 Py_END_ALLOW_THREADS
8500 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008501 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008502
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008503 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008504 if (!async_err)
8505 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008506 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008507 }
8508
Victor Stinnerdaf45552013-08-28 00:53:59 +02008509#ifndef MS_WINDOWS
8510 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8511 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008512 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008513 }
8514#endif
8515
Larry Hastings2f936352014-08-05 14:04:04 +10008516 return fd;
8517}
8518
8519
8520/*[clinic input]
8521os.close
8522
8523 fd: int
8524
8525Close a file descriptor.
8526[clinic start generated code]*/
8527
Barry Warsaw53699e91996-12-10 23:23:01 +00008528static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008529os_close_impl(PyObject *module, int fd)
8530/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008531{
Larry Hastings2f936352014-08-05 14:04:04 +10008532 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008533 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8534 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8535 * for more details.
8536 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008537 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008538 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008539 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008540 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008541 Py_END_ALLOW_THREADS
8542 if (res < 0)
8543 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008544 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008545}
8546
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008547
Jakub Kulíke20134f2019-09-11 17:11:57 +02008548#ifdef HAVE_FDWALK
8549static int
8550_fdwalk_close_func(void *lohi, int fd)
8551{
8552 int lo = ((int *)lohi)[0];
8553 int hi = ((int *)lohi)[1];
8554
8555 if (fd >= hi)
8556 return 1;
8557 else if (fd >= lo)
8558 close(fd);
8559 return 0;
8560}
8561#endif /* HAVE_FDWALK */
8562
Larry Hastings2f936352014-08-05 14:04:04 +10008563/*[clinic input]
8564os.closerange
8565
8566 fd_low: int
8567 fd_high: int
8568 /
8569
8570Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8571[clinic start generated code]*/
8572
Larry Hastings2f936352014-08-05 14:04:04 +10008573static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008574os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8575/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008576{
Jakub Kulíke20134f2019-09-11 17:11:57 +02008577#ifdef HAVE_FDWALK
8578 int lohi[2];
8579#else
Larry Hastings2f936352014-08-05 14:04:04 +10008580 int i;
Jakub Kulíke20134f2019-09-11 17:11:57 +02008581#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008582 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008583 _Py_BEGIN_SUPPRESS_IPH
Jakub Kulíke20134f2019-09-11 17:11:57 +02008584#ifdef HAVE_FDWALK
8585 lohi[0] = Py_MAX(fd_low, 0);
8586 lohi[1] = fd_high;
8587 fdwalk(_fdwalk_close_func, lohi);
8588#else
Benjamin Peterson207116b2016-09-08 11:28:06 -07008589 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008590 close(i);
Jakub Kulíke20134f2019-09-11 17:11:57 +02008591#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008592 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008593 Py_END_ALLOW_THREADS
8594 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008595}
8596
8597
Larry Hastings2f936352014-08-05 14:04:04 +10008598/*[clinic input]
8599os.dup -> int
8600
8601 fd: int
8602 /
8603
8604Return a duplicate of a file descriptor.
8605[clinic start generated code]*/
8606
Larry Hastings2f936352014-08-05 14:04:04 +10008607static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008608os_dup_impl(PyObject *module, int fd)
8609/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008610{
8611 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008612}
8613
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008614
Larry Hastings2f936352014-08-05 14:04:04 +10008615/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008616os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008617 fd: int
8618 fd2: int
8619 inheritable: bool=True
8620
8621Duplicate file descriptor.
8622[clinic start generated code]*/
8623
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008624static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008625os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008626/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008627{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008628 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008629#if defined(HAVE_DUP3) && \
8630 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8631 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008632 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008633#endif
8634
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008635 if (fd < 0 || fd2 < 0) {
8636 posix_error();
8637 return -1;
8638 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008639
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008640 /* dup2() can fail with EINTR if the target FD is already open, because it
8641 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8642 * upon close(), and therefore below.
8643 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008644#ifdef MS_WINDOWS
8645 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008646 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008647 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008648 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008649 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008650 if (res < 0) {
8651 posix_error();
8652 return -1;
8653 }
8654 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008655
8656 /* Character files like console cannot be make non-inheritable */
8657 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8658 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008659 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008660 }
8661
8662#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8663 Py_BEGIN_ALLOW_THREADS
8664 if (!inheritable)
8665 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8666 else
8667 res = dup2(fd, fd2);
8668 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008669 if (res < 0) {
8670 posix_error();
8671 return -1;
8672 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008673
8674#else
8675
8676#ifdef HAVE_DUP3
8677 if (!inheritable && dup3_works != 0) {
8678 Py_BEGIN_ALLOW_THREADS
8679 res = dup3(fd, fd2, O_CLOEXEC);
8680 Py_END_ALLOW_THREADS
8681 if (res < 0) {
8682 if (dup3_works == -1)
8683 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008684 if (dup3_works) {
8685 posix_error();
8686 return -1;
8687 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008688 }
8689 }
8690
8691 if (inheritable || dup3_works == 0)
8692 {
8693#endif
8694 Py_BEGIN_ALLOW_THREADS
8695 res = dup2(fd, fd2);
8696 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008697 if (res < 0) {
8698 posix_error();
8699 return -1;
8700 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008701
8702 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8703 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008704 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008705 }
8706#ifdef HAVE_DUP3
8707 }
8708#endif
8709
8710#endif
8711
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008712 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008713}
8714
Larry Hastings2f936352014-08-05 14:04:04 +10008715
Ross Lagerwall7807c352011-03-17 20:20:30 +02008716#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008717/*[clinic input]
8718os.lockf
8719
8720 fd: int
8721 An open file descriptor.
8722 command: int
8723 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8724 length: Py_off_t
8725 The number of bytes to lock, starting at the current position.
8726 /
8727
8728Apply, test or remove a POSIX lock on an open file descriptor.
8729
8730[clinic start generated code]*/
8731
Larry Hastings2f936352014-08-05 14:04:04 +10008732static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008733os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8734/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008735{
8736 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008737
8738 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008739 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008740 Py_END_ALLOW_THREADS
8741
8742 if (res < 0)
8743 return posix_error();
8744
8745 Py_RETURN_NONE;
8746}
Larry Hastings2f936352014-08-05 14:04:04 +10008747#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008749
Larry Hastings2f936352014-08-05 14:04:04 +10008750/*[clinic input]
8751os.lseek -> Py_off_t
8752
8753 fd: int
8754 position: Py_off_t
8755 how: int
8756 /
8757
8758Set the position of a file descriptor. Return the new position.
8759
8760Return the new cursor position in number of bytes
8761relative to the beginning of the file.
8762[clinic start generated code]*/
8763
Larry Hastings2f936352014-08-05 14:04:04 +10008764static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008765os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8766/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008767{
8768 Py_off_t result;
8769
Guido van Rossum687dd131993-05-17 08:34:16 +00008770#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008771 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8772 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008773 case 0: how = SEEK_SET; break;
8774 case 1: how = SEEK_CUR; break;
8775 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008776 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008777#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008778
Victor Stinner8c62be82010-05-06 00:08:46 +00008779 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008780 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008781#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008782 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008783#else
Larry Hastings2f936352014-08-05 14:04:04 +10008784 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008785#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008786 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008787 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008788 if (result < 0)
8789 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008790
Larry Hastings2f936352014-08-05 14:04:04 +10008791 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008792}
8793
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008794
Larry Hastings2f936352014-08-05 14:04:04 +10008795/*[clinic input]
8796os.read
8797 fd: int
8798 length: Py_ssize_t
8799 /
8800
8801Read from a file descriptor. Returns a bytes object.
8802[clinic start generated code]*/
8803
Larry Hastings2f936352014-08-05 14:04:04 +10008804static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008805os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8806/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008807{
Victor Stinner8c62be82010-05-06 00:08:46 +00008808 Py_ssize_t n;
8809 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008810
8811 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008812 errno = EINVAL;
8813 return posix_error();
8814 }
Larry Hastings2f936352014-08-05 14:04:04 +10008815
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008816 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008817
8818 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008819 if (buffer == NULL)
8820 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008821
Victor Stinner66aab0c2015-03-19 22:53:20 +01008822 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8823 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008824 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008825 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008826 }
Larry Hastings2f936352014-08-05 14:04:04 +10008827
8828 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008829 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008830
Victor Stinner8c62be82010-05-06 00:08:46 +00008831 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008832}
8833
Ross Lagerwall7807c352011-03-17 20:20:30 +02008834#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008835 || defined(__APPLE__))) \
8836 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8837 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8838static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008839iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008840{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008841 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008842
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008843 *iov = PyMem_New(struct iovec, cnt);
8844 if (*iov == NULL) {
8845 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008846 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008847 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008848
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008849 *buf = PyMem_New(Py_buffer, cnt);
8850 if (*buf == NULL) {
8851 PyMem_Del(*iov);
8852 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008853 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008854 }
8855
8856 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008857 PyObject *item = PySequence_GetItem(seq, i);
8858 if (item == NULL)
8859 goto fail;
8860 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8861 Py_DECREF(item);
8862 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008863 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008864 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008865 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008866 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008867 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008868 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008869
8870fail:
8871 PyMem_Del(*iov);
8872 for (j = 0; j < i; j++) {
8873 PyBuffer_Release(&(*buf)[j]);
8874 }
8875 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008876 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008877}
8878
8879static void
8880iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8881{
8882 int i;
8883 PyMem_Del(iov);
8884 for (i = 0; i < cnt; i++) {
8885 PyBuffer_Release(&buf[i]);
8886 }
8887 PyMem_Del(buf);
8888}
8889#endif
8890
Larry Hastings2f936352014-08-05 14:04:04 +10008891
Ross Lagerwall7807c352011-03-17 20:20:30 +02008892#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008893/*[clinic input]
8894os.readv -> Py_ssize_t
8895
8896 fd: int
8897 buffers: object
8898 /
8899
8900Read from a file descriptor fd into an iterable of buffers.
8901
8902The buffers should be mutable buffers accepting bytes.
8903readv will transfer data into each buffer until it is full
8904and then move on to the next buffer in the sequence to hold
8905the rest of the data.
8906
8907readv returns the total number of bytes read,
8908which may be less than the total capacity of all the buffers.
8909[clinic start generated code]*/
8910
Larry Hastings2f936352014-08-05 14:04:04 +10008911static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008912os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8913/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008914{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008915 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008916 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008917 struct iovec *iov;
8918 Py_buffer *buf;
8919
Larry Hastings2f936352014-08-05 14:04:04 +10008920 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008921 PyErr_SetString(PyExc_TypeError,
8922 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008923 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008924 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008925
Larry Hastings2f936352014-08-05 14:04:04 +10008926 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008927 if (cnt < 0)
8928 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008929
8930 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8931 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008932
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008933 do {
8934 Py_BEGIN_ALLOW_THREADS
8935 n = readv(fd, iov, cnt);
8936 Py_END_ALLOW_THREADS
8937 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008938
8939 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008940 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008941 if (!async_err)
8942 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008943 return -1;
8944 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008945
Larry Hastings2f936352014-08-05 14:04:04 +10008946 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008947}
Larry Hastings2f936352014-08-05 14:04:04 +10008948#endif /* HAVE_READV */
8949
Ross Lagerwall7807c352011-03-17 20:20:30 +02008950
8951#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008952/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10008953os.pread
8954
8955 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09008956 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10008957 offset: Py_off_t
8958 /
8959
8960Read a number of bytes from a file descriptor starting at a particular offset.
8961
8962Read length bytes from file descriptor fd, starting at offset bytes from
8963the beginning of the file. The file offset remains unchanged.
8964[clinic start generated code]*/
8965
Larry Hastings2f936352014-08-05 14:04:04 +10008966static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09008967os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
8968/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008969{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008970 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008971 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008972 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008973
Larry Hastings2f936352014-08-05 14:04:04 +10008974 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008975 errno = EINVAL;
8976 return posix_error();
8977 }
Larry Hastings2f936352014-08-05 14:04:04 +10008978 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008979 if (buffer == NULL)
8980 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008981
8982 do {
8983 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008984 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008985 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008986 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008987 Py_END_ALLOW_THREADS
8988 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8989
Ross Lagerwall7807c352011-03-17 20:20:30 +02008990 if (n < 0) {
8991 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008992 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008993 }
Larry Hastings2f936352014-08-05 14:04:04 +10008994 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008995 _PyBytes_Resize(&buffer, n);
8996 return buffer;
8997}
Larry Hastings2f936352014-08-05 14:04:04 +10008998#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008999
Pablo Galindo4defba32018-01-27 16:16:37 +00009000#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9001/*[clinic input]
9002os.preadv -> Py_ssize_t
9003
9004 fd: int
9005 buffers: object
9006 offset: Py_off_t
9007 flags: int = 0
9008 /
9009
9010Reads from a file descriptor into a number of mutable bytes-like objects.
9011
9012Combines the functionality of readv() and pread(). As readv(), it will
9013transfer data into each buffer until it is full and then move on to the next
9014buffer in the sequence to hold the rest of the data. Its fourth argument,
9015specifies the file offset at which the input operation is to be performed. It
9016will return the total number of bytes read (which can be less than the total
9017capacity of all the objects).
9018
9019The flags argument contains a bitwise OR of zero or more of the following flags:
9020
9021- RWF_HIPRI
9022- RWF_NOWAIT
9023
9024Using non-zero flags requires Linux 4.6 or newer.
9025[clinic start generated code]*/
9026
9027static Py_ssize_t
9028os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9029 int flags)
9030/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9031{
9032 Py_ssize_t cnt, n;
9033 int async_err = 0;
9034 struct iovec *iov;
9035 Py_buffer *buf;
9036
9037 if (!PySequence_Check(buffers)) {
9038 PyErr_SetString(PyExc_TypeError,
9039 "preadv2() arg 2 must be a sequence");
9040 return -1;
9041 }
9042
9043 cnt = PySequence_Size(buffers);
9044 if (cnt < 0) {
9045 return -1;
9046 }
9047
9048#ifndef HAVE_PREADV2
9049 if(flags != 0) {
9050 argument_unavailable_error("preadv2", "flags");
9051 return -1;
9052 }
9053#endif
9054
9055 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9056 return -1;
9057 }
9058#ifdef HAVE_PREADV2
9059 do {
9060 Py_BEGIN_ALLOW_THREADS
9061 _Py_BEGIN_SUPPRESS_IPH
9062 n = preadv2(fd, iov, cnt, offset, flags);
9063 _Py_END_SUPPRESS_IPH
9064 Py_END_ALLOW_THREADS
9065 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9066#else
9067 do {
9068 Py_BEGIN_ALLOW_THREADS
9069 _Py_BEGIN_SUPPRESS_IPH
9070 n = preadv(fd, iov, cnt, offset);
9071 _Py_END_SUPPRESS_IPH
9072 Py_END_ALLOW_THREADS
9073 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9074#endif
9075
9076 iov_cleanup(iov, buf, cnt);
9077 if (n < 0) {
9078 if (!async_err) {
9079 posix_error();
9080 }
9081 return -1;
9082 }
9083
9084 return n;
9085}
9086#endif /* HAVE_PREADV */
9087
Larry Hastings2f936352014-08-05 14:04:04 +10009088
9089/*[clinic input]
9090os.write -> Py_ssize_t
9091
9092 fd: int
9093 data: Py_buffer
9094 /
9095
9096Write a bytes object to a file descriptor.
9097[clinic start generated code]*/
9098
Larry Hastings2f936352014-08-05 14:04:04 +10009099static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009100os_write_impl(PyObject *module, int fd, Py_buffer *data)
9101/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009102{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009103 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009104}
9105
9106#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009107PyDoc_STRVAR(posix_sendfile__doc__,
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009108"sendfile(out_fd, in_fd, offset, count) -> byteswritten\n\
9109sendfile(out_fd, in_fd, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009110 -> byteswritten\n\
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009111Copy count bytes from file descriptor in_fd to file descriptor out_fd.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009112
Larry Hastings2f936352014-08-05 14:04:04 +10009113/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009114static PyObject *
9115posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
9116{
9117 int in, out;
9118 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009119 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009120 off_t offset;
9121
9122#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9123#ifndef __APPLE__
9124 Py_ssize_t len;
9125#endif
9126 PyObject *headers = NULL, *trailers = NULL;
9127 Py_buffer *hbuf, *tbuf;
9128 off_t sbytes;
9129 struct sf_hdtr sf;
9130 int flags = 0;
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009131 static char *keywords[] = {"out_fd", "in_fd",
Benjamin Petersond8a43b42011-02-26 21:35:16 +00009132 "offset", "count",
9133 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009134
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009135 sf.headers = NULL;
9136 sf.trailers = NULL;
9137
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009138#ifdef __APPLE__
9139 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10009140 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009141#else
9142 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10009143 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009144#endif
9145 &headers, &trailers, &flags))
9146 return NULL;
9147 if (headers != NULL) {
9148 if (!PySequence_Check(headers)) {
9149 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009150 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009151 return NULL;
9152 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009153 Py_ssize_t i = PySequence_Size(headers);
9154 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009155 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009156 if (i > INT_MAX) {
9157 PyErr_SetString(PyExc_OverflowError,
9158 "sendfile() header is too large");
9159 return NULL;
9160 }
9161 if (i > 0) {
9162 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009163 if (iov_setup(&(sf.headers), &hbuf,
9164 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009165 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009166#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009167 for (i = 0; i < sf.hdr_cnt; i++) {
9168 Py_ssize_t blen = sf.headers[i].iov_len;
9169# define OFF_T_MAX 0x7fffffffffffffff
9170 if (sbytes >= OFF_T_MAX - blen) {
9171 PyErr_SetString(PyExc_OverflowError,
9172 "sendfile() header is too large");
9173 return NULL;
9174 }
9175 sbytes += blen;
9176 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009177#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009178 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009179 }
9180 }
9181 if (trailers != NULL) {
9182 if (!PySequence_Check(trailers)) {
9183 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009184 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009185 return NULL;
9186 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009187 Py_ssize_t i = PySequence_Size(trailers);
9188 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009189 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009190 if (i > INT_MAX) {
9191 PyErr_SetString(PyExc_OverflowError,
9192 "sendfile() trailer is too large");
9193 return NULL;
9194 }
9195 if (i > 0) {
9196 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009197 if (iov_setup(&(sf.trailers), &tbuf,
9198 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009199 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009200 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009201 }
9202 }
9203
Steve Dower8fc89802015-04-12 00:26:27 -04009204 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009205 do {
9206 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009207#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009208 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009209#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009210 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009211#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009212 Py_END_ALLOW_THREADS
9213 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009214 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009215
9216 if (sf.headers != NULL)
9217 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9218 if (sf.trailers != NULL)
9219 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9220
9221 if (ret < 0) {
9222 if ((errno == EAGAIN) || (errno == EBUSY)) {
9223 if (sbytes != 0) {
9224 // some data has been sent
9225 goto done;
9226 }
9227 else {
9228 // no data has been sent; upper application is supposed
9229 // to retry on EAGAIN or EBUSY
9230 return posix_error();
9231 }
9232 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009233 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009234 }
9235 goto done;
9236
9237done:
9238 #if !defined(HAVE_LARGEFILE_SUPPORT)
9239 return Py_BuildValue("l", sbytes);
9240 #else
9241 return Py_BuildValue("L", sbytes);
9242 #endif
9243
9244#else
9245 Py_ssize_t count;
9246 PyObject *offobj;
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009247 static char *keywords[] = {"out_fd", "in_fd",
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009248 "offset", "count", NULL};
9249 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
9250 keywords, &out, &in, &offobj, &count))
9251 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009252#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009253 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009254 do {
9255 Py_BEGIN_ALLOW_THREADS
9256 ret = sendfile(out, in, NULL, count);
9257 Py_END_ALLOW_THREADS
9258 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009259 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009260 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009261 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009262 }
9263#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009264 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009265 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009266
9267 do {
9268 Py_BEGIN_ALLOW_THREADS
9269 ret = sendfile(out, in, &offset, count);
9270 Py_END_ALLOW_THREADS
9271 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009272 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009273 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009274 return Py_BuildValue("n", ret);
9275#endif
9276}
Larry Hastings2f936352014-08-05 14:04:04 +10009277#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009278
Larry Hastings2f936352014-08-05 14:04:04 +10009279
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009280#if defined(__APPLE__)
9281/*[clinic input]
9282os._fcopyfile
9283
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009284 in_fd: int
9285 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009286 flags: int
9287 /
9288
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009289Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009290[clinic start generated code]*/
9291
9292static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009293os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9294/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009295{
9296 int ret;
9297
9298 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009299 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009300 Py_END_ALLOW_THREADS
9301 if (ret < 0)
9302 return posix_error();
9303 Py_RETURN_NONE;
9304}
9305#endif
9306
9307
Larry Hastings2f936352014-08-05 14:04:04 +10009308/*[clinic input]
9309os.fstat
9310
9311 fd : int
9312
9313Perform a stat system call on the given file descriptor.
9314
9315Like stat(), but for an open file descriptor.
9316Equivalent to os.stat(fd).
9317[clinic start generated code]*/
9318
Larry Hastings2f936352014-08-05 14:04:04 +10009319static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009320os_fstat_impl(PyObject *module, int fd)
9321/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009322{
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 STRUCT_STAT st;
9324 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009325 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009326
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009327 do {
9328 Py_BEGIN_ALLOW_THREADS
9329 res = FSTAT(fd, &st);
9330 Py_END_ALLOW_THREADS
9331 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009333#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009334 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009335#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009336 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009337#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 }
Tim Peters5aa91602002-01-30 05:46:57 +00009339
Victor Stinner4195b5c2012-02-08 23:03:19 +01009340 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009341}
9342
Larry Hastings2f936352014-08-05 14:04:04 +10009343
9344/*[clinic input]
9345os.isatty -> bool
9346 fd: int
9347 /
9348
9349Return True if the fd is connected to a terminal.
9350
9351Return True if the file descriptor is an open file descriptor
9352connected to the slave end of a terminal.
9353[clinic start generated code]*/
9354
Larry Hastings2f936352014-08-05 14:04:04 +10009355static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009356os_isatty_impl(PyObject *module, int fd)
9357/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009358{
Steve Dower8fc89802015-04-12 00:26:27 -04009359 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009360 _Py_BEGIN_SUPPRESS_IPH
9361 return_value = isatty(fd);
9362 _Py_END_SUPPRESS_IPH
9363 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009364}
9365
9366
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009367#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009368/*[clinic input]
9369os.pipe
9370
9371Create a pipe.
9372
9373Returns a tuple of two file descriptors:
9374 (read_fd, write_fd)
9375[clinic start generated code]*/
9376
Larry Hastings2f936352014-08-05 14:04:04 +10009377static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009378os_pipe_impl(PyObject *module)
9379/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009380{
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009382#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009384 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009386#else
9387 int res;
9388#endif
9389
9390#ifdef MS_WINDOWS
9391 attr.nLength = sizeof(attr);
9392 attr.lpSecurityDescriptor = NULL;
9393 attr.bInheritHandle = FALSE;
9394
9395 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009396 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009397 ok = CreatePipe(&read, &write, &attr, 0);
9398 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009399 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9400 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009401 if (fds[0] == -1 || fds[1] == -1) {
9402 CloseHandle(read);
9403 CloseHandle(write);
9404 ok = 0;
9405 }
9406 }
Steve Dowerc3630612016-11-19 18:41:16 -08009407 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009408 Py_END_ALLOW_THREADS
9409
Victor Stinner8c62be82010-05-06 00:08:46 +00009410 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009411 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009412#else
9413
9414#ifdef HAVE_PIPE2
9415 Py_BEGIN_ALLOW_THREADS
9416 res = pipe2(fds, O_CLOEXEC);
9417 Py_END_ALLOW_THREADS
9418
9419 if (res != 0 && errno == ENOSYS)
9420 {
9421#endif
9422 Py_BEGIN_ALLOW_THREADS
9423 res = pipe(fds);
9424 Py_END_ALLOW_THREADS
9425
9426 if (res == 0) {
9427 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9428 close(fds[0]);
9429 close(fds[1]);
9430 return NULL;
9431 }
9432 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9433 close(fds[0]);
9434 close(fds[1]);
9435 return NULL;
9436 }
9437 }
9438#ifdef HAVE_PIPE2
9439 }
9440#endif
9441
9442 if (res != 0)
9443 return PyErr_SetFromErrno(PyExc_OSError);
9444#endif /* !MS_WINDOWS */
9445 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009446}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009447#endif /* HAVE_PIPE */
9448
Larry Hastings2f936352014-08-05 14:04:04 +10009449
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009450#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009451/*[clinic input]
9452os.pipe2
9453
9454 flags: int
9455 /
9456
9457Create a pipe with flags set atomically.
9458
9459Returns a tuple of two file descriptors:
9460 (read_fd, write_fd)
9461
9462flags can be constructed by ORing together one or more of these values:
9463O_NONBLOCK, O_CLOEXEC.
9464[clinic start generated code]*/
9465
Larry Hastings2f936352014-08-05 14:04:04 +10009466static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009467os_pipe2_impl(PyObject *module, int flags)
9468/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009469{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009470 int fds[2];
9471 int res;
9472
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009473 res = pipe2(fds, flags);
9474 if (res != 0)
9475 return posix_error();
9476 return Py_BuildValue("(ii)", fds[0], fds[1]);
9477}
9478#endif /* HAVE_PIPE2 */
9479
Larry Hastings2f936352014-08-05 14:04:04 +10009480
Ross Lagerwall7807c352011-03-17 20:20:30 +02009481#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009482/*[clinic input]
9483os.writev -> Py_ssize_t
9484 fd: int
9485 buffers: object
9486 /
9487
9488Iterate over buffers, and write the contents of each to a file descriptor.
9489
9490Returns the total number of bytes written.
9491buffers must be a sequence of bytes-like objects.
9492[clinic start generated code]*/
9493
Larry Hastings2f936352014-08-05 14:04:04 +10009494static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009495os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9496/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009497{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009498 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009499 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009500 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009501 struct iovec *iov;
9502 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009503
9504 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009505 PyErr_SetString(PyExc_TypeError,
9506 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009507 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009508 }
Larry Hastings2f936352014-08-05 14:04:04 +10009509 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009510 if (cnt < 0)
9511 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009512
Larry Hastings2f936352014-08-05 14:04:04 +10009513 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9514 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009515 }
9516
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009517 do {
9518 Py_BEGIN_ALLOW_THREADS
9519 result = writev(fd, iov, cnt);
9520 Py_END_ALLOW_THREADS
9521 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009522
9523 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009524 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009525 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009526
Georg Brandl306336b2012-06-24 12:55:33 +02009527 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009528}
Larry Hastings2f936352014-08-05 14:04:04 +10009529#endif /* HAVE_WRITEV */
9530
9531
9532#ifdef HAVE_PWRITE
9533/*[clinic input]
9534os.pwrite -> Py_ssize_t
9535
9536 fd: int
9537 buffer: Py_buffer
9538 offset: Py_off_t
9539 /
9540
9541Write bytes to a file descriptor starting at a particular offset.
9542
9543Write buffer to fd, starting at offset bytes from the beginning of
9544the file. Returns the number of bytes writte. Does not change the
9545current file offset.
9546[clinic start generated code]*/
9547
Larry Hastings2f936352014-08-05 14:04:04 +10009548static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009549os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9550/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009551{
9552 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009553 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009554
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009555 do {
9556 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009557 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009558 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009559 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009560 Py_END_ALLOW_THREADS
9561 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009562
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009563 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009564 posix_error();
9565 return size;
9566}
9567#endif /* HAVE_PWRITE */
9568
Pablo Galindo4defba32018-01-27 16:16:37 +00009569#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9570/*[clinic input]
9571os.pwritev -> Py_ssize_t
9572
9573 fd: int
9574 buffers: object
9575 offset: Py_off_t
9576 flags: int = 0
9577 /
9578
9579Writes the contents of bytes-like objects to a file descriptor at a given offset.
9580
9581Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9582of bytes-like objects. Buffers are processed in array order. Entire contents of first
9583buffer is written before proceeding to second, and so on. The operating system may
9584set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9585This function writes the contents of each object to the file descriptor and returns
9586the total number of bytes written.
9587
9588The flags argument contains a bitwise OR of zero or more of the following flags:
9589
9590- RWF_DSYNC
9591- RWF_SYNC
9592
9593Using non-zero flags requires Linux 4.7 or newer.
9594[clinic start generated code]*/
9595
9596static Py_ssize_t
9597os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9598 int flags)
9599/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9600{
9601 Py_ssize_t cnt;
9602 Py_ssize_t result;
9603 int async_err = 0;
9604 struct iovec *iov;
9605 Py_buffer *buf;
9606
9607 if (!PySequence_Check(buffers)) {
9608 PyErr_SetString(PyExc_TypeError,
9609 "pwritev() arg 2 must be a sequence");
9610 return -1;
9611 }
9612
9613 cnt = PySequence_Size(buffers);
9614 if (cnt < 0) {
9615 return -1;
9616 }
9617
9618#ifndef HAVE_PWRITEV2
9619 if(flags != 0) {
9620 argument_unavailable_error("pwritev2", "flags");
9621 return -1;
9622 }
9623#endif
9624
9625 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9626 return -1;
9627 }
9628#ifdef HAVE_PWRITEV2
9629 do {
9630 Py_BEGIN_ALLOW_THREADS
9631 _Py_BEGIN_SUPPRESS_IPH
9632 result = pwritev2(fd, iov, cnt, offset, flags);
9633 _Py_END_SUPPRESS_IPH
9634 Py_END_ALLOW_THREADS
9635 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9636#else
9637 do {
9638 Py_BEGIN_ALLOW_THREADS
9639 _Py_BEGIN_SUPPRESS_IPH
9640 result = pwritev(fd, iov, cnt, offset);
9641 _Py_END_SUPPRESS_IPH
9642 Py_END_ALLOW_THREADS
9643 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9644#endif
9645
9646 iov_cleanup(iov, buf, cnt);
9647 if (result < 0) {
9648 if (!async_err) {
9649 posix_error();
9650 }
9651 return -1;
9652 }
9653
9654 return result;
9655}
9656#endif /* HAVE_PWRITEV */
9657
Pablo Galindoaac4d032019-05-31 19:39:47 +01009658#ifdef HAVE_COPY_FILE_RANGE
9659/*[clinic input]
9660
9661os.copy_file_range
9662 src: int
9663 Source file descriptor.
9664 dst: int
9665 Destination file descriptor.
9666 count: Py_ssize_t
9667 Number of bytes to copy.
9668 offset_src: object = None
9669 Starting offset in src.
9670 offset_dst: object = None
9671 Starting offset in dst.
9672
9673Copy count bytes from one file descriptor to another.
9674
9675If offset_src is None, then src is read from the current position;
9676respectively for offset_dst.
9677[clinic start generated code]*/
9678
9679static PyObject *
9680os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
9681 PyObject *offset_src, PyObject *offset_dst)
9682/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
9683{
9684 off_t offset_src_val, offset_dst_val;
9685 off_t *p_offset_src = NULL;
9686 off_t *p_offset_dst = NULL;
9687 Py_ssize_t ret;
9688 int async_err = 0;
9689 /* The flags argument is provided to allow
9690 * for future extensions and currently must be to 0. */
9691 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +00009692
9693
Pablo Galindoaac4d032019-05-31 19:39:47 +01009694 if (count < 0) {
9695 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
9696 return NULL;
9697 }
9698
9699 if (offset_src != Py_None) {
9700 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
9701 return NULL;
9702 }
9703 p_offset_src = &offset_src_val;
9704 }
9705
9706 if (offset_dst != Py_None) {
9707 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
9708 return NULL;
9709 }
9710 p_offset_dst = &offset_dst_val;
9711 }
9712
9713 do {
9714 Py_BEGIN_ALLOW_THREADS
9715 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
9716 Py_END_ALLOW_THREADS
9717 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9718
9719 if (ret < 0) {
9720 return (!async_err) ? posix_error() : NULL;
9721 }
9722
9723 return PyLong_FromSsize_t(ret);
9724}
9725#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +10009726
9727#ifdef HAVE_MKFIFO
9728/*[clinic input]
9729os.mkfifo
9730
9731 path: path_t
9732 mode: int=0o666
9733 *
9734 dir_fd: dir_fd(requires='mkfifoat')=None
9735
9736Create a "fifo" (a POSIX named pipe).
9737
9738If dir_fd is not None, it should be a file descriptor open to a directory,
9739 and path should be relative; path will then be relative to that directory.
9740dir_fd may not be implemented on your platform.
9741 If it is unavailable, using it will raise a NotImplementedError.
9742[clinic start generated code]*/
9743
Larry Hastings2f936352014-08-05 14:04:04 +10009744static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009745os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9746/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009747{
9748 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009749 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009750
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009751 do {
9752 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009753#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009754 if (dir_fd != DEFAULT_DIR_FD)
9755 result = mkfifoat(dir_fd, path->narrow, mode);
9756 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009757#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009758 result = mkfifo(path->narrow, mode);
9759 Py_END_ALLOW_THREADS
9760 } while (result != 0 && errno == EINTR &&
9761 !(async_err = PyErr_CheckSignals()));
9762 if (result != 0)
9763 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009764
9765 Py_RETURN_NONE;
9766}
9767#endif /* HAVE_MKFIFO */
9768
9769
9770#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9771/*[clinic input]
9772os.mknod
9773
9774 path: path_t
9775 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009776 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009777 *
9778 dir_fd: dir_fd(requires='mknodat')=None
9779
9780Create a node in the file system.
9781
9782Create a node in the file system (file, device special file or named pipe)
9783at path. mode specifies both the permissions to use and the
9784type of node to be created, being combined (bitwise OR) with one of
9785S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9786device defines the newly created device special file (probably using
9787os.makedev()). Otherwise device is ignored.
9788
9789If dir_fd is not None, it should be a file descriptor open to a directory,
9790 and path should be relative; path will then be relative to that directory.
9791dir_fd may not be implemented on your platform.
9792 If it is unavailable, using it will raise a NotImplementedError.
9793[clinic start generated code]*/
9794
Larry Hastings2f936352014-08-05 14:04:04 +10009795static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009796os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009797 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009798/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009799{
9800 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009801 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009802
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009803 do {
9804 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009805#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009806 if (dir_fd != DEFAULT_DIR_FD)
9807 result = mknodat(dir_fd, path->narrow, mode, device);
9808 else
Larry Hastings2f936352014-08-05 14:04:04 +10009809#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009810 result = mknod(path->narrow, mode, device);
9811 Py_END_ALLOW_THREADS
9812 } while (result != 0 && errno == EINTR &&
9813 !(async_err = PyErr_CheckSignals()));
9814 if (result != 0)
9815 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009816
9817 Py_RETURN_NONE;
9818}
9819#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9820
9821
9822#ifdef HAVE_DEVICE_MACROS
9823/*[clinic input]
9824os.major -> unsigned_int
9825
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009826 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009827 /
9828
9829Extracts a device major number from a raw device number.
9830[clinic start generated code]*/
9831
Larry Hastings2f936352014-08-05 14:04:04 +10009832static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009833os_major_impl(PyObject *module, dev_t device)
9834/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009835{
9836 return major(device);
9837}
9838
9839
9840/*[clinic input]
9841os.minor -> unsigned_int
9842
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009843 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009844 /
9845
9846Extracts a device minor number from a raw device number.
9847[clinic start generated code]*/
9848
Larry Hastings2f936352014-08-05 14:04:04 +10009849static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009850os_minor_impl(PyObject *module, dev_t device)
9851/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009852{
9853 return minor(device);
9854}
9855
9856
9857/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009858os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009859
9860 major: int
9861 minor: int
9862 /
9863
9864Composes a raw device number from the major and minor device numbers.
9865[clinic start generated code]*/
9866
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009867static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009868os_makedev_impl(PyObject *module, int major, int minor)
9869/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009870{
9871 return makedev(major, minor);
9872}
9873#endif /* HAVE_DEVICE_MACROS */
9874
9875
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009876#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009877/*[clinic input]
9878os.ftruncate
9879
9880 fd: int
9881 length: Py_off_t
9882 /
9883
9884Truncate a file, specified by file descriptor, to a specific length.
9885[clinic start generated code]*/
9886
Larry Hastings2f936352014-08-05 14:04:04 +10009887static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009888os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9889/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009890{
9891 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009892 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009893
Steve Dowerb82e17e2019-05-23 08:45:22 -07009894 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
9895 return NULL;
9896 }
9897
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009898 do {
9899 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009900 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009901#ifdef MS_WINDOWS
9902 result = _chsize_s(fd, length);
9903#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009904 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009905#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009906 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009907 Py_END_ALLOW_THREADS
9908 } while (result != 0 && errno == EINTR &&
9909 !(async_err = PyErr_CheckSignals()));
9910 if (result != 0)
9911 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009912 Py_RETURN_NONE;
9913}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009914#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009915
9916
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009917#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009918/*[clinic input]
9919os.truncate
9920 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9921 length: Py_off_t
9922
9923Truncate a file, specified by path, to a specific length.
9924
9925On some platforms, path may also be specified as an open file descriptor.
9926 If this functionality is unavailable, using it raises an exception.
9927[clinic start generated code]*/
9928
Larry Hastings2f936352014-08-05 14:04:04 +10009929static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009930os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9931/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009932{
9933 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009934#ifdef MS_WINDOWS
9935 int fd;
9936#endif
9937
9938 if (path->fd != -1)
9939 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009940
Steve Dowerb82e17e2019-05-23 08:45:22 -07009941 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
9942 return NULL;
9943 }
9944
Larry Hastings2f936352014-08-05 14:04:04 +10009945 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009946 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009947#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009948 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009949 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009950 result = -1;
9951 else {
9952 result = _chsize_s(fd, length);
9953 close(fd);
9954 if (result < 0)
9955 errno = result;
9956 }
9957#else
9958 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009959#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009960 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009961 Py_END_ALLOW_THREADS
9962 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009963 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009964
9965 Py_RETURN_NONE;
9966}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009967#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009968
Ross Lagerwall7807c352011-03-17 20:20:30 +02009969
Victor Stinnerd6b17692014-09-30 12:20:05 +02009970/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9971 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9972 defined, which is the case in Python on AIX. AIX bug report:
9973 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9974#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9975# define POSIX_FADVISE_AIX_BUG
9976#endif
9977
Victor Stinnerec39e262014-09-30 12:35:58 +02009978
Victor Stinnerd6b17692014-09-30 12:20:05 +02009979#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009980/*[clinic input]
9981os.posix_fallocate
9982
9983 fd: int
9984 offset: Py_off_t
9985 length: Py_off_t
9986 /
9987
9988Ensure a file has allocated at least a particular number of bytes on disk.
9989
9990Ensure that the file specified by fd encompasses a range of bytes
9991starting at offset bytes from the beginning and continuing for length bytes.
9992[clinic start generated code]*/
9993
Larry Hastings2f936352014-08-05 14:04:04 +10009994static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009995os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009996 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009997/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009998{
9999 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010000 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010001
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010002 do {
10003 Py_BEGIN_ALLOW_THREADS
10004 result = posix_fallocate(fd, offset, length);
10005 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010006 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10007
10008 if (result == 0)
10009 Py_RETURN_NONE;
10010
10011 if (async_err)
10012 return NULL;
10013
10014 errno = result;
10015 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010016}
Victor Stinnerec39e262014-09-30 12:35:58 +020010017#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010018
Ross Lagerwall7807c352011-03-17 20:20:30 +020010019
Victor Stinnerd6b17692014-09-30 12:20:05 +020010020#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010021/*[clinic input]
10022os.posix_fadvise
10023
10024 fd: int
10025 offset: Py_off_t
10026 length: Py_off_t
10027 advice: int
10028 /
10029
10030Announce an intention to access data in a specific pattern.
10031
10032Announce an intention to access data in a specific pattern, thus allowing
10033the kernel to make optimizations.
10034The advice applies to the region of the file specified by fd starting at
10035offset and continuing for length bytes.
10036advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10037POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10038POSIX_FADV_DONTNEED.
10039[clinic start generated code]*/
10040
Larry Hastings2f936352014-08-05 14:04:04 +100010041static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010042os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010043 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010044/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010045{
10046 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010047 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010048
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010049 do {
10050 Py_BEGIN_ALLOW_THREADS
10051 result = posix_fadvise(fd, offset, length, advice);
10052 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010053 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10054
10055 if (result == 0)
10056 Py_RETURN_NONE;
10057
10058 if (async_err)
10059 return NULL;
10060
10061 errno = result;
10062 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010063}
Victor Stinnerec39e262014-09-30 12:35:58 +020010064#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010065
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010066
Victor Stinner623ed612020-01-21 19:25:32 +010010067#ifdef PY_PUTENV_DICT
Larry Hastings2f936352014-08-05 14:04:04 +100010068static void
Victor Stinner623ed612020-01-21 19:25:32 +010010069posix_putenv_dict_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010070{
Victor Stinner623ed612020-01-21 19:25:32 +010010071 /* Install the first arg and newstr in putenv_dict;
Larry Hastings2f936352014-08-05 14:04:04 +100010072 * this will cause previous value to be collected. This has to
10073 * happen after the real putenv() call because the old value
10074 * was still accessible until then. */
Victor Stinner623ed612020-01-21 19:25:32 +010010075 if (PyDict_SetItem(_posixstate_global->putenv_dict, name, value))
Larry Hastings2f936352014-08-05 14:04:04 +100010076 /* really not much we can do; just leak */
10077 PyErr_Clear();
10078 else
10079 Py_DECREF(value);
10080}
Victor Stinner623ed612020-01-21 19:25:32 +010010081#endif /* PY_PUTENV_DICT */
Larry Hastings2f936352014-08-05 14:04:04 +100010082
10083
Victor Stinner623ed612020-01-21 19:25:32 +010010084#ifdef HAVE_PUTENV
10085
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010086#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010087/*[clinic input]
10088os.putenv
10089
10090 name: unicode
10091 value: unicode
10092 /
10093
10094Change or add an environment variable.
10095[clinic start generated code]*/
10096
Larry Hastings2f936352014-08-05 14:04:04 +100010097static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010098os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10099/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010100{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010101 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +030010102 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +100010103
Serhiy Storchaka77703942017-06-25 07:33:01 +030010104 /* Search from index 1 because on Windows starting '=' is allowed for
10105 defining hidden environment variables. */
10106 if (PyUnicode_GET_LENGTH(name) == 0 ||
10107 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10108 {
10109 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10110 return NULL;
10111 }
Larry Hastings2f936352014-08-05 14:04:04 +100010112 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
10113 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010114 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +000010115 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +030010116
10117 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
10118 if (env == NULL)
10119 goto error;
10120 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +010010121 PyErr_Format(PyExc_ValueError,
10122 "the environment variable is longer than %u characters",
10123 _MAX_ENV);
10124 goto error;
10125 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +030010126 if (wcslen(env) != (size_t)size) {
10127 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +020010128 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +030010129 }
10130
Larry Hastings2f936352014-08-05 14:04:04 +100010131 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +000010133 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 }
Victor Stinner0852c7d2020-01-22 21:53:26 +010010135 /* _wputenv(env) copies the *env* string and doesn't require the caller
10136 to manage the variable memory. */
10137 Py_DECREF(unicode);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010138
Victor Stinner84ae1182010-05-06 22:05:07 +000010139 Py_RETURN_NONE;
10140
10141error:
Larry Hastings2f936352014-08-05 14:04:04 +100010142 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +000010143 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010144}
Larry Hastings2f936352014-08-05 14:04:04 +100010145#else /* MS_WINDOWS */
10146/*[clinic input]
10147os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010148
Larry Hastings2f936352014-08-05 14:04:04 +100010149 name: FSConverter
10150 value: FSConverter
10151 /
10152
10153Change or add an environment variable.
10154[clinic start generated code]*/
10155
Larry Hastings2f936352014-08-05 14:04:04 +100010156static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010157os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10158/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010159{
10160 PyObject *bytes = NULL;
10161 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +030010162 const char *name_string = PyBytes_AS_STRING(name);
10163 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010164
Serhiy Storchaka77703942017-06-25 07:33:01 +030010165 if (strchr(name_string, '=') != NULL) {
10166 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10167 return NULL;
10168 }
Larry Hastings2f936352014-08-05 14:04:04 +100010169 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
10170 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010171 return NULL;
10172 }
10173
10174 env = PyBytes_AS_STRING(bytes);
10175 if (putenv(env)) {
10176 Py_DECREF(bytes);
10177 return posix_error();
10178 }
10179
Victor Stinner623ed612020-01-21 19:25:32 +010010180 posix_putenv_dict_setitem(name, bytes);
Larry Hastings2f936352014-08-05 14:04:04 +100010181 Py_RETURN_NONE;
10182}
10183#endif /* MS_WINDOWS */
10184#endif /* HAVE_PUTENV */
10185
10186
Victor Stinnerb73dd022020-01-22 21:11:17 +010010187#ifdef HAVE_UNSETENV
Larry Hastings2f936352014-08-05 14:04:04 +100010188/*[clinic input]
10189os.unsetenv
10190 name: FSConverter
10191 /
10192
10193Delete an environment variable.
10194[clinic start generated code]*/
10195
Larry Hastings2f936352014-08-05 14:04:04 +100010196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010197os_unsetenv_impl(PyObject *module, PyObject *name)
10198/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010199{
Victor Stinner984890f2011-11-24 13:53:38 +010010200#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +010010201 int err;
Victor Stinner984890f2011-11-24 13:53:38 +010010202#endif
Victor Stinner84ae1182010-05-06 22:05:07 +000010203
Victor Stinner984890f2011-11-24 13:53:38 +010010204#ifdef HAVE_BROKEN_UNSETENV
10205 unsetenv(PyBytes_AS_STRING(name));
10206#else
Victor Stinner65170952011-11-22 22:16:17 +010010207 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +100010208 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +010010209 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +010010210#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010211
Victor Stinner623ed612020-01-21 19:25:32 +010010212#ifdef PY_PUTENV_DICT
10213 /* Remove the key from putenv_dict;
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 * this will cause it to be collected. This has to
10215 * happen after the real unsetenv() call because the
10216 * old value was still accessible until then.
10217 */
Victor Stinner623ed612020-01-21 19:25:32 +010010218 if (PyDict_DelItem(_posixstate(module)->putenv_dict, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 /* really not much we can do; just leak */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +020010220 if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
10221 return NULL;
10222 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 PyErr_Clear();
10224 }
Victor Stinner623ed612020-01-21 19:25:32 +010010225#endif
10226
Victor Stinner84ae1182010-05-06 22:05:07 +000010227 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010228}
Larry Hastings2f936352014-08-05 14:04:04 +100010229#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +000010230
Larry Hastings2f936352014-08-05 14:04:04 +100010231
10232/*[clinic input]
10233os.strerror
10234
10235 code: int
10236 /
10237
10238Translate an error code to a message string.
10239[clinic start generated code]*/
10240
Larry Hastings2f936352014-08-05 14:04:04 +100010241static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010242os_strerror_impl(PyObject *module, int code)
10243/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010244{
10245 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 if (message == NULL) {
10247 PyErr_SetString(PyExc_ValueError,
10248 "strerror() argument out of range");
10249 return NULL;
10250 }
Victor Stinner1b579672011-12-17 05:47:23 +010010251 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010252}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010253
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010254
Guido van Rossumc9641791998-08-04 15:26:23 +000010255#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010256#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010257/*[clinic input]
10258os.WCOREDUMP -> bool
10259
10260 status: int
10261 /
10262
10263Return True if the process returning status was dumped to a core file.
10264[clinic start generated code]*/
10265
Larry Hastings2f936352014-08-05 14:04:04 +100010266static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010267os_WCOREDUMP_impl(PyObject *module, int status)
10268/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010269{
10270 WAIT_TYPE wait_status;
10271 WAIT_STATUS_INT(wait_status) = status;
10272 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010273}
10274#endif /* WCOREDUMP */
10275
Larry Hastings2f936352014-08-05 14:04:04 +100010276
Fred Drake106c1a02002-04-23 15:58:02 +000010277#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010278/*[clinic input]
10279os.WIFCONTINUED -> bool
10280
10281 status: int
10282
10283Return True if a particular process was continued from a job control stop.
10284
10285Return True if the process returning status was continued from a
10286job control stop.
10287[clinic start generated code]*/
10288
Larry Hastings2f936352014-08-05 14:04:04 +100010289static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010290os_WIFCONTINUED_impl(PyObject *module, int status)
10291/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010292{
10293 WAIT_TYPE wait_status;
10294 WAIT_STATUS_INT(wait_status) = status;
10295 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010296}
10297#endif /* WIFCONTINUED */
10298
Larry Hastings2f936352014-08-05 14:04:04 +100010299
Guido van Rossumc9641791998-08-04 15:26:23 +000010300#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010301/*[clinic input]
10302os.WIFSTOPPED -> bool
10303
10304 status: int
10305
10306Return True if the process returning status was stopped.
10307[clinic start generated code]*/
10308
Larry Hastings2f936352014-08-05 14:04:04 +100010309static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010310os_WIFSTOPPED_impl(PyObject *module, int status)
10311/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010312{
10313 WAIT_TYPE wait_status;
10314 WAIT_STATUS_INT(wait_status) = status;
10315 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010316}
10317#endif /* WIFSTOPPED */
10318
Larry Hastings2f936352014-08-05 14:04:04 +100010319
Guido van Rossumc9641791998-08-04 15:26:23 +000010320#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010321/*[clinic input]
10322os.WIFSIGNALED -> bool
10323
10324 status: int
10325
10326Return True if the process returning status was terminated by a signal.
10327[clinic start generated code]*/
10328
Larry Hastings2f936352014-08-05 14:04:04 +100010329static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010330os_WIFSIGNALED_impl(PyObject *module, int status)
10331/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010332{
10333 WAIT_TYPE wait_status;
10334 WAIT_STATUS_INT(wait_status) = status;
10335 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010336}
10337#endif /* WIFSIGNALED */
10338
Larry Hastings2f936352014-08-05 14:04:04 +100010339
Guido van Rossumc9641791998-08-04 15:26:23 +000010340#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010341/*[clinic input]
10342os.WIFEXITED -> bool
10343
10344 status: int
10345
10346Return True if the process returning status exited via the exit() system call.
10347[clinic start generated code]*/
10348
Larry Hastings2f936352014-08-05 14:04:04 +100010349static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010350os_WIFEXITED_impl(PyObject *module, int status)
10351/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010352{
10353 WAIT_TYPE wait_status;
10354 WAIT_STATUS_INT(wait_status) = status;
10355 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010356}
10357#endif /* WIFEXITED */
10358
Larry Hastings2f936352014-08-05 14:04:04 +100010359
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010360#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010361/*[clinic input]
10362os.WEXITSTATUS -> int
10363
10364 status: int
10365
10366Return the process return code from status.
10367[clinic start generated code]*/
10368
Larry Hastings2f936352014-08-05 14:04:04 +100010369static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010370os_WEXITSTATUS_impl(PyObject *module, int status)
10371/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010372{
10373 WAIT_TYPE wait_status;
10374 WAIT_STATUS_INT(wait_status) = status;
10375 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010376}
10377#endif /* WEXITSTATUS */
10378
Larry Hastings2f936352014-08-05 14:04:04 +100010379
Guido van Rossumc9641791998-08-04 15:26:23 +000010380#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010381/*[clinic input]
10382os.WTERMSIG -> int
10383
10384 status: int
10385
10386Return the signal that terminated the process that provided the status value.
10387[clinic start generated code]*/
10388
Larry Hastings2f936352014-08-05 14:04:04 +100010389static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010390os_WTERMSIG_impl(PyObject *module, int status)
10391/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010392{
10393 WAIT_TYPE wait_status;
10394 WAIT_STATUS_INT(wait_status) = status;
10395 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010396}
10397#endif /* WTERMSIG */
10398
Larry Hastings2f936352014-08-05 14:04:04 +100010399
Guido van Rossumc9641791998-08-04 15:26:23 +000010400#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010401/*[clinic input]
10402os.WSTOPSIG -> int
10403
10404 status: int
10405
10406Return the signal that stopped the process that provided the status value.
10407[clinic start generated code]*/
10408
Larry Hastings2f936352014-08-05 14:04:04 +100010409static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010410os_WSTOPSIG_impl(PyObject *module, int status)
10411/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010412{
10413 WAIT_TYPE wait_status;
10414 WAIT_STATUS_INT(wait_status) = status;
10415 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010416}
10417#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010418#endif /* HAVE_SYS_WAIT_H */
10419
10420
Thomas Wouters477c8d52006-05-27 19:21:47 +000010421#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010422#ifdef _SCO_DS
10423/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10424 needed definitions in sys/statvfs.h */
10425#define _SVID3
10426#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010427#include <sys/statvfs.h>
10428
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010429static PyObject*
10430_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondob3966632019-11-05 07:16:14 -080010431 PyObject *StatVFSResultType = _posixstate_global->StatVFSResultType;
10432 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010433 if (v == NULL)
10434 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010435
10436#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10438 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10439 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10440 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10441 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10442 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10443 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10444 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10445 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10446 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010447#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10449 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10450 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010451 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010453 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010455 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010456 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010457 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010459 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010461 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010462 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10463 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010464#endif
Michael Felt502d5512018-01-05 13:01:58 +010010465/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10466 * (issue #32390). */
10467#if defined(_AIX) && defined(_ALL_SOURCE)
10468 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10469#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010470 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010471#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010472 if (PyErr_Occurred()) {
10473 Py_DECREF(v);
10474 return NULL;
10475 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010476
Victor Stinner8c62be82010-05-06 00:08:46 +000010477 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010478}
10479
Larry Hastings2f936352014-08-05 14:04:04 +100010480
10481/*[clinic input]
10482os.fstatvfs
10483 fd: int
10484 /
10485
10486Perform an fstatvfs system call on the given fd.
10487
10488Equivalent to statvfs(fd).
10489[clinic start generated code]*/
10490
Larry Hastings2f936352014-08-05 14:04:04 +100010491static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010492os_fstatvfs_impl(PyObject *module, int fd)
10493/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010494{
10495 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010496 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010498
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010499 do {
10500 Py_BEGIN_ALLOW_THREADS
10501 result = fstatvfs(fd, &st);
10502 Py_END_ALLOW_THREADS
10503 } while (result != 0 && errno == EINTR &&
10504 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010505 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010506 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010507
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010509}
Larry Hastings2f936352014-08-05 14:04:04 +100010510#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010511
10512
Thomas Wouters477c8d52006-05-27 19:21:47 +000010513#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010514#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010515/*[clinic input]
10516os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010517
Larry Hastings2f936352014-08-05 14:04:04 +100010518 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10519
10520Perform a statvfs system call on the given path.
10521
10522path may always be specified as a string.
10523On some platforms, path may also be specified as an open file descriptor.
10524 If this functionality is unavailable, using it raises an exception.
10525[clinic start generated code]*/
10526
Larry Hastings2f936352014-08-05 14:04:04 +100010527static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010528os_statvfs_impl(PyObject *module, path_t *path)
10529/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010530{
10531 int result;
10532 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010533
10534 Py_BEGIN_ALLOW_THREADS
10535#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010536 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010537#ifdef __APPLE__
10538 /* handle weak-linking on Mac OS X 10.3 */
10539 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010540 fd_specified("statvfs", path->fd);
10541 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010542 }
10543#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010544 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010545 }
10546 else
10547#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010548 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010549 Py_END_ALLOW_THREADS
10550
10551 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010552 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010553 }
10554
Larry Hastings2f936352014-08-05 14:04:04 +100010555 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010556}
Larry Hastings2f936352014-08-05 14:04:04 +100010557#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10558
Guido van Rossum94f6f721999-01-06 18:42:14 +000010559
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010560#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010561/*[clinic input]
10562os._getdiskusage
10563
Steve Dower23ad6d02018-02-22 10:39:10 -080010564 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010565
10566Return disk usage statistics about the given path as a (total, free) tuple.
10567[clinic start generated code]*/
10568
Larry Hastings2f936352014-08-05 14:04:04 +100010569static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010570os__getdiskusage_impl(PyObject *module, path_t *path)
10571/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010572{
10573 BOOL retval;
10574 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010575 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010576
10577 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010578 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010579 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010580 if (retval == 0) {
10581 if (GetLastError() == ERROR_DIRECTORY) {
10582 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010583
Joe Pamerc8c02492018-09-25 10:57:36 -040010584 dir_path = PyMem_New(wchar_t, path->length + 1);
10585 if (dir_path == NULL) {
10586 return PyErr_NoMemory();
10587 }
10588
10589 wcscpy_s(dir_path, path->length + 1, path->wide);
10590
10591 if (_dirnameW(dir_path) != -1) {
10592 Py_BEGIN_ALLOW_THREADS
10593 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10594 Py_END_ALLOW_THREADS
10595 }
10596 /* Record the last error in case it's modified by PyMem_Free. */
10597 err = GetLastError();
10598 PyMem_Free(dir_path);
10599 if (retval) {
10600 goto success;
10601 }
10602 }
10603 return PyErr_SetFromWindowsErr(err);
10604 }
10605
10606success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010607 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10608}
Larry Hastings2f936352014-08-05 14:04:04 +100010609#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010610
10611
Fred Drakec9680921999-12-13 16:37:25 +000010612/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10613 * It maps strings representing configuration variable names to
10614 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010615 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010616 * rarely-used constants. There are three separate tables that use
10617 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010618 *
10619 * This code is always included, even if none of the interfaces that
10620 * need it are included. The #if hackery needed to avoid it would be
10621 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010622 */
10623struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010624 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010625 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010626};
10627
Fred Drake12c6e2d1999-12-14 21:25:03 +000010628static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010629conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010630 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010631{
Christian Heimes217cfd12007-12-02 14:31:20 +000010632 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010633 int value = _PyLong_AsInt(arg);
10634 if (value == -1 && PyErr_Occurred())
10635 return 0;
10636 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010637 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010638 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010639 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010640 /* look up the value in the table using a binary search */
10641 size_t lo = 0;
10642 size_t mid;
10643 size_t hi = tablesize;
10644 int cmp;
10645 const char *confname;
10646 if (!PyUnicode_Check(arg)) {
10647 PyErr_SetString(PyExc_TypeError,
10648 "configuration names must be strings or integers");
10649 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010650 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010651 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010652 if (confname == NULL)
10653 return 0;
10654 while (lo < hi) {
10655 mid = (lo + hi) / 2;
10656 cmp = strcmp(confname, table[mid].name);
10657 if (cmp < 0)
10658 hi = mid;
10659 else if (cmp > 0)
10660 lo = mid + 1;
10661 else {
10662 *valuep = table[mid].value;
10663 return 1;
10664 }
10665 }
10666 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10667 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010668 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010669}
10670
10671
10672#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10673static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010674#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010676#endif
10677#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010679#endif
Fred Drakec9680921999-12-13 16:37:25 +000010680#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010682#endif
10683#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010685#endif
10686#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010688#endif
10689#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010691#endif
10692#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010694#endif
10695#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010697#endif
10698#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010700#endif
10701#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010703#endif
10704#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010706#endif
10707#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010709#endif
10710#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010712#endif
10713#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010715#endif
10716#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010718#endif
10719#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010721#endif
10722#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010724#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010725#ifdef _PC_ACL_ENABLED
10726 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10727#endif
10728#ifdef _PC_MIN_HOLE_SIZE
10729 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10730#endif
10731#ifdef _PC_ALLOC_SIZE_MIN
10732 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10733#endif
10734#ifdef _PC_REC_INCR_XFER_SIZE
10735 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10736#endif
10737#ifdef _PC_REC_MAX_XFER_SIZE
10738 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10739#endif
10740#ifdef _PC_REC_MIN_XFER_SIZE
10741 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10742#endif
10743#ifdef _PC_REC_XFER_ALIGN
10744 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10745#endif
10746#ifdef _PC_SYMLINK_MAX
10747 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10748#endif
10749#ifdef _PC_XATTR_ENABLED
10750 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10751#endif
10752#ifdef _PC_XATTR_EXISTS
10753 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10754#endif
10755#ifdef _PC_TIMESTAMP_RESOLUTION
10756 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10757#endif
Fred Drakec9680921999-12-13 16:37:25 +000010758};
10759
Fred Drakec9680921999-12-13 16:37:25 +000010760static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010761conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010762{
10763 return conv_confname(arg, valuep, posix_constants_pathconf,
10764 sizeof(posix_constants_pathconf)
10765 / sizeof(struct constdef));
10766}
10767#endif
10768
Larry Hastings2f936352014-08-05 14:04:04 +100010769
Fred Drakec9680921999-12-13 16:37:25 +000010770#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010771/*[clinic input]
10772os.fpathconf -> long
10773
10774 fd: int
10775 name: path_confname
10776 /
10777
10778Return the configuration limit name for the file descriptor fd.
10779
10780If there is no limit, return -1.
10781[clinic start generated code]*/
10782
Larry Hastings2f936352014-08-05 14:04:04 +100010783static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010784os_fpathconf_impl(PyObject *module, int fd, int name)
10785/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010786{
10787 long limit;
10788
10789 errno = 0;
10790 limit = fpathconf(fd, name);
10791 if (limit == -1 && errno != 0)
10792 posix_error();
10793
10794 return limit;
10795}
10796#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010797
10798
10799#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010800/*[clinic input]
10801os.pathconf -> long
10802 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10803 name: path_confname
10804
10805Return the configuration limit name for the file or directory path.
10806
10807If there is no limit, return -1.
10808On some platforms, path may also be specified as an open file descriptor.
10809 If this functionality is unavailable, using it raises an exception.
10810[clinic start generated code]*/
10811
Larry Hastings2f936352014-08-05 14:04:04 +100010812static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010813os_pathconf_impl(PyObject *module, path_t *path, int name)
10814/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010815{
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010817
Victor Stinner8c62be82010-05-06 00:08:46 +000010818 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010819#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010820 if (path->fd != -1)
10821 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010822 else
10823#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010824 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010825 if (limit == -1 && errno != 0) {
10826 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010827 /* could be a path or name problem */
10828 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010829 else
Larry Hastings2f936352014-08-05 14:04:04 +100010830 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010831 }
Larry Hastings2f936352014-08-05 14:04:04 +100010832
10833 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010834}
Larry Hastings2f936352014-08-05 14:04:04 +100010835#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010836
10837#ifdef HAVE_CONFSTR
10838static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010839#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010840 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010841#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010842#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010843 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010844#endif
10845#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010846 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010847#endif
Fred Draked86ed291999-12-15 15:34:33 +000010848#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010849 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010850#endif
10851#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010853#endif
10854#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010855 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010856#endif
10857#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010858 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010859#endif
Fred Drakec9680921999-12-13 16:37:25 +000010860#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010862#endif
10863#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010864 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010865#endif
10866#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010867 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010868#endif
10869#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010871#endif
10872#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010874#endif
10875#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010877#endif
10878#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010880#endif
10881#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010883#endif
Fred Draked86ed291999-12-15 15:34:33 +000010884#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010886#endif
Fred Drakec9680921999-12-13 16:37:25 +000010887#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010889#endif
Fred Draked86ed291999-12-15 15:34:33 +000010890#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010892#endif
10893#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010895#endif
10896#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010898#endif
10899#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010901#endif
Fred Drakec9680921999-12-13 16:37:25 +000010902#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010904#endif
10905#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010907#endif
10908#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010910#endif
10911#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010912 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010913#endif
10914#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010915 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010916#endif
10917#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010919#endif
10920#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010922#endif
10923#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010925#endif
10926#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010928#endif
10929#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010931#endif
10932#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010934#endif
10935#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010937#endif
10938#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010939 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010940#endif
10941#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010942 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010943#endif
10944#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010945 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010946#endif
10947#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010948 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010949#endif
Fred Draked86ed291999-12-15 15:34:33 +000010950#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010951 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010952#endif
10953#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010954 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010955#endif
10956#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010958#endif
10959#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010960 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010961#endif
10962#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010963 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010964#endif
10965#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010966 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010967#endif
10968#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010969 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010970#endif
10971#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010972 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010973#endif
10974#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010975 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010976#endif
10977#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010978 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010979#endif
10980#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010981 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010982#endif
10983#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010984 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010985#endif
10986#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010988#endif
Fred Drakec9680921999-12-13 16:37:25 +000010989};
10990
10991static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010992conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010993{
10994 return conv_confname(arg, valuep, posix_constants_confstr,
10995 sizeof(posix_constants_confstr)
10996 / sizeof(struct constdef));
10997}
10998
Larry Hastings2f936352014-08-05 14:04:04 +100010999
11000/*[clinic input]
11001os.confstr
11002
11003 name: confstr_confname
11004 /
11005
11006Return a string-valued system configuration variable.
11007[clinic start generated code]*/
11008
Larry Hastings2f936352014-08-05 14:04:04 +100011009static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011010os_confstr_impl(PyObject *module, int name)
11011/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011012{
11013 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011014 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011015 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011016
Victor Stinnercb043522010-09-10 23:49:04 +000011017 errno = 0;
11018 len = confstr(name, buffer, sizeof(buffer));
11019 if (len == 0) {
11020 if (errno) {
11021 posix_error();
11022 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011023 }
11024 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011025 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011026 }
11027 }
Victor Stinnercb043522010-09-10 23:49:04 +000011028
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011029 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011030 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011031 char *buf = PyMem_Malloc(len);
11032 if (buf == NULL)
11033 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011034 len2 = confstr(name, buf, len);
11035 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011036 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011037 PyMem_Free(buf);
11038 }
11039 else
11040 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011041 return result;
11042}
Larry Hastings2f936352014-08-05 14:04:04 +100011043#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011044
11045
11046#ifdef HAVE_SYSCONF
11047static struct constdef posix_constants_sysconf[] = {
11048#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011049 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011050#endif
11051#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011052 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011053#endif
11054#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011055 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011056#endif
11057#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011058 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011059#endif
11060#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011061 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011062#endif
11063#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011065#endif
11066#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011068#endif
11069#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011070 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011071#endif
11072#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011073 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011074#endif
11075#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011076 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011077#endif
Fred Draked86ed291999-12-15 15:34:33 +000011078#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011079 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011080#endif
11081#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011082 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011083#endif
Fred Drakec9680921999-12-13 16:37:25 +000011084#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011086#endif
Fred Drakec9680921999-12-13 16:37:25 +000011087#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011088 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011089#endif
11090#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011091 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011092#endif
11093#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011094 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011095#endif
11096#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011097 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011098#endif
11099#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011100 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011101#endif
Fred Draked86ed291999-12-15 15:34:33 +000011102#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011103 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011104#endif
Fred Drakec9680921999-12-13 16:37:25 +000011105#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011106 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011107#endif
11108#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011110#endif
11111#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011112 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011113#endif
11114#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011115 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011116#endif
11117#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011118 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011119#endif
Fred Draked86ed291999-12-15 15:34:33 +000011120#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011121 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011122#endif
Fred Drakec9680921999-12-13 16:37:25 +000011123#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011124 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011125#endif
11126#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011127 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011128#endif
11129#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011130 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011131#endif
11132#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011133 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011134#endif
11135#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011136 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011137#endif
11138#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011139 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011140#endif
11141#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011142 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011143#endif
11144#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011145 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011146#endif
11147#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011149#endif
11150#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011151 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011152#endif
11153#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011155#endif
11156#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011158#endif
11159#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011161#endif
11162#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011164#endif
11165#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011167#endif
11168#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011170#endif
11171#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011173#endif
11174#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011175 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011176#endif
11177#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011178 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011179#endif
11180#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011181 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011182#endif
11183#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011184 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011185#endif
11186#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011187 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011188#endif
11189#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011190 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011191#endif
Fred Draked86ed291999-12-15 15:34:33 +000011192#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011193 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011194#endif
Fred Drakec9680921999-12-13 16:37:25 +000011195#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011196 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011197#endif
11198#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011199 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011200#endif
11201#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011202 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011203#endif
Fred Draked86ed291999-12-15 15:34:33 +000011204#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011205 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011206#endif
Fred Drakec9680921999-12-13 16:37:25 +000011207#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011208 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011209#endif
Fred Draked86ed291999-12-15 15:34:33 +000011210#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011211 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011212#endif
11213#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011215#endif
Fred Drakec9680921999-12-13 16:37:25 +000011216#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011218#endif
11219#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011221#endif
11222#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011223 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011224#endif
11225#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011227#endif
Fred Draked86ed291999-12-15 15:34:33 +000011228#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011230#endif
Fred Drakec9680921999-12-13 16:37:25 +000011231#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011233#endif
11234#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011235 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011236#endif
11237#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011239#endif
11240#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011242#endif
11243#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011245#endif
11246#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011248#endif
11249#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011250 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011251#endif
Fred Draked86ed291999-12-15 15:34:33 +000011252#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011254#endif
Fred Drakec9680921999-12-13 16:37:25 +000011255#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011257#endif
11258#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011260#endif
Fred Draked86ed291999-12-15 15:34:33 +000011261#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011263#endif
Fred Drakec9680921999-12-13 16:37:25 +000011264#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011266#endif
11267#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011268 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011269#endif
11270#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011272#endif
11273#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011274 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011275#endif
11276#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011278#endif
11279#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011281#endif
11282#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011284#endif
11285#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011287#endif
11288#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011290#endif
Fred Draked86ed291999-12-15 15:34:33 +000011291#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011293#endif
11294#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011295 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011296#endif
Fred Drakec9680921999-12-13 16:37:25 +000011297#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011299#endif
11300#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011302#endif
11303#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011305#endif
11306#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011308#endif
11309#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011311#endif
11312#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011314#endif
11315#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011317#endif
11318#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011320#endif
11321#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011323#endif
11324#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011326#endif
11327#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011328 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011329#endif
11330#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011331 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011332#endif
11333#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011334 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011335#endif
11336#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011338#endif
11339#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011340 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011341#endif
11342#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011343 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011344#endif
11345#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011346 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011347#endif
11348#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011349 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011350#endif
11351#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011352 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011353#endif
11354#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011355 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011356#endif
11357#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011358 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011359#endif
11360#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011361 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011362#endif
11363#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011364 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011365#endif
11366#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011367 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011368#endif
11369#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011370 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011371#endif
11372#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011373 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011374#endif
11375#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011377#endif
11378#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011379 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011380#endif
11381#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011382 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011383#endif
11384#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011386#endif
11387#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011388 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011389#endif
11390#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011392#endif
11393#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011395#endif
11396#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011397 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011398#endif
11399#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011400 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011401#endif
Fred Draked86ed291999-12-15 15:34:33 +000011402#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011403 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011404#endif
Fred Drakec9680921999-12-13 16:37:25 +000011405#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011406 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011407#endif
11408#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011409 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011410#endif
11411#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011412 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011413#endif
11414#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011415 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011416#endif
11417#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011418 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011419#endif
11420#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011421 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011422#endif
11423#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011424 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011425#endif
11426#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011428#endif
11429#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011430 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011431#endif
11432#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011433 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011434#endif
11435#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011436 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011437#endif
11438#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011439 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011440#endif
11441#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011442 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011443#endif
11444#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011445 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011446#endif
11447#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011448 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011449#endif
11450#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011451 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011452#endif
11453#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011455#endif
11456#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011457 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011458#endif
11459#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011460 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011461#endif
11462#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011464#endif
11465#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011466 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011467#endif
11468#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011469 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011470#endif
11471#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011472 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011473#endif
11474#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011475 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011476#endif
11477#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011478 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011479#endif
11480#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011481 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011482#endif
11483#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011484 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011485#endif
11486#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011487 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011488#endif
11489#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011490 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011491#endif
11492#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011493 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011494#endif
11495#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011496 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011497#endif
11498#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011499 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011500#endif
11501#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011502 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011503#endif
11504#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011505 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011506#endif
11507#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011508 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011509#endif
11510#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011511 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011512#endif
11513#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011514 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011515#endif
11516#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011517 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011518#endif
11519#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011520 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011521#endif
11522#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011523 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011524#endif
11525#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011527#endif
11528#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011529 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011530#endif
11531#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011532 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011533#endif
11534#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011535 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011536#endif
11537#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011538 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011539#endif
11540};
11541
11542static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011543conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011544{
11545 return conv_confname(arg, valuep, posix_constants_sysconf,
11546 sizeof(posix_constants_sysconf)
11547 / sizeof(struct constdef));
11548}
11549
Larry Hastings2f936352014-08-05 14:04:04 +100011550
11551/*[clinic input]
11552os.sysconf -> long
11553 name: sysconf_confname
11554 /
11555
11556Return an integer-valued system configuration variable.
11557[clinic start generated code]*/
11558
Larry Hastings2f936352014-08-05 14:04:04 +100011559static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011560os_sysconf_impl(PyObject *module, int name)
11561/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011562{
11563 long value;
11564
11565 errno = 0;
11566 value = sysconf(name);
11567 if (value == -1 && errno != 0)
11568 posix_error();
11569 return value;
11570}
11571#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011572
11573
Fred Drakebec628d1999-12-15 18:31:10 +000011574/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011575 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011576 * the exported dictionaries that are used to publish information about the
11577 * names available on the host platform.
11578 *
11579 * Sorting the table at runtime ensures that the table is properly ordered
11580 * when used, even for platforms we're not able to test on. It also makes
11581 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011582 */
Fred Drakebec628d1999-12-15 18:31:10 +000011583
11584static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011585cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011586{
11587 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011588 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011589 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011590 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011591
11592 return strcmp(c1->name, c2->name);
11593}
11594
11595static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011596setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011597 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011598{
Fred Drakebec628d1999-12-15 18:31:10 +000011599 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011600 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011601
11602 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11603 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011604 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011605 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011606
Barry Warsaw3155db32000-04-13 15:20:40 +000011607 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011608 PyObject *o = PyLong_FromLong(table[i].value);
11609 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11610 Py_XDECREF(o);
11611 Py_DECREF(d);
11612 return -1;
11613 }
11614 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011615 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011616 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011617}
11618
Fred Drakebec628d1999-12-15 18:31:10 +000011619/* Return -1 on failure, 0 on success. */
11620static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011621setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011622{
11623#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011624 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011625 sizeof(posix_constants_pathconf)
11626 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011627 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011628 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011629#endif
11630#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011631 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011632 sizeof(posix_constants_confstr)
11633 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011634 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011635 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011636#endif
11637#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011638 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011639 sizeof(posix_constants_sysconf)
11640 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011641 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011642 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011643#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011644 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011645}
Fred Draked86ed291999-12-15 15:34:33 +000011646
11647
Larry Hastings2f936352014-08-05 14:04:04 +100011648/*[clinic input]
11649os.abort
11650
11651Abort the interpreter immediately.
11652
11653This function 'dumps core' or otherwise fails in the hardest way possible
11654on the hosting operating system. This function never returns.
11655[clinic start generated code]*/
11656
Larry Hastings2f936352014-08-05 14:04:04 +100011657static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011658os_abort_impl(PyObject *module)
11659/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011660{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011661 abort();
11662 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011663#ifndef __clang__
11664 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11665 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11666 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011667 Py_FatalError("abort() called from Python code didn't abort!");
11668 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011669#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011670}
Fred Drakebec628d1999-12-15 18:31:10 +000011671
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011672#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011673/* Grab ShellExecute dynamically from shell32 */
11674static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011675static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11676 LPCWSTR, INT);
11677static int
11678check_ShellExecute()
11679{
11680 HINSTANCE hShell32;
11681
11682 /* only recheck */
11683 if (-1 == has_ShellExecute) {
11684 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011685 /* Security note: this call is not vulnerable to "DLL hijacking".
11686 SHELL32 is part of "KnownDLLs" and so Windows always load
11687 the system SHELL32.DLL, even if there is another SHELL32.DLL
11688 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011689 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011690 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011691 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11692 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011693 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011694 } else {
11695 has_ShellExecute = 0;
11696 }
Tony Roberts4860f012019-02-02 18:16:42 +010011697 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011698 }
11699 return has_ShellExecute;
11700}
11701
11702
Steve Dowercc16be82016-09-08 10:35:16 -070011703/*[clinic input]
11704os.startfile
11705 filepath: path_t
11706 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011707
Steve Dowercc16be82016-09-08 10:35:16 -070011708Start a file with its associated application.
11709
11710When "operation" is not specified or "open", this acts like
11711double-clicking the file in Explorer, or giving the file name as an
11712argument to the DOS "start" command: the file is opened with whatever
11713application (if any) its extension is associated.
11714When another "operation" is given, it specifies what should be done with
11715the file. A typical operation is "print".
11716
11717startfile returns as soon as the associated application is launched.
11718There is no option to wait for the application to close, and no way
11719to retrieve the application's exit status.
11720
11721The filepath is relative to the current directory. If you want to use
11722an absolute path, make sure the first character is not a slash ("/");
11723the underlying Win32 ShellExecute function doesn't work if it is.
11724[clinic start generated code]*/
11725
11726static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011727os_startfile_impl(PyObject *module, path_t *filepath,
11728 const Py_UNICODE *operation)
Serhiy Storchaka279f4462019-09-14 12:24:05 +030011729/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011730{
11731 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011732
11733 if(!check_ShellExecute()) {
11734 /* If the OS doesn't have ShellExecute, return a
11735 NotImplementedError. */
11736 return PyErr_Format(PyExc_NotImplementedError,
11737 "startfile not available on this platform");
11738 }
11739
Victor Stinner8c62be82010-05-06 00:08:46 +000011740 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011741 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011742 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011743 Py_END_ALLOW_THREADS
11744
Victor Stinner8c62be82010-05-06 00:08:46 +000011745 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011746 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011747 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011748 }
Steve Dowercc16be82016-09-08 10:35:16 -070011749 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011750}
Larry Hastings2f936352014-08-05 14:04:04 +100011751#endif /* MS_WINDOWS */
11752
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011753
Martin v. Löwis438b5342002-12-27 10:16:42 +000011754#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011755/*[clinic input]
11756os.getloadavg
11757
11758Return average recent system load information.
11759
11760Return the number of processes in the system run queue averaged over
11761the last 1, 5, and 15 minutes as a tuple of three floats.
11762Raises OSError if the load average was unobtainable.
11763[clinic start generated code]*/
11764
Larry Hastings2f936352014-08-05 14:04:04 +100011765static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011766os_getloadavg_impl(PyObject *module)
11767/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011768{
11769 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011770 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011771 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11772 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011773 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011774 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011775}
Larry Hastings2f936352014-08-05 14:04:04 +100011776#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011777
Larry Hastings2f936352014-08-05 14:04:04 +100011778
11779/*[clinic input]
11780os.device_encoding
11781 fd: int
11782
11783Return a string describing the encoding of a terminal's file descriptor.
11784
11785The file descriptor must be attached to a terminal.
11786If the device is not a terminal, return None.
11787[clinic start generated code]*/
11788
Larry Hastings2f936352014-08-05 14:04:04 +100011789static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011790os_device_encoding_impl(PyObject *module, int fd)
11791/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011792{
Brett Cannonefb00c02012-02-29 18:31:31 -050011793 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011794}
11795
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011796
Larry Hastings2f936352014-08-05 14:04:04 +100011797#ifdef HAVE_SETRESUID
11798/*[clinic input]
11799os.setresuid
11800
11801 ruid: uid_t
11802 euid: uid_t
11803 suid: uid_t
11804 /
11805
11806Set the current process's real, effective, and saved user ids.
11807[clinic start generated code]*/
11808
Larry Hastings2f936352014-08-05 14:04:04 +100011809static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011810os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11811/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011812{
Victor Stinner8c62be82010-05-06 00:08:46 +000011813 if (setresuid(ruid, euid, suid) < 0)
11814 return posix_error();
11815 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011816}
Larry Hastings2f936352014-08-05 14:04:04 +100011817#endif /* HAVE_SETRESUID */
11818
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011819
11820#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011821/*[clinic input]
11822os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011823
Larry Hastings2f936352014-08-05 14:04:04 +100011824 rgid: gid_t
11825 egid: gid_t
11826 sgid: gid_t
11827 /
11828
11829Set the current process's real, effective, and saved group ids.
11830[clinic start generated code]*/
11831
Larry Hastings2f936352014-08-05 14:04:04 +100011832static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011833os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11834/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011835{
Victor Stinner8c62be82010-05-06 00:08:46 +000011836 if (setresgid(rgid, egid, sgid) < 0)
11837 return posix_error();
11838 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011839}
Larry Hastings2f936352014-08-05 14:04:04 +100011840#endif /* HAVE_SETRESGID */
11841
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011842
11843#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011844/*[clinic input]
11845os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011846
Larry Hastings2f936352014-08-05 14:04:04 +100011847Return a tuple of the current process's real, effective, and saved user ids.
11848[clinic start generated code]*/
11849
Larry Hastings2f936352014-08-05 14:04:04 +100011850static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011851os_getresuid_impl(PyObject *module)
11852/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011853{
Victor Stinner8c62be82010-05-06 00:08:46 +000011854 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011855 if (getresuid(&ruid, &euid, &suid) < 0)
11856 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011857 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11858 _PyLong_FromUid(euid),
11859 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011860}
Larry Hastings2f936352014-08-05 14:04:04 +100011861#endif /* HAVE_GETRESUID */
11862
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011863
11864#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011865/*[clinic input]
11866os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011867
Larry Hastings2f936352014-08-05 14:04:04 +100011868Return a tuple of the current process's real, effective, and saved group ids.
11869[clinic start generated code]*/
11870
Larry Hastings2f936352014-08-05 14:04:04 +100011871static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011872os_getresgid_impl(PyObject *module)
11873/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011874{
11875 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011876 if (getresgid(&rgid, &egid, &sgid) < 0)
11877 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011878 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11879 _PyLong_FromGid(egid),
11880 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011881}
Larry Hastings2f936352014-08-05 14:04:04 +100011882#endif /* HAVE_GETRESGID */
11883
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011884
Benjamin Peterson9428d532011-09-14 11:45:52 -040011885#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011886/*[clinic input]
11887os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011888
Larry Hastings2f936352014-08-05 14:04:04 +100011889 path: path_t(allow_fd=True)
11890 attribute: path_t
11891 *
11892 follow_symlinks: bool = True
11893
11894Return the value of extended attribute attribute on path.
11895
BNMetricsb9427072018-11-02 15:20:19 +000011896path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011897If follow_symlinks is False, and the last element of the path is a symbolic
11898 link, getxattr will examine the symbolic link itself instead of the file
11899 the link points to.
11900
11901[clinic start generated code]*/
11902
Larry Hastings2f936352014-08-05 14:04:04 +100011903static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011904os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011905 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011906/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011907{
11908 Py_ssize_t i;
11909 PyObject *buffer = NULL;
11910
11911 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11912 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011913
Larry Hastings9cf065c2012-06-22 16:30:09 -070011914 for (i = 0; ; i++) {
11915 void *ptr;
11916 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011917 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011918 Py_ssize_t buffer_size = buffer_sizes[i];
11919 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011920 path_error(path);
11921 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011922 }
11923 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11924 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011925 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011926 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011927
Larry Hastings9cf065c2012-06-22 16:30:09 -070011928 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011929 if (path->fd >= 0)
11930 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011931 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011932 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011933 else
Larry Hastings2f936352014-08-05 14:04:04 +100011934 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011935 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011936
Larry Hastings9cf065c2012-06-22 16:30:09 -070011937 if (result < 0) {
11938 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011939 if (errno == ERANGE)
11940 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011941 path_error(path);
11942 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011943 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011944
Larry Hastings9cf065c2012-06-22 16:30:09 -070011945 if (result != buffer_size) {
11946 /* Can only shrink. */
11947 _PyBytes_Resize(&buffer, result);
11948 }
11949 break;
11950 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011951
Larry Hastings9cf065c2012-06-22 16:30:09 -070011952 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011953}
11954
Larry Hastings2f936352014-08-05 14:04:04 +100011955
11956/*[clinic input]
11957os.setxattr
11958
11959 path: path_t(allow_fd=True)
11960 attribute: path_t
11961 value: Py_buffer
11962 flags: int = 0
11963 *
11964 follow_symlinks: bool = True
11965
11966Set extended attribute attribute on path to value.
11967
BNMetricsb9427072018-11-02 15:20:19 +000011968path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011969If follow_symlinks is False, and the last element of the path is a symbolic
11970 link, setxattr will modify the symbolic link itself instead of the file
11971 the link points to.
11972
11973[clinic start generated code]*/
11974
Benjamin Peterson799bd802011-08-31 22:15:17 -040011975static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011976os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011977 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011978/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011979{
Larry Hastings2f936352014-08-05 14:04:04 +100011980 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011981
Larry Hastings2f936352014-08-05 14:04:04 +100011982 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011983 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011984
Benjamin Peterson799bd802011-08-31 22:15:17 -040011985 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011986 if (path->fd > -1)
11987 result = fsetxattr(path->fd, attribute->narrow,
11988 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011989 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011990 result = setxattr(path->narrow, attribute->narrow,
11991 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011992 else
Larry Hastings2f936352014-08-05 14:04:04 +100011993 result = lsetxattr(path->narrow, attribute->narrow,
11994 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011995 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011996
Larry Hastings9cf065c2012-06-22 16:30:09 -070011997 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011998 path_error(path);
11999 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012000 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012001
Larry Hastings2f936352014-08-05 14:04:04 +100012002 Py_RETURN_NONE;
12003}
12004
12005
12006/*[clinic input]
12007os.removexattr
12008
12009 path: path_t(allow_fd=True)
12010 attribute: path_t
12011 *
12012 follow_symlinks: bool = True
12013
12014Remove extended attribute attribute on path.
12015
BNMetricsb9427072018-11-02 15:20:19 +000012016path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012017If follow_symlinks is False, and the last element of the path is a symbolic
12018 link, removexattr will modify the symbolic link itself instead of the file
12019 the link points to.
12020
12021[clinic start generated code]*/
12022
Larry Hastings2f936352014-08-05 14:04:04 +100012023static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012024os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012025 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012026/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012027{
12028 ssize_t result;
12029
12030 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12031 return NULL;
12032
12033 Py_BEGIN_ALLOW_THREADS;
12034 if (path->fd > -1)
12035 result = fremovexattr(path->fd, attribute->narrow);
12036 else if (follow_symlinks)
12037 result = removexattr(path->narrow, attribute->narrow);
12038 else
12039 result = lremovexattr(path->narrow, attribute->narrow);
12040 Py_END_ALLOW_THREADS;
12041
12042 if (result) {
12043 return path_error(path);
12044 }
12045
12046 Py_RETURN_NONE;
12047}
12048
12049
12050/*[clinic input]
12051os.listxattr
12052
12053 path: path_t(allow_fd=True, nullable=True) = None
12054 *
12055 follow_symlinks: bool = True
12056
12057Return a list of extended attributes on path.
12058
BNMetricsb9427072018-11-02 15:20:19 +000012059path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012060if path is None, listxattr will examine the current directory.
12061If follow_symlinks is False, and the last element of the path is a symbolic
12062 link, listxattr will examine the symbolic link itself instead of the file
12063 the link points to.
12064[clinic start generated code]*/
12065
Larry Hastings2f936352014-08-05 14:04:04 +100012066static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012067os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012068/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012069{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012070 Py_ssize_t i;
12071 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012072 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012073 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012074
Larry Hastings2f936352014-08-05 14:04:04 +100012075 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012076 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012077
Larry Hastings2f936352014-08-05 14:04:04 +100012078 name = path->narrow ? path->narrow : ".";
12079
Larry Hastings9cf065c2012-06-22 16:30:09 -070012080 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012081 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012082 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012083 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012084 Py_ssize_t buffer_size = buffer_sizes[i];
12085 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012086 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012087 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012088 break;
12089 }
12090 buffer = PyMem_MALLOC(buffer_size);
12091 if (!buffer) {
12092 PyErr_NoMemory();
12093 break;
12094 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012095
Larry Hastings9cf065c2012-06-22 16:30:09 -070012096 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012097 if (path->fd > -1)
12098 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012099 else if (follow_symlinks)
12100 length = listxattr(name, buffer, buffer_size);
12101 else
12102 length = llistxattr(name, buffer, buffer_size);
12103 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012104
Larry Hastings9cf065c2012-06-22 16:30:09 -070012105 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012106 if (errno == ERANGE) {
12107 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012108 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012109 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012110 }
Larry Hastings2f936352014-08-05 14:04:04 +100012111 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012112 break;
12113 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012114
Larry Hastings9cf065c2012-06-22 16:30:09 -070012115 result = PyList_New(0);
12116 if (!result) {
12117 goto exit;
12118 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012119
Larry Hastings9cf065c2012-06-22 16:30:09 -070012120 end = buffer + length;
12121 for (trace = start = buffer; trace != end; trace++) {
12122 if (!*trace) {
12123 int error;
12124 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12125 trace - start);
12126 if (!attribute) {
12127 Py_DECREF(result);
12128 result = NULL;
12129 goto exit;
12130 }
12131 error = PyList_Append(result, attribute);
12132 Py_DECREF(attribute);
12133 if (error) {
12134 Py_DECREF(result);
12135 result = NULL;
12136 goto exit;
12137 }
12138 start = trace + 1;
12139 }
12140 }
12141 break;
12142 }
12143exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012144 if (buffer)
12145 PyMem_FREE(buffer);
12146 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012147}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012148#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012149
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012150
Larry Hastings2f936352014-08-05 14:04:04 +100012151/*[clinic input]
12152os.urandom
12153
12154 size: Py_ssize_t
12155 /
12156
12157Return a bytes object containing random bytes suitable for cryptographic use.
12158[clinic start generated code]*/
12159
Larry Hastings2f936352014-08-05 14:04:04 +100012160static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012161os_urandom_impl(PyObject *module, Py_ssize_t size)
12162/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012163{
12164 PyObject *bytes;
12165 int result;
12166
Georg Brandl2fb477c2012-02-21 00:33:36 +010012167 if (size < 0)
12168 return PyErr_Format(PyExc_ValueError,
12169 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012170 bytes = PyBytes_FromStringAndSize(NULL, size);
12171 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012172 return NULL;
12173
Victor Stinnere66987e2016-09-06 16:33:52 -070012174 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012175 if (result == -1) {
12176 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012177 return NULL;
12178 }
Larry Hastings2f936352014-08-05 14:04:04 +100012179 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012180}
12181
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012182#ifdef HAVE_MEMFD_CREATE
12183/*[clinic input]
12184os.memfd_create
12185
12186 name: FSConverter
12187 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12188
12189[clinic start generated code]*/
12190
12191static PyObject *
12192os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12193/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12194{
12195 int fd;
12196 const char *bytes = PyBytes_AS_STRING(name);
12197 Py_BEGIN_ALLOW_THREADS
12198 fd = memfd_create(bytes, flags);
12199 Py_END_ALLOW_THREADS
12200 if (fd == -1) {
12201 return PyErr_SetFromErrno(PyExc_OSError);
12202 }
12203 return PyLong_FromLong(fd);
12204}
12205#endif
12206
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012207/* Terminal size querying */
12208
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012209PyDoc_STRVAR(TerminalSize_docstring,
12210 "A tuple of (columns, lines) for holding terminal window size");
12211
12212static PyStructSequence_Field TerminalSize_fields[] = {
12213 {"columns", "width of the terminal window in characters"},
12214 {"lines", "height of the terminal window in characters"},
12215 {NULL, NULL}
12216};
12217
12218static PyStructSequence_Desc TerminalSize_desc = {
12219 "os.terminal_size",
12220 TerminalSize_docstring,
12221 TerminalSize_fields,
12222 2,
12223};
12224
12225#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100012226/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012227PyDoc_STRVAR(termsize__doc__,
12228 "Return the size of the terminal window as (columns, lines).\n" \
12229 "\n" \
12230 "The optional argument fd (default standard output) specifies\n" \
12231 "which file descriptor should be queried.\n" \
12232 "\n" \
12233 "If the file descriptor is not connected to a terminal, an OSError\n" \
12234 "is thrown.\n" \
12235 "\n" \
12236 "This function will only be defined if an implementation is\n" \
12237 "available for this system.\n" \
12238 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080012239 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012240 "normally be used, os.get_terminal_size is the low-level implementation.");
12241
12242static PyObject*
12243get_terminal_size(PyObject *self, PyObject *args)
12244{
12245 int columns, lines;
12246 PyObject *termsize;
12247
12248 int fd = fileno(stdout);
12249 /* Under some conditions stdout may not be connected and
12250 * fileno(stdout) may point to an invalid file descriptor. For example
12251 * GUI apps don't have valid standard streams by default.
12252 *
12253 * If this happens, and the optional fd argument is not present,
12254 * the ioctl below will fail returning EBADF. This is what we want.
12255 */
12256
12257 if (!PyArg_ParseTuple(args, "|i", &fd))
12258 return NULL;
12259
12260#ifdef TERMSIZE_USE_IOCTL
12261 {
12262 struct winsize w;
12263 if (ioctl(fd, TIOCGWINSZ, &w))
12264 return PyErr_SetFromErrno(PyExc_OSError);
12265 columns = w.ws_col;
12266 lines = w.ws_row;
12267 }
12268#endif /* TERMSIZE_USE_IOCTL */
12269
12270#ifdef TERMSIZE_USE_CONIO
12271 {
12272 DWORD nhandle;
12273 HANDLE handle;
12274 CONSOLE_SCREEN_BUFFER_INFO csbi;
12275 switch (fd) {
12276 case 0: nhandle = STD_INPUT_HANDLE;
12277 break;
12278 case 1: nhandle = STD_OUTPUT_HANDLE;
12279 break;
12280 case 2: nhandle = STD_ERROR_HANDLE;
12281 break;
12282 default:
12283 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12284 }
12285 handle = GetStdHandle(nhandle);
12286 if (handle == NULL)
12287 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12288 if (handle == INVALID_HANDLE_VALUE)
12289 return PyErr_SetFromWindowsErr(0);
12290
12291 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12292 return PyErr_SetFromWindowsErr(0);
12293
12294 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12295 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12296 }
12297#endif /* TERMSIZE_USE_CONIO */
12298
Eddie Elizondob3966632019-11-05 07:16:14 -080012299 PyObject *TerminalSizeType = _posixstate(self)->TerminalSizeType;
12300 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012301 if (termsize == NULL)
12302 return NULL;
12303 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12304 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12305 if (PyErr_Occurred()) {
12306 Py_DECREF(termsize);
12307 return NULL;
12308 }
12309 return termsize;
12310}
12311#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12312
Larry Hastings2f936352014-08-05 14:04:04 +100012313
12314/*[clinic input]
12315os.cpu_count
12316
Charles-François Natali80d62e62015-08-13 20:37:08 +010012317Return the number of CPUs in the system; return None if indeterminable.
12318
12319This number is not equivalent to the number of CPUs the current process can
12320use. The number of usable CPUs can be obtained with
12321``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012322[clinic start generated code]*/
12323
Larry Hastings2f936352014-08-05 14:04:04 +100012324static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012325os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012326/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012327{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012328 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012329#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010012330 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012331#elif defined(__hpux)
12332 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12333#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12334 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012335#elif defined(__DragonFly__) || \
12336 defined(__OpenBSD__) || \
12337 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012338 defined(__NetBSD__) || \
12339 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012340 int mib[2];
12341 size_t len = sizeof(ncpu);
12342 mib[0] = CTL_HW;
12343 mib[1] = HW_NCPU;
12344 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12345 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012346#endif
12347 if (ncpu >= 1)
12348 return PyLong_FromLong(ncpu);
12349 else
12350 Py_RETURN_NONE;
12351}
12352
Victor Stinnerdaf45552013-08-28 00:53:59 +020012353
Larry Hastings2f936352014-08-05 14:04:04 +100012354/*[clinic input]
12355os.get_inheritable -> bool
12356
12357 fd: int
12358 /
12359
12360Get the close-on-exe flag of the specified file descriptor.
12361[clinic start generated code]*/
12362
Larry Hastings2f936352014-08-05 14:04:04 +100012363static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012364os_get_inheritable_impl(PyObject *module, int fd)
12365/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012366{
Steve Dower8fc89802015-04-12 00:26:27 -040012367 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012368 _Py_BEGIN_SUPPRESS_IPH
12369 return_value = _Py_get_inheritable(fd);
12370 _Py_END_SUPPRESS_IPH
12371 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012372}
12373
12374
12375/*[clinic input]
12376os.set_inheritable
12377 fd: int
12378 inheritable: int
12379 /
12380
12381Set the inheritable flag of the specified file descriptor.
12382[clinic start generated code]*/
12383
Larry Hastings2f936352014-08-05 14:04:04 +100012384static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012385os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12386/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012387{
Steve Dower8fc89802015-04-12 00:26:27 -040012388 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012389
Steve Dower8fc89802015-04-12 00:26:27 -040012390 _Py_BEGIN_SUPPRESS_IPH
12391 result = _Py_set_inheritable(fd, inheritable, NULL);
12392 _Py_END_SUPPRESS_IPH
12393 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012394 return NULL;
12395 Py_RETURN_NONE;
12396}
12397
12398
12399#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012400/*[clinic input]
12401os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012402 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012403 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012404
Larry Hastings2f936352014-08-05 14:04:04 +100012405Get the close-on-exe flag of the specified file descriptor.
12406[clinic start generated code]*/
12407
Larry Hastings2f936352014-08-05 14:04:04 +100012408static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012409os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012410/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012411{
12412 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012413
12414 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12415 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012416 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012417 }
12418
Larry Hastings2f936352014-08-05 14:04:04 +100012419 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012420}
12421
Victor Stinnerdaf45552013-08-28 00:53:59 +020012422
Larry Hastings2f936352014-08-05 14:04:04 +100012423/*[clinic input]
12424os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012425 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012426 inheritable: bool
12427 /
12428
12429Set the inheritable flag of the specified handle.
12430[clinic start generated code]*/
12431
Larry Hastings2f936352014-08-05 14:04:04 +100012432static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012433os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012434 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012435/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012436{
12437 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012438 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12439 PyErr_SetFromWindowsErr(0);
12440 return NULL;
12441 }
12442 Py_RETURN_NONE;
12443}
Larry Hastings2f936352014-08-05 14:04:04 +100012444#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012445
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012446#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012447/*[clinic input]
12448os.get_blocking -> bool
12449 fd: int
12450 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012451
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012452Get the blocking mode of the file descriptor.
12453
12454Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12455[clinic start generated code]*/
12456
12457static int
12458os_get_blocking_impl(PyObject *module, int fd)
12459/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012460{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012461 int blocking;
12462
Steve Dower8fc89802015-04-12 00:26:27 -040012463 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012464 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012465 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012466 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012467}
12468
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012469/*[clinic input]
12470os.set_blocking
12471 fd: int
12472 blocking: bool(accept={int})
12473 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012474
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012475Set the blocking mode of the specified file descriptor.
12476
12477Set the O_NONBLOCK flag if blocking is False,
12478clear the O_NONBLOCK flag otherwise.
12479[clinic start generated code]*/
12480
12481static PyObject *
12482os_set_blocking_impl(PyObject *module, int fd, int blocking)
12483/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012484{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012485 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012486
Steve Dower8fc89802015-04-12 00:26:27 -040012487 _Py_BEGIN_SUPPRESS_IPH
12488 result = _Py_set_blocking(fd, blocking);
12489 _Py_END_SUPPRESS_IPH
12490 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012491 return NULL;
12492 Py_RETURN_NONE;
12493}
12494#endif /* !MS_WINDOWS */
12495
12496
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012497/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080012498class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012499[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080012500/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012501
12502typedef struct {
12503 PyObject_HEAD
12504 PyObject *name;
12505 PyObject *path;
12506 PyObject *stat;
12507 PyObject *lstat;
12508#ifdef MS_WINDOWS
12509 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012510 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012511 int got_file_index;
12512#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012513#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012514 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012515#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012516 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012517 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012518#endif
12519} DirEntry;
12520
Eddie Elizondob3966632019-11-05 07:16:14 -080012521static PyObject *
12522_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
12523{
12524 PyErr_Format(PyExc_TypeError,
12525 "cannot create '%.100s' instances", _PyType_Name(type));
12526 return NULL;
12527}
12528
Victor Stinner6036e442015-03-08 01:58:04 +010012529static void
12530DirEntry_dealloc(DirEntry *entry)
12531{
Eddie Elizondob3966632019-11-05 07:16:14 -080012532 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010012533 Py_XDECREF(entry->name);
12534 Py_XDECREF(entry->path);
12535 Py_XDECREF(entry->stat);
12536 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080012537 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
12538 free_func(entry);
12539 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010012540}
12541
12542/* Forward reference */
12543static int
12544DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12545
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012546/*[clinic input]
12547os.DirEntry.is_symlink -> bool
12548
12549Return True if the entry is a symbolic link; cached per entry.
12550[clinic start generated code]*/
12551
Victor Stinner6036e442015-03-08 01:58:04 +010012552static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012553os_DirEntry_is_symlink_impl(DirEntry *self)
12554/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012555{
12556#ifdef MS_WINDOWS
12557 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012558#elif defined(HAVE_DIRENT_D_TYPE)
12559 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012560 if (self->d_type != DT_UNKNOWN)
12561 return self->d_type == DT_LNK;
12562 else
12563 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012564#else
12565 /* POSIX without d_type */
12566 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012567#endif
12568}
12569
12570static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012571DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12572{
12573 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012574 STRUCT_STAT st;
12575 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012576
12577#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012578 if (!PyUnicode_FSDecoder(self->path, &ub))
12579 return NULL;
12580 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012581#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012582 if (!PyUnicode_FSConverter(self->path, &ub))
12583 return NULL;
12584 const char *path = PyBytes_AS_STRING(ub);
12585 if (self->dir_fd != DEFAULT_DIR_FD) {
12586#ifdef HAVE_FSTATAT
12587 result = fstatat(self->dir_fd, path, &st,
12588 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12589#else
12590 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12591 return NULL;
12592#endif /* HAVE_FSTATAT */
12593 }
12594 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012595#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012596 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012597 if (follow_symlinks)
12598 result = STAT(path, &st);
12599 else
12600 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012601 }
12602 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012603
12604 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012605 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012606
12607 return _pystat_fromstructstat(&st);
12608}
12609
12610static PyObject *
12611DirEntry_get_lstat(DirEntry *self)
12612{
12613 if (!self->lstat) {
12614#ifdef MS_WINDOWS
12615 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12616#else /* POSIX */
12617 self->lstat = DirEntry_fetch_stat(self, 0);
12618#endif
12619 }
12620 Py_XINCREF(self->lstat);
12621 return self->lstat;
12622}
12623
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012624/*[clinic input]
12625os.DirEntry.stat
12626 *
12627 follow_symlinks: bool = True
12628
12629Return stat_result object for the entry; cached per entry.
12630[clinic start generated code]*/
12631
Victor Stinner6036e442015-03-08 01:58:04 +010012632static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012633os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12634/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012635{
12636 if (!follow_symlinks)
12637 return DirEntry_get_lstat(self);
12638
12639 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012640 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012641 if (result == -1)
12642 return NULL;
12643 else if (result)
12644 self->stat = DirEntry_fetch_stat(self, 1);
12645 else
12646 self->stat = DirEntry_get_lstat(self);
12647 }
12648
12649 Py_XINCREF(self->stat);
12650 return self->stat;
12651}
12652
Victor Stinner6036e442015-03-08 01:58:04 +010012653/* Set exception and return -1 on error, 0 for False, 1 for True */
12654static int
12655DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12656{
12657 PyObject *stat = NULL;
12658 PyObject *st_mode = NULL;
12659 long mode;
12660 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012661#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012662 int is_symlink;
12663 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012664#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012665#ifdef MS_WINDOWS
12666 unsigned long dir_bits;
12667#endif
12668
12669#ifdef MS_WINDOWS
12670 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12671 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012672#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012673 is_symlink = self->d_type == DT_LNK;
12674 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12675#endif
12676
Victor Stinner35a97c02015-03-08 02:59:09 +010012677#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012678 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012679#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012680 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012681 if (!stat) {
12682 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12683 /* If file doesn't exist (anymore), then return False
12684 (i.e., say it's not a file/directory) */
12685 PyErr_Clear();
12686 return 0;
12687 }
12688 goto error;
12689 }
Eddie Elizondob3966632019-11-05 07:16:14 -080012690 st_mode = PyObject_GetAttr(stat, _posixstate_global->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012691 if (!st_mode)
12692 goto error;
12693
12694 mode = PyLong_AsLong(st_mode);
12695 if (mode == -1 && PyErr_Occurred())
12696 goto error;
12697 Py_CLEAR(st_mode);
12698 Py_CLEAR(stat);
12699 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012700#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012701 }
12702 else if (is_symlink) {
12703 assert(mode_bits != S_IFLNK);
12704 result = 0;
12705 }
12706 else {
12707 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12708#ifdef MS_WINDOWS
12709 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12710 if (mode_bits == S_IFDIR)
12711 result = dir_bits != 0;
12712 else
12713 result = dir_bits == 0;
12714#else /* POSIX */
12715 if (mode_bits == S_IFDIR)
12716 result = self->d_type == DT_DIR;
12717 else
12718 result = self->d_type == DT_REG;
12719#endif
12720 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012721#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012722
12723 return result;
12724
12725error:
12726 Py_XDECREF(st_mode);
12727 Py_XDECREF(stat);
12728 return -1;
12729}
12730
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012731/*[clinic input]
12732os.DirEntry.is_dir -> bool
12733 *
12734 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012735
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012736Return True if the entry is a directory; cached per entry.
12737[clinic start generated code]*/
12738
12739static int
12740os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12741/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12742{
12743 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012744}
12745
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012746/*[clinic input]
12747os.DirEntry.is_file -> bool
12748 *
12749 follow_symlinks: bool = True
12750
12751Return True if the entry is a file; cached per entry.
12752[clinic start generated code]*/
12753
12754static int
12755os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12756/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012757{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012758 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012759}
12760
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012761/*[clinic input]
12762os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012763
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012764Return inode of the entry; cached per entry.
12765[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012766
12767static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012768os_DirEntry_inode_impl(DirEntry *self)
12769/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012770{
12771#ifdef MS_WINDOWS
12772 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012773 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012774 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012775 STRUCT_STAT stat;
12776 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012777
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012778 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012779 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012780 path = PyUnicode_AsUnicode(unicode);
12781 result = LSTAT(path, &stat);
12782 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012783
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012784 if (result != 0)
12785 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012786
12787 self->win32_file_index = stat.st_ino;
12788 self->got_file_index = 1;
12789 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012790 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12791 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012792#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012793 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12794 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012795#endif
12796}
12797
12798static PyObject *
12799DirEntry_repr(DirEntry *self)
12800{
12801 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12802}
12803
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012804/*[clinic input]
12805os.DirEntry.__fspath__
12806
12807Returns the path for the entry.
12808[clinic start generated code]*/
12809
Brett Cannon96881cd2016-06-10 14:37:21 -070012810static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012811os_DirEntry___fspath___impl(DirEntry *self)
12812/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012813{
12814 Py_INCREF(self->path);
12815 return self->path;
12816}
12817
Victor Stinner6036e442015-03-08 01:58:04 +010012818static PyMemberDef DirEntry_members[] = {
12819 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12820 "the entry's base filename, relative to scandir() \"path\" argument"},
12821 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12822 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12823 {NULL}
12824};
12825
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012826#include "clinic/posixmodule.c.h"
12827
Victor Stinner6036e442015-03-08 01:58:04 +010012828static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012829 OS_DIRENTRY_IS_DIR_METHODDEF
12830 OS_DIRENTRY_IS_FILE_METHODDEF
12831 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12832 OS_DIRENTRY_STAT_METHODDEF
12833 OS_DIRENTRY_INODE_METHODDEF
12834 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012835 {NULL}
12836};
12837
Eddie Elizondob3966632019-11-05 07:16:14 -080012838static PyType_Slot DirEntryType_slots[] = {
12839 {Py_tp_new, _disabled_new},
12840 {Py_tp_dealloc, DirEntry_dealloc},
12841 {Py_tp_repr, DirEntry_repr},
12842 {Py_tp_methods, DirEntry_methods},
12843 {Py_tp_members, DirEntry_members},
12844 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010012845};
12846
Eddie Elizondob3966632019-11-05 07:16:14 -080012847static PyType_Spec DirEntryType_spec = {
12848 MODNAME ".DirEntry",
12849 sizeof(DirEntry),
12850 0,
12851 Py_TPFLAGS_DEFAULT,
12852 DirEntryType_slots
12853};
12854
12855
Victor Stinner6036e442015-03-08 01:58:04 +010012856#ifdef MS_WINDOWS
12857
12858static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012859join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012860{
12861 Py_ssize_t path_len;
12862 Py_ssize_t size;
12863 wchar_t *result;
12864 wchar_t ch;
12865
12866 if (!path_wide) { /* Default arg: "." */
12867 path_wide = L".";
12868 path_len = 1;
12869 }
12870 else {
12871 path_len = wcslen(path_wide);
12872 }
12873
12874 /* The +1's are for the path separator and the NUL */
12875 size = path_len + 1 + wcslen(filename) + 1;
12876 result = PyMem_New(wchar_t, size);
12877 if (!result) {
12878 PyErr_NoMemory();
12879 return NULL;
12880 }
12881 wcscpy(result, path_wide);
12882 if (path_len > 0) {
12883 ch = result[path_len - 1];
12884 if (ch != SEP && ch != ALTSEP && ch != L':')
12885 result[path_len++] = SEP;
12886 wcscpy(result + path_len, filename);
12887 }
12888 return result;
12889}
12890
12891static PyObject *
12892DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12893{
12894 DirEntry *entry;
12895 BY_HANDLE_FILE_INFORMATION file_info;
12896 ULONG reparse_tag;
12897 wchar_t *joined_path;
12898
Eddie Elizondob3966632019-11-05 07:16:14 -080012899 PyObject *DirEntryType = _posixstate_global->DirEntryType;
12900 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010012901 if (!entry)
12902 return NULL;
12903 entry->name = NULL;
12904 entry->path = NULL;
12905 entry->stat = NULL;
12906 entry->lstat = NULL;
12907 entry->got_file_index = 0;
12908
12909 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12910 if (!entry->name)
12911 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012912 if (path->narrow) {
12913 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12914 if (!entry->name)
12915 goto error;
12916 }
Victor Stinner6036e442015-03-08 01:58:04 +010012917
12918 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12919 if (!joined_path)
12920 goto error;
12921
12922 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12923 PyMem_Free(joined_path);
12924 if (!entry->path)
12925 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012926 if (path->narrow) {
12927 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12928 if (!entry->path)
12929 goto error;
12930 }
Victor Stinner6036e442015-03-08 01:58:04 +010012931
Steve Dowercc16be82016-09-08 10:35:16 -070012932 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012933 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12934
12935 return (PyObject *)entry;
12936
12937error:
12938 Py_DECREF(entry);
12939 return NULL;
12940}
12941
12942#else /* POSIX */
12943
12944static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012945join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012946{
12947 Py_ssize_t path_len;
12948 Py_ssize_t size;
12949 char *result;
12950
12951 if (!path_narrow) { /* Default arg: "." */
12952 path_narrow = ".";
12953 path_len = 1;
12954 }
12955 else {
12956 path_len = strlen(path_narrow);
12957 }
12958
12959 if (filename_len == -1)
12960 filename_len = strlen(filename);
12961
12962 /* The +1's are for the path separator and the NUL */
12963 size = path_len + 1 + filename_len + 1;
12964 result = PyMem_New(char, size);
12965 if (!result) {
12966 PyErr_NoMemory();
12967 return NULL;
12968 }
12969 strcpy(result, path_narrow);
12970 if (path_len > 0 && result[path_len - 1] != '/')
12971 result[path_len++] = '/';
12972 strcpy(result + path_len, filename);
12973 return result;
12974}
12975
12976static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012977DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012978 ino_t d_ino
12979#ifdef HAVE_DIRENT_D_TYPE
12980 , unsigned char d_type
12981#endif
12982 )
Victor Stinner6036e442015-03-08 01:58:04 +010012983{
12984 DirEntry *entry;
12985 char *joined_path;
12986
Eddie Elizondob3966632019-11-05 07:16:14 -080012987 PyObject *DirEntryType = _posixstate_global->DirEntryType;
12988 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010012989 if (!entry)
12990 return NULL;
12991 entry->name = NULL;
12992 entry->path = NULL;
12993 entry->stat = NULL;
12994 entry->lstat = NULL;
12995
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012996 if (path->fd != -1) {
12997 entry->dir_fd = path->fd;
12998 joined_path = NULL;
12999 }
13000 else {
13001 entry->dir_fd = DEFAULT_DIR_FD;
13002 joined_path = join_path_filename(path->narrow, name, name_len);
13003 if (!joined_path)
13004 goto error;
13005 }
Victor Stinner6036e442015-03-08 01:58:04 +010013006
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013007 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013008 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013009 if (joined_path)
13010 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013011 }
13012 else {
13013 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013014 if (joined_path)
13015 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013016 }
13017 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013018 if (!entry->name)
13019 goto error;
13020
13021 if (path->fd != -1) {
13022 entry->path = entry->name;
13023 Py_INCREF(entry->path);
13024 }
13025 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013026 goto error;
13027
Victor Stinner35a97c02015-03-08 02:59:09 +010013028#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013029 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013030#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013031 entry->d_ino = d_ino;
13032
13033 return (PyObject *)entry;
13034
13035error:
13036 Py_XDECREF(entry);
13037 return NULL;
13038}
13039
13040#endif
13041
13042
13043typedef struct {
13044 PyObject_HEAD
13045 path_t path;
13046#ifdef MS_WINDOWS
13047 HANDLE handle;
13048 WIN32_FIND_DATAW file_data;
13049 int first_time;
13050#else /* POSIX */
13051 DIR *dirp;
13052#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013053#ifdef HAVE_FDOPENDIR
13054 int fd;
13055#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013056} ScandirIterator;
13057
13058#ifdef MS_WINDOWS
13059
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013060static int
13061ScandirIterator_is_closed(ScandirIterator *iterator)
13062{
13063 return iterator->handle == INVALID_HANDLE_VALUE;
13064}
13065
Victor Stinner6036e442015-03-08 01:58:04 +010013066static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013067ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013068{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013069 HANDLE handle = iterator->handle;
13070
13071 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013072 return;
13073
Victor Stinner6036e442015-03-08 01:58:04 +010013074 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013075 Py_BEGIN_ALLOW_THREADS
13076 FindClose(handle);
13077 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013078}
13079
13080static PyObject *
13081ScandirIterator_iternext(ScandirIterator *iterator)
13082{
13083 WIN32_FIND_DATAW *file_data = &iterator->file_data;
13084 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013085 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013086
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013087 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013088 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013089 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013090
13091 while (1) {
13092 if (!iterator->first_time) {
13093 Py_BEGIN_ALLOW_THREADS
13094 success = FindNextFileW(iterator->handle, file_data);
13095 Py_END_ALLOW_THREADS
13096 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013097 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013098 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013099 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013100 break;
13101 }
13102 }
13103 iterator->first_time = 0;
13104
13105 /* Skip over . and .. */
13106 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013107 wcscmp(file_data->cFileName, L"..") != 0) {
13108 entry = DirEntry_from_find_data(&iterator->path, file_data);
13109 if (!entry)
13110 break;
13111 return entry;
13112 }
Victor Stinner6036e442015-03-08 01:58:04 +010013113
13114 /* Loop till we get a non-dot directory or finish iterating */
13115 }
13116
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013117 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013118 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013119 return NULL;
13120}
13121
13122#else /* POSIX */
13123
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013124static int
13125ScandirIterator_is_closed(ScandirIterator *iterator)
13126{
13127 return !iterator->dirp;
13128}
13129
Victor Stinner6036e442015-03-08 01:58:04 +010013130static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013131ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013132{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013133 DIR *dirp = iterator->dirp;
13134
13135 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013136 return;
13137
Victor Stinner6036e442015-03-08 01:58:04 +010013138 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013139 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013140#ifdef HAVE_FDOPENDIR
13141 if (iterator->path.fd != -1)
13142 rewinddir(dirp);
13143#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013144 closedir(dirp);
13145 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013146 return;
13147}
13148
13149static PyObject *
13150ScandirIterator_iternext(ScandirIterator *iterator)
13151{
13152 struct dirent *direntp;
13153 Py_ssize_t name_len;
13154 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013155 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013156
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013157 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013158 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013159 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013160
13161 while (1) {
13162 errno = 0;
13163 Py_BEGIN_ALLOW_THREADS
13164 direntp = readdir(iterator->dirp);
13165 Py_END_ALLOW_THREADS
13166
13167 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013168 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013169 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013170 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013171 break;
13172 }
13173
13174 /* Skip over . and .. */
13175 name_len = NAMLEN(direntp);
13176 is_dot = direntp->d_name[0] == '.' &&
13177 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
13178 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013179 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010013180 name_len, direntp->d_ino
13181#ifdef HAVE_DIRENT_D_TYPE
13182 , direntp->d_type
13183#endif
13184 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013185 if (!entry)
13186 break;
13187 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013188 }
13189
13190 /* Loop till we get a non-dot directory or finish iterating */
13191 }
13192
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013193 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013194 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013195 return NULL;
13196}
13197
13198#endif
13199
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013200static PyObject *
13201ScandirIterator_close(ScandirIterator *self, PyObject *args)
13202{
13203 ScandirIterator_closedir(self);
13204 Py_RETURN_NONE;
13205}
13206
13207static PyObject *
13208ScandirIterator_enter(PyObject *self, PyObject *args)
13209{
13210 Py_INCREF(self);
13211 return self;
13212}
13213
13214static PyObject *
13215ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13216{
13217 ScandirIterator_closedir(self);
13218 Py_RETURN_NONE;
13219}
13220
Victor Stinner6036e442015-03-08 01:58:04 +010013221static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013222ScandirIterator_finalize(ScandirIterator *iterator)
13223{
13224 PyObject *error_type, *error_value, *error_traceback;
13225
13226 /* Save the current exception, if any. */
13227 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13228
13229 if (!ScandirIterator_is_closed(iterator)) {
13230 ScandirIterator_closedir(iterator);
13231
13232 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13233 "unclosed scandir iterator %R", iterator)) {
13234 /* Spurious errors can appear at shutdown */
13235 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13236 PyErr_WriteUnraisable((PyObject *) iterator);
13237 }
13238 }
13239 }
13240
Victor Stinner7bfa4092016-03-23 00:43:54 +010013241 path_cleanup(&iterator->path);
13242
13243 /* Restore the saved exception. */
13244 PyErr_Restore(error_type, error_value, error_traceback);
13245}
13246
13247static void
Victor Stinner6036e442015-03-08 01:58:04 +010013248ScandirIterator_dealloc(ScandirIterator *iterator)
13249{
Eddie Elizondob3966632019-11-05 07:16:14 -080013250 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010013251 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13252 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013253
Eddie Elizondob3966632019-11-05 07:16:14 -080013254 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13255 free_func(iterator);
13256 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013257}
13258
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013259static PyMethodDef ScandirIterator_methods[] = {
13260 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13261 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13262 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13263 {NULL}
13264};
13265
Eddie Elizondob3966632019-11-05 07:16:14 -080013266static PyType_Slot ScandirIteratorType_slots[] = {
13267 {Py_tp_new, _disabled_new},
13268 {Py_tp_dealloc, ScandirIterator_dealloc},
13269 {Py_tp_finalize, ScandirIterator_finalize},
13270 {Py_tp_iter, PyObject_SelfIter},
13271 {Py_tp_iternext, ScandirIterator_iternext},
13272 {Py_tp_methods, ScandirIterator_methods},
13273 {0, 0},
13274};
13275
13276static PyType_Spec ScandirIteratorType_spec = {
13277 MODNAME ".ScandirIterator",
13278 sizeof(ScandirIterator),
13279 0,
13280 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
13281 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010013282};
13283
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013284/*[clinic input]
13285os.scandir
13286
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013287 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013288
13289Return an iterator of DirEntry objects for given path.
13290
BNMetricsb9427072018-11-02 15:20:19 +000013291path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013292is bytes, the names of yielded DirEntry objects will also be bytes; in
13293all other circumstances they will be str.
13294
13295If path is None, uses the path='.'.
13296[clinic start generated code]*/
13297
Victor Stinner6036e442015-03-08 01:58:04 +010013298static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013299os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013300/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013301{
13302 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013303#ifdef MS_WINDOWS
13304 wchar_t *path_strW;
13305#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013306 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013307#ifdef HAVE_FDOPENDIR
13308 int fd = -1;
13309#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013310#endif
13311
Steve Dower60419a72019-06-24 08:42:54 -070013312 if (PySys_Audit("os.scandir", "O",
13313 path->object ? path->object : Py_None) < 0) {
13314 return NULL;
13315 }
13316
Eddie Elizondob3966632019-11-05 07:16:14 -080013317 PyObject *ScandirIteratorType = _posixstate(module)->ScandirIteratorType;
13318 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010013319 if (!iterator)
13320 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013321
13322#ifdef MS_WINDOWS
13323 iterator->handle = INVALID_HANDLE_VALUE;
13324#else
13325 iterator->dirp = NULL;
13326#endif
13327
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013328 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013329 /* Move the ownership to iterator->path */
13330 path->object = NULL;
13331 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013332
13333#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013334 iterator->first_time = 1;
13335
13336 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13337 if (!path_strW)
13338 goto error;
13339
13340 Py_BEGIN_ALLOW_THREADS
13341 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13342 Py_END_ALLOW_THREADS
13343
13344 PyMem_Free(path_strW);
13345
13346 if (iterator->handle == INVALID_HANDLE_VALUE) {
13347 path_error(&iterator->path);
13348 goto error;
13349 }
13350#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013351 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013352#ifdef HAVE_FDOPENDIR
13353 if (path->fd != -1) {
13354 /* closedir() closes the FD, so we duplicate it */
13355 fd = _Py_dup(path->fd);
13356 if (fd == -1)
13357 goto error;
13358
13359 Py_BEGIN_ALLOW_THREADS
13360 iterator->dirp = fdopendir(fd);
13361 Py_END_ALLOW_THREADS
13362 }
13363 else
13364#endif
13365 {
13366 if (iterator->path.narrow)
13367 path_str = iterator->path.narrow;
13368 else
13369 path_str = ".";
13370
13371 Py_BEGIN_ALLOW_THREADS
13372 iterator->dirp = opendir(path_str);
13373 Py_END_ALLOW_THREADS
13374 }
Victor Stinner6036e442015-03-08 01:58:04 +010013375
13376 if (!iterator->dirp) {
13377 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013378#ifdef HAVE_FDOPENDIR
13379 if (fd != -1) {
13380 Py_BEGIN_ALLOW_THREADS
13381 close(fd);
13382 Py_END_ALLOW_THREADS
13383 }
13384#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013385 goto error;
13386 }
13387#endif
13388
13389 return (PyObject *)iterator;
13390
13391error:
13392 Py_DECREF(iterator);
13393 return NULL;
13394}
13395
Ethan Furman410ef8e2016-06-04 12:06:26 -070013396/*
13397 Return the file system path representation of the object.
13398
13399 If the object is str or bytes, then allow it to pass through with
13400 an incremented refcount. If the object defines __fspath__(), then
13401 return the result of that method. All other types raise a TypeError.
13402*/
13403PyObject *
13404PyOS_FSPath(PyObject *path)
13405{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013406 /* For error message reasons, this function is manually inlined in
13407 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013408 PyObject *func = NULL;
13409 PyObject *path_repr = NULL;
13410
13411 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13412 Py_INCREF(path);
13413 return path;
13414 }
13415
13416 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13417 if (NULL == func) {
13418 return PyErr_Format(PyExc_TypeError,
13419 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013420 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080013421 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070013422 }
13423
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013424 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013425 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013426 if (NULL == path_repr) {
13427 return NULL;
13428 }
13429
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013430 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13431 PyErr_Format(PyExc_TypeError,
13432 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080013433 "not %.200s", _PyType_Name(Py_TYPE(path)),
13434 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013435 Py_DECREF(path_repr);
13436 return NULL;
13437 }
13438
Ethan Furman410ef8e2016-06-04 12:06:26 -070013439 return path_repr;
13440}
13441
13442/*[clinic input]
13443os.fspath
13444
13445 path: object
13446
13447Return the file system path representation of the object.
13448
Brett Cannonb4f43e92016-06-09 14:32:08 -070013449If the object is str or bytes, then allow it to pass through as-is. If the
13450object defines __fspath__(), then return the result of that method. All other
13451types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013452[clinic start generated code]*/
13453
13454static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013455os_fspath_impl(PyObject *module, PyObject *path)
13456/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013457{
13458 return PyOS_FSPath(path);
13459}
Victor Stinner6036e442015-03-08 01:58:04 +010013460
Victor Stinner9b1f4742016-09-06 16:18:52 -070013461#ifdef HAVE_GETRANDOM_SYSCALL
13462/*[clinic input]
13463os.getrandom
13464
13465 size: Py_ssize_t
13466 flags: int=0
13467
13468Obtain a series of random bytes.
13469[clinic start generated code]*/
13470
13471static PyObject *
13472os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13473/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13474{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013475 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013476 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013477
13478 if (size < 0) {
13479 errno = EINVAL;
13480 return posix_error();
13481 }
13482
Victor Stinnerec2319c2016-09-20 23:00:59 +020013483 bytes = PyBytes_FromStringAndSize(NULL, size);
13484 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013485 PyErr_NoMemory();
13486 return NULL;
13487 }
13488
13489 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013490 n = syscall(SYS_getrandom,
13491 PyBytes_AS_STRING(bytes),
13492 PyBytes_GET_SIZE(bytes),
13493 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013494 if (n < 0 && errno == EINTR) {
13495 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013496 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013497 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013498
13499 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013500 continue;
13501 }
13502 break;
13503 }
13504
13505 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013506 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013507 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013508 }
13509
Victor Stinnerec2319c2016-09-20 23:00:59 +020013510 if (n != size) {
13511 _PyBytes_Resize(&bytes, n);
13512 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013513
13514 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013515
13516error:
13517 Py_DECREF(bytes);
13518 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013519}
13520#endif /* HAVE_GETRANDOM_SYSCALL */
13521
Steve Dower2438cdf2019-03-29 16:37:16 -070013522#ifdef MS_WINDOWS
13523/* bpo-36085: Helper functions for managing DLL search directories
13524 * on win32
13525 */
13526
13527typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13528typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13529
13530/*[clinic input]
13531os._add_dll_directory
13532
13533 path: path_t
13534
13535Add a path to the DLL search path.
13536
13537This search path is used when resolving dependencies for imported
13538extension modules (the module itself is resolved through sys.path),
13539and also by ctypes.
13540
13541Returns an opaque value that may be passed to os.remove_dll_directory
13542to remove this directory from the search path.
13543[clinic start generated code]*/
13544
13545static PyObject *
13546os__add_dll_directory_impl(PyObject *module, path_t *path)
13547/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13548{
13549 HMODULE hKernel32;
13550 PAddDllDirectory AddDllDirectory;
13551 DLL_DIRECTORY_COOKIE cookie = 0;
13552 DWORD err = 0;
13553
13554 /* For Windows 7, we have to load this. As this will be a fairly
13555 infrequent operation, just do it each time. Kernel32 is always
13556 loaded. */
13557 Py_BEGIN_ALLOW_THREADS
13558 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13559 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13560 hKernel32, "AddDllDirectory")) ||
13561 !(cookie = (*AddDllDirectory)(path->wide))) {
13562 err = GetLastError();
13563 }
13564 Py_END_ALLOW_THREADS
13565
13566 if (err) {
13567 return win32_error_object_err("add_dll_directory",
13568 path->object, err);
13569 }
13570
13571 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13572}
13573
13574/*[clinic input]
13575os._remove_dll_directory
13576
13577 cookie: object
13578
13579Removes a path from the DLL search path.
13580
13581The parameter is an opaque value that was returned from
13582os.add_dll_directory. You can only remove directories that you added
13583yourself.
13584[clinic start generated code]*/
13585
13586static PyObject *
13587os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13588/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13589{
13590 HMODULE hKernel32;
13591 PRemoveDllDirectory RemoveDllDirectory;
13592 DLL_DIRECTORY_COOKIE cookieValue;
13593 DWORD err = 0;
13594
13595 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13596 PyErr_SetString(PyExc_TypeError,
13597 "Provided cookie was not returned from os.add_dll_directory");
13598 return NULL;
13599 }
13600
13601 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13602 cookie, "DLL directory cookie");
13603
13604 /* For Windows 7, we have to load this. As this will be a fairly
13605 infrequent operation, just do it each time. Kernel32 is always
13606 loaded. */
13607 Py_BEGIN_ALLOW_THREADS
13608 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13609 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13610 hKernel32, "RemoveDllDirectory")) ||
13611 !(*RemoveDllDirectory)(cookieValue)) {
13612 err = GetLastError();
13613 }
13614 Py_END_ALLOW_THREADS
13615
13616 if (err) {
13617 return win32_error_object_err("remove_dll_directory",
13618 NULL, err);
13619 }
13620
13621 if (PyCapsule_SetName(cookie, NULL)) {
13622 return NULL;
13623 }
13624
13625 Py_RETURN_NONE;
13626}
13627
13628#endif
Larry Hastings31826802013-10-19 00:09:25 -070013629
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013630static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013631
13632 OS_STAT_METHODDEF
13633 OS_ACCESS_METHODDEF
13634 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013635 OS_CHDIR_METHODDEF
13636 OS_CHFLAGS_METHODDEF
13637 OS_CHMOD_METHODDEF
13638 OS_FCHMOD_METHODDEF
13639 OS_LCHMOD_METHODDEF
13640 OS_CHOWN_METHODDEF
13641 OS_FCHOWN_METHODDEF
13642 OS_LCHOWN_METHODDEF
13643 OS_LCHFLAGS_METHODDEF
13644 OS_CHROOT_METHODDEF
13645 OS_CTERMID_METHODDEF
13646 OS_GETCWD_METHODDEF
13647 OS_GETCWDB_METHODDEF
13648 OS_LINK_METHODDEF
13649 OS_LISTDIR_METHODDEF
13650 OS_LSTAT_METHODDEF
13651 OS_MKDIR_METHODDEF
13652 OS_NICE_METHODDEF
13653 OS_GETPRIORITY_METHODDEF
13654 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013655 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013656 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013657 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010013658 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013659 OS_RENAME_METHODDEF
13660 OS_REPLACE_METHODDEF
13661 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013662 OS_SYMLINK_METHODDEF
13663 OS_SYSTEM_METHODDEF
13664 OS_UMASK_METHODDEF
13665 OS_UNAME_METHODDEF
13666 OS_UNLINK_METHODDEF
13667 OS_REMOVE_METHODDEF
13668 OS_UTIME_METHODDEF
13669 OS_TIMES_METHODDEF
13670 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013671 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013672 OS_EXECV_METHODDEF
13673 OS_EXECVE_METHODDEF
13674 OS_SPAWNV_METHODDEF
13675 OS_SPAWNVE_METHODDEF
13676 OS_FORK1_METHODDEF
13677 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013678 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013679 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13680 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13681 OS_SCHED_GETPARAM_METHODDEF
13682 OS_SCHED_GETSCHEDULER_METHODDEF
13683 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13684 OS_SCHED_SETPARAM_METHODDEF
13685 OS_SCHED_SETSCHEDULER_METHODDEF
13686 OS_SCHED_YIELD_METHODDEF
13687 OS_SCHED_SETAFFINITY_METHODDEF
13688 OS_SCHED_GETAFFINITY_METHODDEF
13689 OS_OPENPTY_METHODDEF
13690 OS_FORKPTY_METHODDEF
13691 OS_GETEGID_METHODDEF
13692 OS_GETEUID_METHODDEF
13693 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013694#ifdef HAVE_GETGROUPLIST
13695 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13696#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013697 OS_GETGROUPS_METHODDEF
13698 OS_GETPID_METHODDEF
13699 OS_GETPGRP_METHODDEF
13700 OS_GETPPID_METHODDEF
13701 OS_GETUID_METHODDEF
13702 OS_GETLOGIN_METHODDEF
13703 OS_KILL_METHODDEF
13704 OS_KILLPG_METHODDEF
13705 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013706#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013707 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013708#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013709 OS_SETUID_METHODDEF
13710 OS_SETEUID_METHODDEF
13711 OS_SETREUID_METHODDEF
13712 OS_SETGID_METHODDEF
13713 OS_SETEGID_METHODDEF
13714 OS_SETREGID_METHODDEF
13715 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013716#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013717 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013718#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013719 OS_GETPGID_METHODDEF
13720 OS_SETPGRP_METHODDEF
13721 OS_WAIT_METHODDEF
13722 OS_WAIT3_METHODDEF
13723 OS_WAIT4_METHODDEF
13724 OS_WAITID_METHODDEF
13725 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080013726 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013727 OS_GETSID_METHODDEF
13728 OS_SETSID_METHODDEF
13729 OS_SETPGID_METHODDEF
13730 OS_TCGETPGRP_METHODDEF
13731 OS_TCSETPGRP_METHODDEF
13732 OS_OPEN_METHODDEF
13733 OS_CLOSE_METHODDEF
13734 OS_CLOSERANGE_METHODDEF
13735 OS_DEVICE_ENCODING_METHODDEF
13736 OS_DUP_METHODDEF
13737 OS_DUP2_METHODDEF
13738 OS_LOCKF_METHODDEF
13739 OS_LSEEK_METHODDEF
13740 OS_READ_METHODDEF
13741 OS_READV_METHODDEF
13742 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013743 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013744 OS_WRITE_METHODDEF
13745 OS_WRITEV_METHODDEF
13746 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013747 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013748#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013749 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013750 posix_sendfile__doc__},
13751#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013752 OS_FSTAT_METHODDEF
13753 OS_ISATTY_METHODDEF
13754 OS_PIPE_METHODDEF
13755 OS_PIPE2_METHODDEF
13756 OS_MKFIFO_METHODDEF
13757 OS_MKNOD_METHODDEF
13758 OS_MAJOR_METHODDEF
13759 OS_MINOR_METHODDEF
13760 OS_MAKEDEV_METHODDEF
13761 OS_FTRUNCATE_METHODDEF
13762 OS_TRUNCATE_METHODDEF
13763 OS_POSIX_FALLOCATE_METHODDEF
13764 OS_POSIX_FADVISE_METHODDEF
13765 OS_PUTENV_METHODDEF
13766 OS_UNSETENV_METHODDEF
13767 OS_STRERROR_METHODDEF
13768 OS_FCHDIR_METHODDEF
13769 OS_FSYNC_METHODDEF
13770 OS_SYNC_METHODDEF
13771 OS_FDATASYNC_METHODDEF
13772 OS_WCOREDUMP_METHODDEF
13773 OS_WIFCONTINUED_METHODDEF
13774 OS_WIFSTOPPED_METHODDEF
13775 OS_WIFSIGNALED_METHODDEF
13776 OS_WIFEXITED_METHODDEF
13777 OS_WEXITSTATUS_METHODDEF
13778 OS_WTERMSIG_METHODDEF
13779 OS_WSTOPSIG_METHODDEF
13780 OS_FSTATVFS_METHODDEF
13781 OS_STATVFS_METHODDEF
13782 OS_CONFSTR_METHODDEF
13783 OS_SYSCONF_METHODDEF
13784 OS_FPATHCONF_METHODDEF
13785 OS_PATHCONF_METHODDEF
13786 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013787 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013788 OS__GETDISKUSAGE_METHODDEF
13789 OS__GETFINALPATHNAME_METHODDEF
13790 OS__GETVOLUMEPATHNAME_METHODDEF
13791 OS_GETLOADAVG_METHODDEF
13792 OS_URANDOM_METHODDEF
13793 OS_SETRESUID_METHODDEF
13794 OS_SETRESGID_METHODDEF
13795 OS_GETRESUID_METHODDEF
13796 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013797
Larry Hastings2f936352014-08-05 14:04:04 +100013798 OS_GETXATTR_METHODDEF
13799 OS_SETXATTR_METHODDEF
13800 OS_REMOVEXATTR_METHODDEF
13801 OS_LISTXATTR_METHODDEF
13802
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013803#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13804 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13805#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013806 OS_CPU_COUNT_METHODDEF
13807 OS_GET_INHERITABLE_METHODDEF
13808 OS_SET_INHERITABLE_METHODDEF
13809 OS_GET_HANDLE_INHERITABLE_METHODDEF
13810 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013811#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013812 OS_GET_BLOCKING_METHODDEF
13813 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013814#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013815 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013816 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013817 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060013818 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070013819#ifdef MS_WINDOWS
13820 OS__ADD_DLL_DIRECTORY_METHODDEF
13821 OS__REMOVE_DLL_DIRECTORY_METHODDEF
13822#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013823 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013824};
13825
Barry Warsaw4a342091996-12-19 23:50:02 +000013826static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013827all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013828{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013829#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013830 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013831#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013832#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013833 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013834#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013835#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013836 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013837#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013838#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013839 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013840#endif
Fred Drakec9680921999-12-13 16:37:25 +000013841#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013842 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013843#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013844#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013845 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013846#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013847#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013848 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013849#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013850#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013851 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013852#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013853#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013854 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013855#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013856#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013857 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013858#endif
13859#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013860 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013861#endif
13862#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013863 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013864#endif
13865#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013866 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013867#endif
13868#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013869 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013870#endif
13871#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013872 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013873#endif
13874#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013875 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013876#endif
13877#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013878 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013879#endif
13880#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013881 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013882#endif
13883#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013884 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013885#endif
13886#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013887 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013888#endif
13889#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013890 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013891#endif
13892#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013893 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013894#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013895#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013896 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013897#endif
13898#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013899 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013900#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013901#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013902 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013903#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013904#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013905 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013906#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013907#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013908#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013909 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013910#endif
13911#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013912 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013913#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013914#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013915#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013916 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013917#endif
13918#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013919 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013920#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013921#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013922 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013923#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013924#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013925 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013926#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013927#ifdef O_TMPFILE
13928 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13929#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013930#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013931 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013932#endif
13933#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013934 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013935#endif
13936#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013937 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013938#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013939#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013940 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013941#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013942#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013943 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013944#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013945
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013946
Jesus Cea94363612012-06-22 18:32:07 +020013947#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013948 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013949#endif
13950#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013951 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013952#endif
13953
Tim Peters5aa91602002-01-30 05:46:57 +000013954/* MS Windows */
13955#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013956 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013957 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013958#endif
13959#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013960 /* Optimize for short life (keep in memory). */
13961 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013962 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013963#endif
13964#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013965 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013966 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013967#endif
13968#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013969 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013970 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013971#endif
13972#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013973 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013974 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013975#endif
13976
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013977/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013978#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013979 /* Send a SIGIO signal whenever input or output
13980 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013981 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013982#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013983#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013984 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013985 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013986#endif
13987#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013988 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013989 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013990#endif
13991#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013992 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013993 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013994#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013995#ifdef O_NOLINKS
13996 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013997 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013998#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013999#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014000 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014001 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014002#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000014003
Victor Stinner8c62be82010-05-06 00:08:46 +000014004 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014005#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014006 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014007#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014008#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014009 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014010#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014011#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014012 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014013#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014014#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014015 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014016#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014017#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014018 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014019#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014020#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014021 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014022#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014023#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014024 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014025#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014026#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014027 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014028#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014029#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014030 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014031#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014032#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014033 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014034#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014035#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014036 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014037#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014038#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014039 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014040#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014041#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014042 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014043#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014044#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014045 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014046#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014047#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014048 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014049#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014050#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014051 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014052#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014053#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014054 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014055#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014056
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000014057 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014058#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014059 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014060#endif /* ST_RDONLY */
14061#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014062 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014063#endif /* ST_NOSUID */
14064
doko@ubuntu.comca616a22013-12-08 15:23:07 +010014065 /* GNU extensions */
14066#ifdef ST_NODEV
14067 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
14068#endif /* ST_NODEV */
14069#ifdef ST_NOEXEC
14070 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
14071#endif /* ST_NOEXEC */
14072#ifdef ST_SYNCHRONOUS
14073 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
14074#endif /* ST_SYNCHRONOUS */
14075#ifdef ST_MANDLOCK
14076 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
14077#endif /* ST_MANDLOCK */
14078#ifdef ST_WRITE
14079 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
14080#endif /* ST_WRITE */
14081#ifdef ST_APPEND
14082 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
14083#endif /* ST_APPEND */
14084#ifdef ST_NOATIME
14085 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
14086#endif /* ST_NOATIME */
14087#ifdef ST_NODIRATIME
14088 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
14089#endif /* ST_NODIRATIME */
14090#ifdef ST_RELATIME
14091 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
14092#endif /* ST_RELATIME */
14093
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014094 /* FreeBSD sendfile() constants */
14095#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014096 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014097#endif
14098#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014099 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014100#endif
14101#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014102 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014103#endif
14104
Ross Lagerwall7807c352011-03-17 20:20:30 +020014105 /* constants for posix_fadvise */
14106#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014107 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014108#endif
14109#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014110 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014111#endif
14112#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014113 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014114#endif
14115#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014116 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014117#endif
14118#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014119 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014120#endif
14121#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014122 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014123#endif
14124
14125 /* constants for waitid */
14126#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014127 if (PyModule_AddIntMacro(m, P_PID)) return -1;
14128 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
14129 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080014130#ifdef P_PIDFD
14131 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
14132#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014133#endif
14134#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014135 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014136#endif
14137#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014138 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014139#endif
14140#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014141 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014142#endif
14143#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014144 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014145#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014146#ifdef CLD_KILLED
14147 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
14148#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014149#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014150 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014151#endif
14152#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014153 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014154#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014155#ifdef CLD_STOPPED
14156 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
14157#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014158#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014159 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014160#endif
14161
14162 /* constants for lockf */
14163#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014164 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014165#endif
14166#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014167 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014168#endif
14169#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014170 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014171#endif
14172#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014173 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014174#endif
14175
Pablo Galindo4defba32018-01-27 16:16:37 +000014176#ifdef RWF_DSYNC
14177 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14178#endif
14179#ifdef RWF_HIPRI
14180 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14181#endif
14182#ifdef RWF_SYNC
14183 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14184#endif
14185#ifdef RWF_NOWAIT
14186 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14187#endif
14188
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014189/* constants for posix_spawn */
14190#ifdef HAVE_POSIX_SPAWN
14191 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14192 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14193 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14194#endif
14195
pxinwrf2d7ac72019-05-21 18:46:37 +080014196#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014197 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14198 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014199 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014200#endif
14201#ifdef HAVE_SPAWNV
14202 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014203 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014204#endif
14205
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014206#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014207#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014208 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014209#endif
14210#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014211 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014212#endif
14213#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014214 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014215#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014216#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014217 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014218#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014219#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014220 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014221#endif
14222#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014223 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014224#endif
14225#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014226 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014227#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014228#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014229 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014230#endif
14231#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014232 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014233#endif
14234#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014235 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014236#endif
14237#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014238 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014239#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014240#endif
14241
Benjamin Peterson9428d532011-09-14 11:45:52 -040014242#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014243 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
14244 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
14245 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040014246#endif
14247
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014248#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014249 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014250#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014251#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014252 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014253#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014254#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014255 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014256#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014257#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014258 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014259#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014260#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014261 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014262#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014263#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014264 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014265#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014266#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014267 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014268#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010014269#if HAVE_DECL_RTLD_MEMBER
14270 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
14271#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020014272
Victor Stinner9b1f4742016-09-06 16:18:52 -070014273#ifdef HAVE_GETRANDOM_SYSCALL
14274 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
14275 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
14276#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014277#ifdef HAVE_MEMFD_CREATE
14278 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
14279 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
14280#ifdef MFD_HUGETLB
14281 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014282#endif
14283#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014284 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014285#endif
14286#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014287 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014288#endif
14289#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014290 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014291#endif
14292#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014293 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014294#endif
14295#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014296 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014297#endif
14298#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014299 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014300#endif
14301#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014302 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014303#endif
14304#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014305 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014306#endif
14307#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014308 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014309#endif
14310#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014311 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014312#endif
14313#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014314 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014315#endif
14316#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014317 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014318#endif
14319#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014320 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014321#endif
14322#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014323 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
14324#endif
14325#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070014326
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014327#if defined(__APPLE__)
14328 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
14329#endif
14330
Steve Dower2438cdf2019-03-29 16:37:16 -070014331#ifdef MS_WINDOWS
14332 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
14333 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
14334 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
14335 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
14336 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
14337#endif
14338
Victor Stinner8c62be82010-05-06 00:08:46 +000014339 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000014340}
14341
14342
Martin v. Löwis1a214512008-06-11 05:26:20 +000014343static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000014344 PyModuleDef_HEAD_INIT,
14345 MODNAME,
14346 posix__doc__,
Eddie Elizondob3966632019-11-05 07:16:14 -080014347 sizeof(_posixstate),
Victor Stinner8c62be82010-05-06 00:08:46 +000014348 posix_methods,
14349 NULL,
Eddie Elizondob3966632019-11-05 07:16:14 -080014350 _posix_traverse,
14351 _posix_clear,
14352 _posix_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +000014353};
14354
14355
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014356static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014357
14358#ifdef HAVE_FACCESSAT
14359 "HAVE_FACCESSAT",
14360#endif
14361
14362#ifdef HAVE_FCHDIR
14363 "HAVE_FCHDIR",
14364#endif
14365
14366#ifdef HAVE_FCHMOD
14367 "HAVE_FCHMOD",
14368#endif
14369
14370#ifdef HAVE_FCHMODAT
14371 "HAVE_FCHMODAT",
14372#endif
14373
14374#ifdef HAVE_FCHOWN
14375 "HAVE_FCHOWN",
14376#endif
14377
Larry Hastings00964ed2013-08-12 13:49:30 -040014378#ifdef HAVE_FCHOWNAT
14379 "HAVE_FCHOWNAT",
14380#endif
14381
Larry Hastings9cf065c2012-06-22 16:30:09 -070014382#ifdef HAVE_FEXECVE
14383 "HAVE_FEXECVE",
14384#endif
14385
14386#ifdef HAVE_FDOPENDIR
14387 "HAVE_FDOPENDIR",
14388#endif
14389
Georg Brandl306336b2012-06-24 12:55:33 +020014390#ifdef HAVE_FPATHCONF
14391 "HAVE_FPATHCONF",
14392#endif
14393
Larry Hastings9cf065c2012-06-22 16:30:09 -070014394#ifdef HAVE_FSTATAT
14395 "HAVE_FSTATAT",
14396#endif
14397
14398#ifdef HAVE_FSTATVFS
14399 "HAVE_FSTATVFS",
14400#endif
14401
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014402#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014403 "HAVE_FTRUNCATE",
14404#endif
14405
Larry Hastings9cf065c2012-06-22 16:30:09 -070014406#ifdef HAVE_FUTIMENS
14407 "HAVE_FUTIMENS",
14408#endif
14409
14410#ifdef HAVE_FUTIMES
14411 "HAVE_FUTIMES",
14412#endif
14413
14414#ifdef HAVE_FUTIMESAT
14415 "HAVE_FUTIMESAT",
14416#endif
14417
14418#ifdef HAVE_LINKAT
14419 "HAVE_LINKAT",
14420#endif
14421
14422#ifdef HAVE_LCHFLAGS
14423 "HAVE_LCHFLAGS",
14424#endif
14425
14426#ifdef HAVE_LCHMOD
14427 "HAVE_LCHMOD",
14428#endif
14429
14430#ifdef HAVE_LCHOWN
14431 "HAVE_LCHOWN",
14432#endif
14433
14434#ifdef HAVE_LSTAT
14435 "HAVE_LSTAT",
14436#endif
14437
14438#ifdef HAVE_LUTIMES
14439 "HAVE_LUTIMES",
14440#endif
14441
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014442#ifdef HAVE_MEMFD_CREATE
14443 "HAVE_MEMFD_CREATE",
14444#endif
14445
Larry Hastings9cf065c2012-06-22 16:30:09 -070014446#ifdef HAVE_MKDIRAT
14447 "HAVE_MKDIRAT",
14448#endif
14449
14450#ifdef HAVE_MKFIFOAT
14451 "HAVE_MKFIFOAT",
14452#endif
14453
14454#ifdef HAVE_MKNODAT
14455 "HAVE_MKNODAT",
14456#endif
14457
14458#ifdef HAVE_OPENAT
14459 "HAVE_OPENAT",
14460#endif
14461
14462#ifdef HAVE_READLINKAT
14463 "HAVE_READLINKAT",
14464#endif
14465
14466#ifdef HAVE_RENAMEAT
14467 "HAVE_RENAMEAT",
14468#endif
14469
14470#ifdef HAVE_SYMLINKAT
14471 "HAVE_SYMLINKAT",
14472#endif
14473
14474#ifdef HAVE_UNLINKAT
14475 "HAVE_UNLINKAT",
14476#endif
14477
14478#ifdef HAVE_UTIMENSAT
14479 "HAVE_UTIMENSAT",
14480#endif
14481
14482#ifdef MS_WINDOWS
14483 "MS_WINDOWS",
14484#endif
14485
14486 NULL
14487};
14488
14489
Mark Hammondfe51c6d2002-08-02 02:27:13 +000014490PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000014491INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014492{
Victor Stinner8c62be82010-05-06 00:08:46 +000014493 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014494 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014495 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000014496
Eddie Elizondob3966632019-11-05 07:16:14 -080014497 m = PyState_FindModule(&posixmodule);
14498 if (m != NULL) {
14499 Py_INCREF(m);
14500 return m;
14501 }
14502
Victor Stinner8c62be82010-05-06 00:08:46 +000014503 m = PyModule_Create(&posixmodule);
14504 if (m == NULL)
14505 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000014506
Victor Stinner8c62be82010-05-06 00:08:46 +000014507 /* Initialize environ dictionary */
14508 v = convertenviron();
14509 Py_XINCREF(v);
14510 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
14511 return NULL;
14512 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014513
Victor Stinner8c62be82010-05-06 00:08:46 +000014514 if (all_ins(m))
14515 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000014516
Victor Stinner8c62be82010-05-06 00:08:46 +000014517 if (setup_confname_tables(m))
14518 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000014519
Victor Stinner8c62be82010-05-06 00:08:46 +000014520 Py_INCREF(PyExc_OSError);
14521 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014522
Victor Stinner623ed612020-01-21 19:25:32 +010014523#ifdef PY_PUTENV_DICT
Eddie Elizondob3966632019-11-05 07:16:14 -080014524 /* Save putenv() parameters as values here, so we can collect them when they
14525 * get re-set with another call for the same key. */
Victor Stinner623ed612020-01-21 19:25:32 +010014526 _posixstate(m)->putenv_dict = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000014527#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000014528
Ross Lagerwall7807c352011-03-17 20:20:30 +020014529#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080014530 waitid_result_desc.name = MODNAME ".waitid_result";
14531 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
14532 if (WaitidResultType == NULL) {
14533 return NULL;
14534 }
14535 Py_INCREF(WaitidResultType);
14536 PyModule_AddObject(m, "waitid_result", WaitidResultType);
14537 _posixstate(m)->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014538#endif
14539
Eddie Elizondob3966632019-11-05 07:16:14 -080014540 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
14541 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14542 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14543 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
14544 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
14545 if (StatResultType == NULL) {
14546 return NULL;
14547 }
14548 Py_INCREF(StatResultType);
14549 PyModule_AddObject(m, "stat_result", StatResultType);
14550 _posixstate(m)->StatResultType = StatResultType;
14551 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
14552 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014553
Eddie Elizondob3966632019-11-05 07:16:14 -080014554 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
14555 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
14556 if (StatVFSResultType == NULL) {
14557 return NULL;
14558 }
14559 Py_INCREF(StatVFSResultType);
14560 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
14561 _posixstate(m)->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014562#ifdef NEED_TICKS_PER_SECOND
14563# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080014564 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014565# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080014566 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014567# else
Eddie Elizondob3966632019-11-05 07:16:14 -080014568 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014569# endif
14570#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014571
William Orr81574b82018-10-01 22:19:56 -070014572#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080014573 sched_param_desc.name = MODNAME ".sched_param";
14574 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
14575 if (SchedParamType == NULL) {
14576 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014577 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014578 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080014579 PyModule_AddObject(m, "sched_param", SchedParamType);
14580 _posixstate(m)->SchedParamType = SchedParamType;
14581 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014582#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014583
Eddie Elizondob3966632019-11-05 07:16:14 -080014584 /* initialize TerminalSize_info */
14585 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
14586 if (TerminalSizeType == NULL) {
14587 return NULL;
14588 }
14589 Py_INCREF(TerminalSizeType);
14590 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
14591 _posixstate(m)->TerminalSizeType = TerminalSizeType;
14592
14593 /* initialize scandir types */
14594 PyObject *ScandirIteratorType = PyType_FromSpec(&ScandirIteratorType_spec);
14595 if (ScandirIteratorType == NULL) {
14596 return NULL;
14597 }
14598 _posixstate(m)->ScandirIteratorType = ScandirIteratorType;
14599
14600 PyObject *DirEntryType = PyType_FromSpec(&DirEntryType_spec);
14601 if (DirEntryType == NULL) {
14602 return NULL;
14603 }
14604 Py_INCREF(DirEntryType);
14605 PyModule_AddObject(m, "DirEntry", DirEntryType);
14606 _posixstate(m)->DirEntryType = DirEntryType;
14607
Larry Hastings605a62d2012-06-24 04:33:36 -070014608 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080014609 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014610 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014611 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014612 }
Eddie Elizondob3966632019-11-05 07:16:14 -080014613 Py_INCREF(TimesResultType);
14614 PyModule_AddObject(m, "times_result", TimesResultType);
14615 _posixstate(m)->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070014616
Eddie Elizondob3966632019-11-05 07:16:14 -080014617 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014618 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014619 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014620 }
Eddie Elizondob3966632019-11-05 07:16:14 -080014621 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014622 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -080014623 _posixstate(m)->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070014624
Thomas Wouters477c8d52006-05-27 19:21:47 +000014625#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014626 /*
14627 * Step 2 of weak-linking support on Mac OS X.
14628 *
14629 * The code below removes functions that are not available on the
14630 * currently active platform.
14631 *
14632 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014633 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014634 * OSX 10.4.
14635 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014636#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014637 if (fstatvfs == NULL) {
14638 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14639 return NULL;
14640 }
14641 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014642#endif /* HAVE_FSTATVFS */
14643
14644#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014645 if (statvfs == NULL) {
14646 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14647 return NULL;
14648 }
14649 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014650#endif /* HAVE_STATVFS */
14651
14652# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014653 if (lchown == NULL) {
14654 if (PyObject_DelAttrString(m, "lchown") == -1) {
14655 return NULL;
14656 }
14657 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014658#endif /* HAVE_LCHOWN */
14659
14660
14661#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014662
Eddie Elizondob3966632019-11-05 07:16:14 -080014663 if ((_posixstate(m)->billion = PyLong_FromLong(1000000000)) == NULL)
14664 return NULL;
14665#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
14666 _posixstate(m)->struct_rusage = PyUnicode_InternFromString("struct_rusage");
14667 if (_posixstate(m)->struct_rusage == NULL)
14668 return NULL;
14669#endif
14670 _posixstate(m)->st_mode = PyUnicode_InternFromString("st_mode");
14671 if (_posixstate(m)->st_mode == NULL)
Larry Hastings6fe20b32012-04-19 15:07:49 -070014672 return NULL;
14673
Larry Hastings9cf065c2012-06-22 16:30:09 -070014674 /* suppress "function not used" warnings */
14675 {
14676 int ignored;
14677 fd_specified("", -1);
14678 follow_symlinks_specified("", 1);
14679 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14680 dir_fd_converter(Py_None, &ignored);
14681 dir_fd_unavailable(Py_None, &ignored);
14682 }
14683
14684 /*
14685 * provide list of locally available functions
14686 * so os.py can populate support_* lists
14687 */
14688 list = PyList_New(0);
14689 if (!list)
14690 return NULL;
14691 for (trace = have_functions; *trace; trace++) {
14692 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14693 if (!unicode)
14694 return NULL;
14695 if (PyList_Append(list, unicode))
14696 return NULL;
14697 Py_DECREF(unicode);
14698 }
14699 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014700
Victor Stinner8c62be82010-05-06 00:08:46 +000014701 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014702}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014703
14704#ifdef __cplusplus
14705}
14706#endif