blob: 9f15866d9d3db4048ea2c875c1f51755bea26196 [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() */
39#include "pycore_pystate.h" /* _PyRuntime */
Antoine Pitrou346cbd32017-05-27 17:50:54 +020040#include "pythread.h"
Victor Stinner6036e442015-03-08 01:58:04 +010041#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020042#ifndef MS_WINDOWS
Victor Stinnerd5d9e812019-05-13 12:35:37 +020043# include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010044#else
Victor Stinnerd5d9e812019-05-13 12:35:37 +020045# include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020046#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000047
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020048/* On android API level 21, 'AT_EACCESS' is not declared although
49 * HAVE_FACCESSAT is defined. */
50#ifdef __ANDROID__
51#undef HAVE_FACCESSAT
52#endif
53
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000054#include <stdio.h> /* needed for ctermid() */
55
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000056#ifdef __cplusplus
57extern "C" {
58#endif
59
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000060PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000061"This module provides access to operating system functionality that is\n\
62standardized by the C Standard and the POSIX standard (a thinly\n\
63disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000064corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000065
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000066
Ross Lagerwall4d076da2011-03-18 06:56:53 +020067#ifdef HAVE_SYS_UIO_H
68#include <sys/uio.h>
69#endif
70
Christian Heimes75b96182017-09-05 15:53:09 +020071#ifdef HAVE_SYS_SYSMACROS_H
72/* GNU C Library: major(), minor(), makedev() */
73#include <sys/sysmacros.h>
74#endif
75
Thomas Wouters0e3f5912006-08-11 14:57:12 +000076#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000077#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#endif /* HAVE_SYS_TYPES_H */
79
80#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000081#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000082#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000083
Guido van Rossum36bc6801995-06-14 22:54:23 +000084#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000085#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000086#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000087
Thomas Wouters0e3f5912006-08-11 14:57:12 +000088#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000089#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000090#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000091
Guido van Rossumb6775db1994-08-01 11:34:53 +000092#ifdef HAVE_FCNTL_H
93#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000094#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000095
Guido van Rossuma6535fd2001-10-18 19:44:10 +000096#ifdef HAVE_GRP_H
97#include <grp.h>
98#endif
99
Barry Warsaw5676bd12003-01-07 20:57:09 +0000100#ifdef HAVE_SYSEXITS_H
101#include <sysexits.h>
102#endif /* HAVE_SYSEXITS_H */
103
Anthony Baxter8a560de2004-10-13 15:30:56 +0000104#ifdef HAVE_SYS_LOADAVG_H
105#include <sys/loadavg.h>
106#endif
107
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000108#ifdef HAVE_SYS_SENDFILE_H
109#include <sys/sendfile.h>
110#endif
111
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200112#if defined(__APPLE__)
113#include <copyfile.h>
114#endif
115
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500116#ifdef HAVE_SCHED_H
117#include <sched.h>
118#endif
119
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500120#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500121#undef HAVE_SCHED_SETAFFINITY
122#endif
123
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200124#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400125#define USE_XATTRS
126#endif
127
128#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400129#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400130#endif
131
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000132#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
133#ifdef HAVE_SYS_SOCKET_H
134#include <sys/socket.h>
135#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000136#endif
137
Victor Stinner8b905bd2011-10-25 13:34:04 +0200138#ifdef HAVE_DLFCN_H
139#include <dlfcn.h>
140#endif
141
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200142#ifdef __hpux
143#include <sys/mpctl.h>
144#endif
145
146#if defined(__DragonFly__) || \
147 defined(__OpenBSD__) || \
148 defined(__FreeBSD__) || \
149 defined(__NetBSD__) || \
150 defined(__APPLE__)
151#include <sys/sysctl.h>
152#endif
153
Victor Stinner9b1f4742016-09-06 16:18:52 -0700154#ifdef HAVE_LINUX_RANDOM_H
155# include <linux/random.h>
156#endif
157#ifdef HAVE_GETRANDOM_SYSCALL
158# include <sys/syscall.h>
159#endif
160
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100161#if defined(MS_WINDOWS)
162# define TERMSIZE_USE_CONIO
163#elif defined(HAVE_SYS_IOCTL_H)
164# include <sys/ioctl.h>
165# if defined(HAVE_TERMIOS_H)
166# include <termios.h>
167# endif
168# if defined(TIOCGWINSZ)
169# define TERMSIZE_USE_IOCTL
170# endif
171#endif /* MS_WINDOWS */
172
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000174/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000175#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000177#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#include <process.h>
179#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000180#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000181#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000182#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000183#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000184#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700185#define HAVE_WSPAWNV 1
186#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000187#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000188#define HAVE_SYSTEM 1
189#define HAVE_CWAIT 1
190#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000191#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000192#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000193/* Unix functions that the configure script doesn't check for */
pxinwrf2d7ac72019-05-21 18:46:37 +0800194#ifndef __VXWORKS__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000195#define HAVE_EXECV 1
196#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000197#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000198#define HAVE_FORK1 1
199#endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800200#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#define HAVE_GETEGID 1
202#define HAVE_GETEUID 1
203#define HAVE_GETGID 1
204#define HAVE_GETPPID 1
205#define HAVE_GETUID 1
206#define HAVE_KILL 1
207#define HAVE_OPENDIR 1
208#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000209#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000211#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000213#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000214
Victor Stinnera2f7c002012-02-08 03:36:25 +0100215
Larry Hastings61272b72014-01-07 12:41:53 -0800216/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000217# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800218module os
Larry Hastings61272b72014-01-07 12:41:53 -0800219[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000220/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100221
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000222#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000223
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000224#if defined(__sgi)&&_COMPILER_VERSION>=700
225/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
226 (default) */
227extern char *ctermid_r(char *);
228#endif
229
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000230#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231
pxinwrf2d7ac72019-05-21 18:46:37 +0800232#if defined(__VXWORKS__)
233#include <vxCpuLib.h>
234#include <rtpLib.h>
235#include <wait.h>
236#include <taskLib.h>
237#ifndef _P_WAIT
238#define _P_WAIT 0
239#define _P_NOWAIT 1
240#define _P_NOWAITO 1
241#endif
242#endif /* __VXWORKS__ */
243
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000244#ifdef HAVE_POSIX_SPAWN
245#include <spawn.h>
246#endif
247
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#ifdef HAVE_UTIME_H
249#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000250#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000252#ifdef HAVE_SYS_UTIME_H
253#include <sys/utime.h>
254#define HAVE_UTIME_H /* pretend we do for the rest of this file */
255#endif /* HAVE_SYS_UTIME_H */
256
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#ifdef HAVE_SYS_TIMES_H
258#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000259#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260
261#ifdef HAVE_SYS_PARAM_H
262#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000263#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264
265#ifdef HAVE_SYS_UTSNAME_H
266#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000267#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000269#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000271#define NAMLEN(dirent) strlen((dirent)->d_name)
272#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000273#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000274#include <direct.h>
275#define NAMLEN(dirent) strlen((dirent)->d_name)
276#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#endif
283#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#endif
286#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#endif
289#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000291#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294#endif
295#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#endif
298#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000301#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000302#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000303#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100304#ifndef IO_REPARSE_TAG_MOUNT_POINT
305#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
306#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000307#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000308#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000309#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000310#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000311#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000312#define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000313#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000314
Tim Petersbc2e10e2002-03-03 23:17:02 +0000315#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000316#if defined(PATH_MAX) && PATH_MAX > 1024
317#define MAXPATHLEN PATH_MAX
318#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000319#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000321#endif /* MAXPATHLEN */
322
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000323#ifdef UNION_WAIT
324/* Emulate some macros on systems that have a union instead of macros */
325
326#ifndef WIFEXITED
327#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
328#endif
329
330#ifndef WEXITSTATUS
331#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
332#endif
333
334#ifndef WTERMSIG
335#define WTERMSIG(u_wait) ((u_wait).w_termsig)
336#endif
337
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000338#define WAIT_TYPE union wait
339#define WAIT_STATUS_INT(s) (s.w_status)
340
341#else /* !UNION_WAIT */
342#define WAIT_TYPE int
343#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000344#endif /* UNION_WAIT */
345
Greg Wardb48bc172000-03-01 21:51:56 +0000346/* Don't use the "_r" form if we don't need it (also, won't have a
347 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200348#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000349#define USE_CTERMID_R
350#endif
351
Fred Drake699f3522000-06-29 21:12:41 +0000352/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000353#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000354#undef FSTAT
355#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200356#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000357# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700358# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200359# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800360# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000361#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000362# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700363# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000364# define FSTAT fstat
365# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000366#endif
367
Tim Peters11b23062003-04-23 02:39:17 +0000368#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000369#include <sys/mkdev.h>
370#else
371#if defined(MAJOR_IN_SYSMACROS)
372#include <sys/sysmacros.h>
373#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000374#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
375#include <sys/mkdev.h>
376#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000377#endif
Fred Drake699f3522000-06-29 21:12:41 +0000378
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200379#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100380#define INITFUNC PyInit_nt
381#define MODNAME "nt"
382#else
383#define INITFUNC PyInit_posix
384#define MODNAME "posix"
385#endif
386
jcea6c51d512018-01-28 14:00:08 +0100387#if defined(__sun)
388/* Something to implement in autoconf, not present in autoconf 2.69 */
389#define HAVE_STRUCT_STAT_ST_FSTYPE 1
390#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200391
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800392#ifdef _Py_MEMORY_SANITIZER
393# include <sanitizer/msan_interface.h>
394#endif
395
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200396#ifdef HAVE_FORK
397static void
398run_at_forkers(PyObject *lst, int reverse)
399{
400 Py_ssize_t i;
401 PyObject *cpy;
402
403 if (lst != NULL) {
404 assert(PyList_CheckExact(lst));
405
406 /* Use a list copy in case register_at_fork() is called from
407 * one of the callbacks.
408 */
409 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
410 if (cpy == NULL)
411 PyErr_WriteUnraisable(lst);
412 else {
413 if (reverse)
414 PyList_Reverse(cpy);
415 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
416 PyObject *func, *res;
417 func = PyList_GET_ITEM(cpy, i);
418 res = PyObject_CallObject(func, NULL);
419 if (res == NULL)
420 PyErr_WriteUnraisable(func);
421 else
422 Py_DECREF(res);
423 }
424 Py_DECREF(cpy);
425 }
426 }
427}
428
429void
430PyOS_BeforeFork(void)
431{
Victor Stinnercaba55b2018-08-03 15:33:52 +0200432 run_at_forkers(_PyInterpreterState_Get()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200433
434 _PyImport_AcquireLock();
435}
436
437void
438PyOS_AfterFork_Parent(void)
439{
440 if (_PyImport_ReleaseLock() <= 0)
441 Py_FatalError("failed releasing import lock after fork");
442
Victor Stinnercaba55b2018-08-03 15:33:52 +0200443 run_at_forkers(_PyInterpreterState_Get()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200444}
445
446void
447PyOS_AfterFork_Child(void)
448{
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200449 _PyRuntimeState *runtime = &_PyRuntime;
450 _PyGILState_Reinit(runtime);
451 _PyInterpreterState_DeleteExceptMain(runtime);
Victor Stinnerd5d9e812019-05-13 12:35:37 +0200452 _PyEval_ReInitThreads(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200453 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200454 _PySignal_AfterFork();
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200455 _PyRuntimeState_ReInitThreads(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200456
Victor Stinnercaba55b2018-08-03 15:33:52 +0200457 run_at_forkers(_PyInterpreterState_Get()->after_forkers_child, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200458}
459
460static int
461register_at_forker(PyObject **lst, PyObject *func)
462{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700463 if (func == NULL) /* nothing to register? do nothing. */
464 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200465 if (*lst == NULL) {
466 *lst = PyList_New(0);
467 if (*lst == NULL)
468 return -1;
469 }
470 return PyList_Append(*lst, func);
471}
472#endif
473
474/* Legacy wrapper */
475void
476PyOS_AfterFork(void)
477{
478#ifdef HAVE_FORK
479 PyOS_AfterFork_Child();
480#endif
481}
482
483
Victor Stinner6036e442015-03-08 01:58:04 +0100484#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200485/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700486void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
487void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200488 ULONG, struct _Py_stat_struct *);
489#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700490
491#ifdef MS_WINDOWS
492static int
493win32_warn_bytes_api()
494{
495 return PyErr_WarnEx(PyExc_DeprecationWarning,
496 "The Windows bytes API has been deprecated, "
497 "use Unicode filenames instead",
498 1);
499}
500#endif
501
502
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200503#ifndef MS_WINDOWS
504PyObject *
505_PyLong_FromUid(uid_t uid)
506{
507 if (uid == (uid_t)-1)
508 return PyLong_FromLong(-1);
509 return PyLong_FromUnsignedLong(uid);
510}
511
512PyObject *
513_PyLong_FromGid(gid_t gid)
514{
515 if (gid == (gid_t)-1)
516 return PyLong_FromLong(-1);
517 return PyLong_FromUnsignedLong(gid);
518}
519
520int
521_Py_Uid_Converter(PyObject *obj, void *p)
522{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700523 uid_t uid;
524 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200525 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200526 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700527 unsigned long uresult;
528
529 index = PyNumber_Index(obj);
530 if (index == NULL) {
531 PyErr_Format(PyExc_TypeError,
532 "uid should be integer, not %.200s",
533 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200534 return 0;
535 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700536
537 /*
538 * Handling uid_t is complicated for two reasons:
539 * * Although uid_t is (always?) unsigned, it still
540 * accepts -1.
541 * * We don't know its size in advance--it may be
542 * bigger than an int, or it may be smaller than
543 * a long.
544 *
545 * So a bit of defensive programming is in order.
546 * Start with interpreting the value passed
547 * in as a signed long and see if it works.
548 */
549
550 result = PyLong_AsLongAndOverflow(index, &overflow);
551
552 if (!overflow) {
553 uid = (uid_t)result;
554
555 if (result == -1) {
556 if (PyErr_Occurred())
557 goto fail;
558 /* It's a legitimate -1, we're done. */
559 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200560 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700561
562 /* Any other negative number is disallowed. */
563 if (result < 0)
564 goto underflow;
565
566 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200567 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700568 (long)uid != result)
569 goto underflow;
570 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200571 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700572
573 if (overflow < 0)
574 goto underflow;
575
576 /*
577 * Okay, the value overflowed a signed long. If it
578 * fits in an *unsigned* long, it may still be okay,
579 * as uid_t may be unsigned long on this platform.
580 */
581 uresult = PyLong_AsUnsignedLong(index);
582 if (PyErr_Occurred()) {
583 if (PyErr_ExceptionMatches(PyExc_OverflowError))
584 goto overflow;
585 goto fail;
586 }
587
588 uid = (uid_t)uresult;
589
590 /*
591 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
592 * but this value would get interpreted as (uid_t)-1 by chown
593 * and its siblings. That's not what the user meant! So we
594 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100595 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700596 */
597 if (uid == (uid_t)-1)
598 goto overflow;
599
600 /* Ensure the value wasn't truncated. */
601 if (sizeof(uid_t) < sizeof(long) &&
602 (unsigned long)uid != uresult)
603 goto overflow;
604 /* fallthrough */
605
606success:
607 Py_DECREF(index);
608 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200609 return 1;
610
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700611underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200612 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700613 "uid is less than minimum");
614 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200615
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200617 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618 "uid is greater than maximum");
619 /* fallthrough */
620
621fail:
622 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200623 return 0;
624}
625
626int
627_Py_Gid_Converter(PyObject *obj, void *p)
628{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700629 gid_t gid;
630 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200631 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200632 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700633 unsigned long uresult;
634
635 index = PyNumber_Index(obj);
636 if (index == NULL) {
637 PyErr_Format(PyExc_TypeError,
638 "gid should be integer, not %.200s",
639 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200640 return 0;
641 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700642
643 /*
644 * Handling gid_t is complicated for two reasons:
645 * * Although gid_t is (always?) unsigned, it still
646 * accepts -1.
647 * * We don't know its size in advance--it may be
648 * bigger than an int, or it may be smaller than
649 * a long.
650 *
651 * So a bit of defensive programming is in order.
652 * Start with interpreting the value passed
653 * in as a signed long and see if it works.
654 */
655
656 result = PyLong_AsLongAndOverflow(index, &overflow);
657
658 if (!overflow) {
659 gid = (gid_t)result;
660
661 if (result == -1) {
662 if (PyErr_Occurred())
663 goto fail;
664 /* It's a legitimate -1, we're done. */
665 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200666 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700667
668 /* Any other negative number is disallowed. */
669 if (result < 0) {
670 goto underflow;
671 }
672
673 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200674 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700675 (long)gid != result)
676 goto underflow;
677 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200678 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700679
680 if (overflow < 0)
681 goto underflow;
682
683 /*
684 * Okay, the value overflowed a signed long. If it
685 * fits in an *unsigned* long, it may still be okay,
686 * as gid_t may be unsigned long on this platform.
687 */
688 uresult = PyLong_AsUnsignedLong(index);
689 if (PyErr_Occurred()) {
690 if (PyErr_ExceptionMatches(PyExc_OverflowError))
691 goto overflow;
692 goto fail;
693 }
694
695 gid = (gid_t)uresult;
696
697 /*
698 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
699 * but this value would get interpreted as (gid_t)-1 by chown
700 * and its siblings. That's not what the user meant! So we
701 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100702 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700703 */
704 if (gid == (gid_t)-1)
705 goto overflow;
706
707 /* Ensure the value wasn't truncated. */
708 if (sizeof(gid_t) < sizeof(long) &&
709 (unsigned long)gid != uresult)
710 goto overflow;
711 /* fallthrough */
712
713success:
714 Py_DECREF(index);
715 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200716 return 1;
717
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700718underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200719 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700720 "gid is less than minimum");
721 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200722
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700723overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200724 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700725 "gid is greater than maximum");
726 /* fallthrough */
727
728fail:
729 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200730 return 0;
731}
732#endif /* MS_WINDOWS */
733
734
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700735#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800736
737
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200738#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
739static int
740_Py_Dev_Converter(PyObject *obj, void *p)
741{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200742 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200743 if (PyErr_Occurred())
744 return 0;
745 return 1;
746}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800747#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200748
749
Larry Hastings9cf065c2012-06-22 16:30:09 -0700750#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400751/*
752 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
753 * without the int cast, the value gets interpreted as uint (4291925331),
754 * which doesn't play nicely with all the initializer lines in this file that
755 * look like this:
756 * int dir_fd = DEFAULT_DIR_FD;
757 */
758#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700759#else
760#define DEFAULT_DIR_FD (-100)
761#endif
762
763static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300764_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200765{
766 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700767 long long_value;
768
769 PyObject *index = PyNumber_Index(o);
770 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700771 return 0;
772 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700773
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300774 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700775 long_value = PyLong_AsLongAndOverflow(index, &overflow);
776 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300777 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200778 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700779 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700780 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700781 return 0;
782 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200783 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700784 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700785 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700786 return 0;
787 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700788
Larry Hastings9cf065c2012-06-22 16:30:09 -0700789 *p = (int)long_value;
790 return 1;
791}
792
793static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200794dir_fd_converter(PyObject *o, void *p)
795{
796 if (o == Py_None) {
797 *(int *)p = DEFAULT_DIR_FD;
798 return 1;
799 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300800 else if (PyIndex_Check(o)) {
801 return _fd_converter(o, (int *)p);
802 }
803 else {
804 PyErr_Format(PyExc_TypeError,
805 "argument should be integer or None, not %.200s",
806 Py_TYPE(o)->tp_name);
807 return 0;
808 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700809}
810
811
Larry Hastings9cf065c2012-06-22 16:30:09 -0700812/*
813 * A PyArg_ParseTuple "converter" function
814 * that handles filesystem paths in the manner
815 * preferred by the os module.
816 *
817 * path_converter accepts (Unicode) strings and their
818 * subclasses, and bytes and their subclasses. What
819 * it does with the argument depends on the platform:
820 *
821 * * On Windows, if we get a (Unicode) string we
822 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700823 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700824 *
825 * * On all other platforms, strings are encoded
826 * to bytes using PyUnicode_FSConverter, then we
827 * extract the char * from the bytes object and
828 * return that.
829 *
830 * path_converter also optionally accepts signed
831 * integers (representing open file descriptors) instead
832 * of path strings.
833 *
834 * Input fields:
835 * path.nullable
836 * If nonzero, the path is permitted to be None.
837 * path.allow_fd
838 * If nonzero, the path is permitted to be a file handle
839 * (a signed int) instead of a string.
840 * path.function_name
841 * If non-NULL, path_converter will use that as the name
842 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700843 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700844 * path.argument_name
845 * If non-NULL, path_converter will use that as the name
846 * of the parameter in error messages.
847 * (If path.argument_name is NULL it uses "path".)
848 *
849 * Output fields:
850 * path.wide
851 * Points to the path if it was expressed as Unicode
852 * and was not encoded. (Only used on Windows.)
853 * path.narrow
854 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700855 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000856 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700857 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700858 * path.fd
859 * Contains a file descriptor if path.accept_fd was true
860 * and the caller provided a signed integer instead of any
861 * sort of string.
862 *
863 * WARNING: if your "path" parameter is optional, and is
864 * unspecified, path_converter will never get called.
865 * So if you set allow_fd, you *MUST* initialize path.fd = -1
866 * yourself!
867 * path.length
868 * The length of the path in characters, if specified as
869 * a string.
870 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800871 * The original object passed in (if get a PathLike object,
872 * the result of PyOS_FSPath() is treated as the original object).
873 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700874 * path.cleanup
875 * For internal use only. May point to a temporary object.
876 * (Pay no attention to the man behind the curtain.)
877 *
878 * At most one of path.wide or path.narrow will be non-NULL.
879 * If path was None and path.nullable was set,
880 * or if path was an integer and path.allow_fd was set,
881 * both path.wide and path.narrow will be NULL
882 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200883 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700884 * path_converter takes care to not write to the path_t
885 * unless it's successful. However it must reset the
886 * "cleanup" field each time it's called.
887 *
888 * Use as follows:
889 * path_t path;
890 * memset(&path, 0, sizeof(path));
891 * PyArg_ParseTuple(args, "O&", path_converter, &path);
892 * // ... use values from path ...
893 * path_cleanup(&path);
894 *
895 * (Note that if PyArg_Parse fails you don't need to call
896 * path_cleanup(). However it is safe to do so.)
897 */
898typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100899 const char *function_name;
900 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700901 int nullable;
902 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300903 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700904#ifdef MS_WINDOWS
905 BOOL narrow;
906#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300907 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700908#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700909 int fd;
910 Py_ssize_t length;
911 PyObject *object;
912 PyObject *cleanup;
913} path_t;
914
Steve Dowercc16be82016-09-08 10:35:16 -0700915#ifdef MS_WINDOWS
916#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
917 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
918#else
Larry Hastings2f936352014-08-05 14:04:04 +1000919#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
920 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700921#endif
Larry Hastings31826802013-10-19 00:09:25 -0700922
Larry Hastings9cf065c2012-06-22 16:30:09 -0700923static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800924path_cleanup(path_t *path)
925{
926 Py_CLEAR(path->object);
927 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700928}
929
930static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300931path_converter(PyObject *o, void *p)
932{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800934 PyObject *bytes = NULL;
935 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700936 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300937 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700938#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800939 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700940 const wchar_t *wide;
941#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700942
943#define FORMAT_EXCEPTION(exc, fmt) \
944 PyErr_Format(exc, "%s%s" fmt, \
945 path->function_name ? path->function_name : "", \
946 path->function_name ? ": " : "", \
947 path->argument_name ? path->argument_name : "path")
948
949 /* Py_CLEANUP_SUPPORTED support */
950 if (o == NULL) {
951 path_cleanup(path);
952 return 1;
953 }
954
Brett Cannon3f9183b2016-08-26 14:44:48 -0700955 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800956 path->object = path->cleanup = NULL;
957 /* path->object owns a reference to the original object */
958 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700959
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300960 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700961 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700962#ifdef MS_WINDOWS
963 path->narrow = FALSE;
964#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700965 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700966#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700967 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800968 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700969 }
970
Brett Cannon3f9183b2016-08-26 14:44:48 -0700971 /* Only call this here so that we don't treat the return value of
972 os.fspath() as an fd or buffer. */
973 is_index = path->allow_fd && PyIndex_Check(o);
974 is_buffer = PyObject_CheckBuffer(o);
975 is_bytes = PyBytes_Check(o);
976 is_unicode = PyUnicode_Check(o);
977
978 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
979 /* Inline PyOS_FSPath() for better error messages. */
980 _Py_IDENTIFIER(__fspath__);
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000981 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700982
983 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
984 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800985 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700986 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000987 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700988 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000989 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700990 goto error_exit;
991 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000992 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700993 is_unicode = 1;
994 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000995 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700996 is_bytes = 1;
997 }
998 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000999 PyErr_Format(PyExc_TypeError,
1000 "expected %.200s.__fspath__() to return str or bytes, "
1001 "not %.200s", Py_TYPE(o)->tp_name,
1002 Py_TYPE(res)->tp_name);
1003 Py_DECREF(res);
1004 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001005 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001006
1007 /* still owns a reference to the original object */
1008 Py_DECREF(o);
1009 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001010 }
1011
1012 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001013#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001014 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001015 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001016 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001017 }
Victor Stinner59799a82013-11-13 14:17:30 +01001018 if (length > 32767) {
1019 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001020 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001021 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001022 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001023 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001024 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001025 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001026
1027 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001028 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001029 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001030 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001031#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001032 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001033 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001034 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001035#endif
1036 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001037 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001038 bytes = o;
1039 Py_INCREF(bytes);
1040 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001041 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001042 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001043 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001044 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1045 "%s%s%s should be %s, not %.200s",
1046 path->function_name ? path->function_name : "",
1047 path->function_name ? ": " : "",
1048 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001049 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1050 "integer or None" :
1051 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1052 path->nullable ? "string, bytes, os.PathLike or None" :
1053 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001054 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001055 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001056 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001057 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001058 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001059 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001060 }
1061 }
Steve Dowercc16be82016-09-08 10:35:16 -07001062 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001063 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001064 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001065 }
1066 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001067#ifdef MS_WINDOWS
1068 path->narrow = FALSE;
1069#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001070 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001071#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001072 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001073 }
1074 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001075 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001076 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1077 path->function_name ? path->function_name : "",
1078 path->function_name ? ": " : "",
1079 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001080 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1081 "integer or None" :
1082 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1083 path->nullable ? "string, bytes, os.PathLike or None" :
1084 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001085 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001086 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001087 }
1088
Larry Hastings9cf065c2012-06-22 16:30:09 -07001089 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001090 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001091 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001092 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001093 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001094 }
1095
Steve Dowercc16be82016-09-08 10:35:16 -07001096#ifdef MS_WINDOWS
1097 wo = PyUnicode_DecodeFSDefaultAndSize(
1098 narrow,
1099 length
1100 );
1101 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001102 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001103 }
1104
Xiang Zhang04316c42017-01-08 23:26:57 +08001105 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001106 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001107 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001108 }
1109 if (length > 32767) {
1110 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001111 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001112 }
1113 if (wcslen(wide) != length) {
1114 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001115 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001116 }
1117 path->wide = wide;
1118 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001119 path->cleanup = wo;
1120 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001121#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001122 path->wide = NULL;
1123 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001124 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001125 /* Still a reference owned by path->object, don't have to
1126 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001127 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001128 }
1129 else {
1130 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001131 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001132#endif
1133 path->fd = -1;
1134
1135 success_exit:
1136 path->length = length;
1137 path->object = o;
1138 return Py_CLEANUP_SUPPORTED;
1139
1140 error_exit:
1141 Py_XDECREF(o);
1142 Py_XDECREF(bytes);
1143#ifdef MS_WINDOWS
1144 Py_XDECREF(wo);
1145#endif
1146 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001147}
1148
1149static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001150argument_unavailable_error(const char *function_name, const char *argument_name)
1151{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001152 PyErr_Format(PyExc_NotImplementedError,
1153 "%s%s%s unavailable on this platform",
1154 (function_name != NULL) ? function_name : "",
1155 (function_name != NULL) ? ": ": "",
1156 argument_name);
1157}
1158
1159static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001160dir_fd_unavailable(PyObject *o, void *p)
1161{
1162 int dir_fd;
1163 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001164 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001165 if (dir_fd != DEFAULT_DIR_FD) {
1166 argument_unavailable_error(NULL, "dir_fd");
1167 return 0;
1168 }
1169 *(int *)p = dir_fd;
1170 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001171}
1172
1173static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001174fd_specified(const char *function_name, int fd)
1175{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001176 if (fd == -1)
1177 return 0;
1178
1179 argument_unavailable_error(function_name, "fd");
1180 return 1;
1181}
1182
1183static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001184follow_symlinks_specified(const char *function_name, int follow_symlinks)
1185{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001186 if (follow_symlinks)
1187 return 0;
1188
1189 argument_unavailable_error(function_name, "follow_symlinks");
1190 return 1;
1191}
1192
1193static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001194path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1195{
Steve Dowercc16be82016-09-08 10:35:16 -07001196 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1197#ifndef MS_WINDOWS
1198 && !path->narrow
1199#endif
1200 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001201 PyErr_Format(PyExc_ValueError,
1202 "%s: can't specify dir_fd without matching path",
1203 function_name);
1204 return 1;
1205 }
1206 return 0;
1207}
1208
1209static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001210dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1211{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001212 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1213 PyErr_Format(PyExc_ValueError,
1214 "%s: can't specify both dir_fd and fd",
1215 function_name);
1216 return 1;
1217 }
1218 return 0;
1219}
1220
1221static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001222fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1223 int follow_symlinks)
1224{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001225 if ((fd > 0) && (!follow_symlinks)) {
1226 PyErr_Format(PyExc_ValueError,
1227 "%s: cannot use fd and follow_symlinks together",
1228 function_name);
1229 return 1;
1230 }
1231 return 0;
1232}
1233
1234static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001235dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1236 int follow_symlinks)
1237{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001238 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1239 PyErr_Format(PyExc_ValueError,
1240 "%s: cannot use dir_fd and follow_symlinks together",
1241 function_name);
1242 return 1;
1243 }
1244 return 0;
1245}
1246
Larry Hastings2f936352014-08-05 14:04:04 +10001247#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001248 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001249#else
Larry Hastings2f936352014-08-05 14:04:04 +10001250 typedef off_t Py_off_t;
1251#endif
1252
1253static int
1254Py_off_t_converter(PyObject *arg, void *addr)
1255{
1256#ifdef HAVE_LARGEFILE_SUPPORT
1257 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1258#else
1259 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001260#endif
1261 if (PyErr_Occurred())
1262 return 0;
1263 return 1;
1264}
Larry Hastings2f936352014-08-05 14:04:04 +10001265
1266static PyObject *
1267PyLong_FromPy_off_t(Py_off_t offset)
1268{
1269#ifdef HAVE_LARGEFILE_SUPPORT
1270 return PyLong_FromLongLong(offset);
1271#else
1272 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001273#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001274}
1275
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001276#ifdef HAVE_SIGSET_T
1277/* Convert an iterable of integers to a sigset.
1278 Return 1 on success, return 0 and raise an exception on error. */
1279int
1280_Py_Sigset_Converter(PyObject *obj, void *addr)
1281{
1282 sigset_t *mask = (sigset_t *)addr;
1283 PyObject *iterator, *item;
1284 long signum;
1285 int overflow;
1286
Rémi Lapeyref0900192019-05-04 01:30:53 +02001287 // The extra parens suppress the unreachable-code warning with clang on MacOS
1288 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001289 /* Probably only if mask == NULL. */
1290 PyErr_SetFromErrno(PyExc_OSError);
1291 return 0;
1292 }
1293
1294 iterator = PyObject_GetIter(obj);
1295 if (iterator == NULL) {
1296 return 0;
1297 }
1298
1299 while ((item = PyIter_Next(iterator)) != NULL) {
1300 signum = PyLong_AsLongAndOverflow(item, &overflow);
1301 Py_DECREF(item);
1302 if (signum <= 0 || signum >= NSIG) {
1303 if (overflow || signum != -1 || !PyErr_Occurred()) {
1304 PyErr_Format(PyExc_ValueError,
1305 "signal number %ld out of range", signum);
1306 }
1307 goto error;
1308 }
1309 if (sigaddset(mask, (int)signum)) {
1310 if (errno != EINVAL) {
1311 /* Probably impossible */
1312 PyErr_SetFromErrno(PyExc_OSError);
1313 goto error;
1314 }
1315 /* For backwards compatibility, allow idioms such as
1316 * `range(1, NSIG)` but warn about invalid signal numbers
1317 */
1318 const char msg[] =
1319 "invalid signal number %ld, please use valid_signals()";
1320 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1321 goto error;
1322 }
1323 }
1324 }
1325 if (!PyErr_Occurred()) {
1326 Py_DECREF(iterator);
1327 return 1;
1328 }
1329
1330error:
1331 Py_DECREF(iterator);
1332 return 0;
1333}
1334#endif /* HAVE_SIGSET_T */
1335
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001336#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001337
1338static int
Brian Curtind25aef52011-06-13 15:16:04 -05001339win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001340{
Martin Panter70214ad2016-08-04 02:38:59 +00001341 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1342 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001343 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001344
1345 if (0 == DeviceIoControl(
1346 reparse_point_handle,
1347 FSCTL_GET_REPARSE_POINT,
1348 NULL, 0, /* in buffer */
1349 target_buffer, sizeof(target_buffer),
1350 &n_bytes_returned,
1351 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001352 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001353
1354 if (reparse_tag)
1355 *reparse_tag = rdb->ReparseTag;
1356
Brian Curtind25aef52011-06-13 15:16:04 -05001357 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001358}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001359
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001360#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001361
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001362/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001363#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001364/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001365** environ directly, we must obtain it with _NSGetEnviron(). See also
1366** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001367*/
1368#include <crt_externs.h>
1369static char **environ;
pxinwrf2d7ac72019-05-21 18:46:37 +08001370#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001371extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001372#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001373
Barry Warsaw53699e91996-12-10 23:23:01 +00001374static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001375convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001376{
Victor Stinner8c62be82010-05-06 00:08:46 +00001377 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001378#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001379 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001380#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001382#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001383
Victor Stinner8c62be82010-05-06 00:08:46 +00001384 d = PyDict_New();
1385 if (d == NULL)
1386 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001387#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001388 if (environ == NULL)
1389 environ = *_NSGetEnviron();
1390#endif
1391#ifdef MS_WINDOWS
1392 /* _wenviron must be initialized in this way if the program is started
1393 through main() instead of wmain(). */
1394 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001395 e = _wenviron;
Victor Stinner8c62be82010-05-06 00:08:46 +00001396#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001397 e = environ;
1398#endif
1399 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001401 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001402 PyObject *k;
1403 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001404#ifdef MS_WINDOWS
1405 const wchar_t *p = wcschr(*e, L'=');
1406#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001407 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001408#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001409 if (p == NULL)
1410 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001411#ifdef MS_WINDOWS
1412 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1413#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001414 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001415#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001416 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001417 Py_DECREF(d);
1418 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001419 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001420#ifdef MS_WINDOWS
1421 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1422#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001423 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001424#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001425 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001426 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001427 Py_DECREF(d);
1428 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001429 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001430 if (PyDict_GetItemWithError(d, k) == NULL) {
1431 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1432 Py_DECREF(v);
1433 Py_DECREF(k);
1434 Py_DECREF(d);
1435 return NULL;
1436 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001437 }
1438 Py_DECREF(k);
1439 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001440 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001441 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001442}
1443
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001444/* Set a POSIX-specific error from errno, and return NULL */
1445
Barry Warsawd58d7641998-07-23 16:14:40 +00001446static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001447posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001448{
Victor Stinner8c62be82010-05-06 00:08:46 +00001449 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001450}
Mark Hammondef8b6542001-05-13 08:04:26 +00001451
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001452#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001453static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001454win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001455{
Victor Stinner8c62be82010-05-06 00:08:46 +00001456 /* XXX We should pass the function name along in the future.
1457 (winreg.c also wants to pass the function name.)
1458 This would however require an additional param to the
1459 Windows error object, which is non-trivial.
1460 */
1461 errno = GetLastError();
1462 if (filename)
1463 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1464 else
1465 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001466}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001467
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001468static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001469win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001470{
1471 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001472 if (filename)
1473 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001474 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001475 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001476 filename);
1477 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001478 return PyErr_SetFromWindowsErr(err);
1479}
1480
1481static PyObject *
1482win32_error_object(const char* function, PyObject* filename)
1483{
1484 errno = GetLastError();
1485 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001486}
1487
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001488#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001489
Larry Hastings9cf065c2012-06-22 16:30:09 -07001490static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001491posix_path_object_error(PyObject *path)
1492{
1493 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1494}
1495
1496static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001497path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001498{
1499#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001500 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1501 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001502#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001503 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001504#endif
1505}
1506
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001507static PyObject *
1508path_object_error2(PyObject *path, PyObject *path2)
1509{
1510#ifdef MS_WINDOWS
1511 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1512 PyExc_OSError, 0, path, path2);
1513#else
1514 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1515#endif
1516}
1517
1518static PyObject *
1519path_error(path_t *path)
1520{
1521 return path_object_error(path->object);
1522}
Larry Hastings31826802013-10-19 00:09:25 -07001523
Larry Hastingsb0827312014-02-09 22:05:19 -08001524static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001525posix_path_error(path_t *path)
1526{
1527 return posix_path_object_error(path->object);
1528}
1529
1530static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001531path_error2(path_t *path, path_t *path2)
1532{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001533 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001534}
1535
1536
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001537/* POSIX generic methods */
1538
Larry Hastings2f936352014-08-05 14:04:04 +10001539static int
1540fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001541{
Victor Stinner8c62be82010-05-06 00:08:46 +00001542 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001543 int *pointer = (int *)p;
1544 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001545 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001546 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001547 *pointer = fd;
1548 return 1;
1549}
1550
1551static PyObject *
1552posix_fildes_fd(int fd, int (*func)(int))
1553{
1554 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001555 int async_err = 0;
1556
1557 do {
1558 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001559 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001560 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001561 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001562 Py_END_ALLOW_THREADS
1563 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1564 if (res != 0)
1565 return (!async_err) ? posix_error() : NULL;
1566 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001567}
Guido van Rossum21142a01999-01-08 21:05:37 +00001568
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001569
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001570#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001571/* This is a reimplementation of the C library's chdir function,
1572 but one that produces Win32 errors instead of DOS error codes.
1573 chdir is essentially a wrapper around SetCurrentDirectory; however,
1574 it also needs to set "magic" environment variables indicating
1575 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001576static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001577win32_wchdir(LPCWSTR path)
1578{
Victor Stinnered537822015-12-13 21:40:26 +01001579 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001580 int result;
1581 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001582
Victor Stinner8c62be82010-05-06 00:08:46 +00001583 if(!SetCurrentDirectoryW(path))
1584 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001585 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001586 if (!result)
1587 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001588 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001589 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001590 if (!new_path) {
1591 SetLastError(ERROR_OUTOFMEMORY);
1592 return FALSE;
1593 }
1594 result = GetCurrentDirectoryW(result, new_path);
1595 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001596 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001597 return FALSE;
1598 }
1599 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001600 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1601 wcsncmp(new_path, L"//", 2) == 0);
1602 if (!is_unc_like_path) {
1603 env[1] = new_path[0];
1604 result = SetEnvironmentVariableW(env, new_path);
1605 }
Victor Stinnered537822015-12-13 21:40:26 +01001606 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001607 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001608 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001609}
1610#endif
1611
Martin v. Löwis14694662006-02-03 12:54:16 +00001612#ifdef MS_WINDOWS
1613/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1614 - time stamps are restricted to second resolution
1615 - file modification times suffer from forth-and-back conversions between
1616 UTC and local time
1617 Therefore, we implement our own stat, based on the Win32 API directly.
1618*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001619#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001620#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001621
Victor Stinner6036e442015-03-08 01:58:04 +01001622static void
Steve Dowercc16be82016-09-08 10:35:16 -07001623find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1624 BY_HANDLE_FILE_INFORMATION *info,
1625 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001626{
1627 memset(info, 0, sizeof(*info));
1628 info->dwFileAttributes = pFileData->dwFileAttributes;
1629 info->ftCreationTime = pFileData->ftCreationTime;
1630 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1631 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1632 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1633 info->nFileSizeLow = pFileData->nFileSizeLow;
1634/* info->nNumberOfLinks = 1; */
1635 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1636 *reparse_tag = pFileData->dwReserved0;
1637 else
1638 *reparse_tag = 0;
1639}
1640
Guido van Rossumd8faa362007-04-27 19:54:29 +00001641static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001642attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001643{
Victor Stinner8c62be82010-05-06 00:08:46 +00001644 HANDLE hFindFile;
1645 WIN32_FIND_DATAW FileData;
1646 hFindFile = FindFirstFileW(pszFile, &FileData);
1647 if (hFindFile == INVALID_HANDLE_VALUE)
1648 return FALSE;
1649 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001650 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001651 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001652}
1653
Brian Curtind25aef52011-06-13 15:16:04 -05001654static BOOL
1655get_target_path(HANDLE hdl, wchar_t **target_path)
1656{
1657 int buf_size, result_length;
1658 wchar_t *buf;
1659
1660 /* We have a good handle to the target, use it to determine
1661 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001662 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1663 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001664 if(!buf_size)
1665 return FALSE;
1666
Victor Stinnerc36674a2016-03-16 14:30:16 +01001667 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001668 if (!buf) {
1669 SetLastError(ERROR_OUTOFMEMORY);
1670 return FALSE;
1671 }
1672
Steve Dower2ea51c92015-03-20 21:49:12 -07001673 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001674 buf, buf_size, VOLUME_NAME_DOS);
1675
1676 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001677 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001678 return FALSE;
1679 }
1680
Brian Curtind25aef52011-06-13 15:16:04 -05001681 buf[result_length] = 0;
1682
1683 *target_path = buf;
1684 return TRUE;
1685}
1686
1687static int
Steve Dowercc16be82016-09-08 10:35:16 -07001688win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001689 BOOL traverse)
1690{
Victor Stinner26de69d2011-06-17 15:15:38 +02001691 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001692 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001693 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001694 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001695 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001696 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001697
Steve Dowercc16be82016-09-08 10:35:16 -07001698 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001699 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001700 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001701 0, /* share mode */
1702 NULL, /* security attributes */
1703 OPEN_EXISTING,
1704 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001705 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1706 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001707 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001708 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1709 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001710 NULL);
1711
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001712 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001713 /* Either the target doesn't exist, or we don't have access to
1714 get a handle to it. If the former, we need to return an error.
1715 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001716 DWORD lastError = GetLastError();
1717 if (lastError != ERROR_ACCESS_DENIED &&
1718 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001719 return -1;
1720 /* Could not get attributes on open file. Fall back to
1721 reading the directory. */
1722 if (!attributes_from_dir(path, &info, &reparse_tag))
1723 /* Very strange. This should not fail now */
1724 return -1;
1725 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1726 if (traverse) {
1727 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001728 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001729 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001730 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001731 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001732 } else {
1733 if (!GetFileInformationByHandle(hFile, &info)) {
1734 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001735 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001736 }
1737 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Mark Becwarb82bfac2019-02-02 16:08:23 -05001738 if (!win32_get_reparse_tag(hFile, &reparse_tag)) {
1739 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001740 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001741 }
Brian Curtind25aef52011-06-13 15:16:04 -05001742 /* Close the outer open file handle now that we're about to
1743 reopen it with different flags. */
1744 if (!CloseHandle(hFile))
1745 return -1;
1746
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001747 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001748 /* In order to call GetFinalPathNameByHandle we need to open
1749 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001750 hFile2 = CreateFileW(
1751 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1752 NULL, OPEN_EXISTING,
1753 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1754 NULL);
1755 if (hFile2 == INVALID_HANDLE_VALUE)
1756 return -1;
1757
Mark Becwarb82bfac2019-02-02 16:08:23 -05001758 if (!get_target_path(hFile2, &target_path)) {
1759 CloseHandle(hFile2);
Brian Curtind25aef52011-06-13 15:16:04 -05001760 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001761 }
1762
1763 if (!CloseHandle(hFile2)) {
1764 return -1;
1765 }
Brian Curtind25aef52011-06-13 15:16:04 -05001766
Steve Dowercc16be82016-09-08 10:35:16 -07001767 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001768 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001769 return code;
1770 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001771 } else
1772 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001773 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001774 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001775
1776 /* Set S_IEXEC if it is an .exe, .bat, ... */
1777 dot = wcsrchr(path, '.');
1778 if (dot) {
1779 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1780 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1781 result->st_mode |= 0111;
1782 }
1783 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001784}
1785
1786static int
Steve Dowercc16be82016-09-08 10:35:16 -07001787win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001788{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001789 /* Protocol violation: we explicitly clear errno, instead of
1790 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001791 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001792 errno = 0;
1793 return code;
1794}
Brian Curtind25aef52011-06-13 15:16:04 -05001795/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001796
1797 In Posix, stat automatically traverses symlinks and returns the stat
1798 structure for the target. In Windows, the equivalent GetFileAttributes by
1799 default does not traverse symlinks and instead returns attributes for
1800 the symlink.
1801
1802 Therefore, win32_lstat will get the attributes traditionally, and
1803 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001804 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001805
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001806static int
Steve Dowercc16be82016-09-08 10:35:16 -07001807win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001808{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001809 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001810}
1811
Victor Stinner8c62be82010-05-06 00:08:46 +00001812static int
Steve Dowercc16be82016-09-08 10:35:16 -07001813win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001814{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001815 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001816}
1817
Martin v. Löwis14694662006-02-03 12:54:16 +00001818#endif /* MS_WINDOWS */
1819
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001820PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001821"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001822This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001823 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001824or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1825\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001826Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1827or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001828\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001829See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001830
1831static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001832 {"st_mode", "protection bits"},
1833 {"st_ino", "inode"},
1834 {"st_dev", "device"},
1835 {"st_nlink", "number of hard links"},
1836 {"st_uid", "user ID of owner"},
1837 {"st_gid", "group ID of owner"},
1838 {"st_size", "total size, in bytes"},
1839 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1840 {NULL, "integer time of last access"},
1841 {NULL, "integer time of last modification"},
1842 {NULL, "integer time of last change"},
1843 {"st_atime", "time of last access"},
1844 {"st_mtime", "time of last modification"},
1845 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001846 {"st_atime_ns", "time of last access in nanoseconds"},
1847 {"st_mtime_ns", "time of last modification in nanoseconds"},
1848 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001849#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001850 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001851#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001852#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001853 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001854#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001855#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001856 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001857#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001858#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001860#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001861#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001862 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001863#endif
1864#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001865 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001866#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001867#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1868 {"st_file_attributes", "Windows file attribute bits"},
1869#endif
jcea6c51d512018-01-28 14:00:08 +01001870#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1871 {"st_fstype", "Type of filesystem"},
1872#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001873 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001874};
1875
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001876#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001877#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001878#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001879#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001880#endif
1881
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001882#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001883#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1884#else
1885#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1886#endif
1887
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001888#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001889#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1890#else
1891#define ST_RDEV_IDX ST_BLOCKS_IDX
1892#endif
1893
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001894#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1895#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1896#else
1897#define ST_FLAGS_IDX ST_RDEV_IDX
1898#endif
1899
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001900#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001901#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001902#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001903#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001904#endif
1905
1906#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1907#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1908#else
1909#define ST_BIRTHTIME_IDX ST_GEN_IDX
1910#endif
1911
Zachary Ware63f277b2014-06-19 09:46:37 -05001912#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1913#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1914#else
1915#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1916#endif
1917
jcea6c51d512018-01-28 14:00:08 +01001918#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1919#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1920#else
1921#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1922#endif
1923
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001924static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001925 "stat_result", /* name */
1926 stat_result__doc__, /* doc */
1927 stat_result_fields,
1928 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001929};
1930
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001931PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001932"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1933This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001934 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001935or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001936\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001937See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001938
1939static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001940 {"f_bsize", },
1941 {"f_frsize", },
1942 {"f_blocks", },
1943 {"f_bfree", },
1944 {"f_bavail", },
1945 {"f_files", },
1946 {"f_ffree", },
1947 {"f_favail", },
1948 {"f_flag", },
1949 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001950 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001951 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001952};
1953
1954static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 "statvfs_result", /* name */
1956 statvfs_result__doc__, /* doc */
1957 statvfs_result_fields,
1958 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001959};
1960
Ross Lagerwall7807c352011-03-17 20:20:30 +02001961#if defined(HAVE_WAITID) && !defined(__APPLE__)
1962PyDoc_STRVAR(waitid_result__doc__,
1963"waitid_result: Result from waitid.\n\n\
1964This object may be accessed either as a tuple of\n\
1965 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1966or via the attributes si_pid, si_uid, and so on.\n\
1967\n\
1968See os.waitid for more information.");
1969
1970static PyStructSequence_Field waitid_result_fields[] = {
1971 {"si_pid", },
1972 {"si_uid", },
1973 {"si_signo", },
1974 {"si_status", },
1975 {"si_code", },
1976 {0}
1977};
1978
1979static PyStructSequence_Desc waitid_result_desc = {
1980 "waitid_result", /* name */
1981 waitid_result__doc__, /* doc */
1982 waitid_result_fields,
1983 5
1984};
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001985static PyTypeObject* WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +02001986#endif
1987
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001988static int initialized;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001989static PyTypeObject* StatResultType;
1990static PyTypeObject* StatVFSResultType;
William Orr81574b82018-10-01 22:19:56 -07001991#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001992static PyTypeObject* SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001993#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001994static newfunc structseq_new;
1995
1996static PyObject *
1997statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1998{
Victor Stinner8c62be82010-05-06 00:08:46 +00001999 PyStructSequence *result;
2000 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002001
Victor Stinner8c62be82010-05-06 00:08:46 +00002002 result = (PyStructSequence*)structseq_new(type, args, kwds);
2003 if (!result)
2004 return NULL;
2005 /* If we have been initialized from a tuple,
2006 st_?time might be set to None. Initialize it
2007 from the int slots. */
2008 for (i = 7; i <= 9; i++) {
2009 if (result->ob_item[i+3] == Py_None) {
2010 Py_DECREF(Py_None);
2011 Py_INCREF(result->ob_item[i]);
2012 result->ob_item[i+3] = result->ob_item[i];
2013 }
2014 }
2015 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002016}
2017
2018
Larry Hastings6fe20b32012-04-19 15:07:49 -07002019static PyObject *billion = NULL;
2020
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002021static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002022fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002023{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002024 PyObject *s = _PyLong_FromTime_t(sec);
2025 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2026 PyObject *s_in_ns = NULL;
2027 PyObject *ns_total = NULL;
2028 PyObject *float_s = NULL;
2029
2030 if (!(s && ns_fractional))
2031 goto exit;
2032
2033 s_in_ns = PyNumber_Multiply(s, billion);
2034 if (!s_in_ns)
2035 goto exit;
2036
2037 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2038 if (!ns_total)
2039 goto exit;
2040
Victor Stinner01b5aab2017-10-24 02:02:00 -07002041 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2042 if (!float_s) {
2043 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002044 }
2045
2046 PyStructSequence_SET_ITEM(v, index, s);
2047 PyStructSequence_SET_ITEM(v, index+3, float_s);
2048 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2049 s = NULL;
2050 float_s = NULL;
2051 ns_total = NULL;
2052exit:
2053 Py_XDECREF(s);
2054 Py_XDECREF(ns_fractional);
2055 Py_XDECREF(s_in_ns);
2056 Py_XDECREF(ns_total);
2057 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002058}
2059
Tim Peters5aa91602002-01-30 05:46:57 +00002060/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002061 (used by posix_stat() and posix_fstat()) */
2062static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002063_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002064{
Victor Stinner8c62be82010-05-06 00:08:46 +00002065 unsigned long ansec, mnsec, cnsec;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002066 PyObject *v = PyStructSequence_New(StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002067 if (v == NULL)
2068 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002069
Victor Stinner8c62be82010-05-06 00:08:46 +00002070 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002071 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002072 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002073#ifdef MS_WINDOWS
2074 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002075#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002076 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002077#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002078 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002079#if defined(MS_WINDOWS)
2080 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2081 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2082#else
2083 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2084 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2085#endif
xdegaye50e86032017-05-22 11:15:08 +02002086 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2087 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002088
Martin v. Löwis14694662006-02-03 12:54:16 +00002089#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002090 ansec = st->st_atim.tv_nsec;
2091 mnsec = st->st_mtim.tv_nsec;
2092 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002093#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002094 ansec = st->st_atimespec.tv_nsec;
2095 mnsec = st->st_mtimespec.tv_nsec;
2096 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002097#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002098 ansec = st->st_atime_nsec;
2099 mnsec = st->st_mtime_nsec;
2100 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002101#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002102 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002103#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002104 fill_time(v, 7, st->st_atime, ansec);
2105 fill_time(v, 8, st->st_mtime, mnsec);
2106 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002107
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002108#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002109 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2110 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002111#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002112#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002113 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2114 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002115#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002116#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002117 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2118 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002119#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002120#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002121 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2122 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002123#endif
2124#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002125 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002126 PyObject *val;
2127 unsigned long bsec,bnsec;
2128 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002129#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002130 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002131#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002132 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002133#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002134 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002135 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2136 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002137 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002138#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002139#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2141 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002142#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002143#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2144 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2145 PyLong_FromUnsignedLong(st->st_file_attributes));
2146#endif
jcea6c51d512018-01-28 14:00:08 +01002147#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2148 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2149 PyUnicode_FromString(st->st_fstype));
2150#endif
Fred Drake699f3522000-06-29 21:12:41 +00002151
Victor Stinner8c62be82010-05-06 00:08:46 +00002152 if (PyErr_Occurred()) {
2153 Py_DECREF(v);
2154 return NULL;
2155 }
Fred Drake699f3522000-06-29 21:12:41 +00002156
Victor Stinner8c62be82010-05-06 00:08:46 +00002157 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002158}
2159
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002160/* POSIX methods */
2161
Guido van Rossum94f6f721999-01-06 18:42:14 +00002162
2163static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002164posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002165 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002166{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002167 STRUCT_STAT st;
2168 int result;
2169
2170#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2171 if (follow_symlinks_specified(function_name, follow_symlinks))
2172 return NULL;
2173#endif
2174
2175 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2176 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2177 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2178 return NULL;
2179
2180 Py_BEGIN_ALLOW_THREADS
2181 if (path->fd != -1)
2182 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002183#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002184 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002185 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002186 else
Steve Dowercc16be82016-09-08 10:35:16 -07002187 result = win32_lstat(path->wide, &st);
2188#else
2189 else
2190#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002191 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2192 result = LSTAT(path->narrow, &st);
2193 else
Steve Dowercc16be82016-09-08 10:35:16 -07002194#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002195#ifdef HAVE_FSTATAT
2196 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2197 result = fstatat(dir_fd, path->narrow, &st,
2198 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2199 else
Steve Dowercc16be82016-09-08 10:35:16 -07002200#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002201 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002202#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002203 Py_END_ALLOW_THREADS
2204
Victor Stinner292c8352012-10-30 02:17:38 +01002205 if (result != 0) {
2206 return path_error(path);
2207 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002208
2209 return _pystat_fromstructstat(&st);
2210}
2211
Larry Hastings2f936352014-08-05 14:04:04 +10002212/*[python input]
2213
2214for s in """
2215
2216FACCESSAT
2217FCHMODAT
2218FCHOWNAT
2219FSTATAT
2220LINKAT
2221MKDIRAT
2222MKFIFOAT
2223MKNODAT
2224OPENAT
2225READLINKAT
2226SYMLINKAT
2227UNLINKAT
2228
2229""".strip().split():
2230 s = s.strip()
2231 print("""
2232#ifdef HAVE_{s}
2233 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002234#else
Larry Hastings2f936352014-08-05 14:04:04 +10002235 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002236#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002237""".rstrip().format(s=s))
2238
2239for s in """
2240
2241FCHDIR
2242FCHMOD
2243FCHOWN
2244FDOPENDIR
2245FEXECVE
2246FPATHCONF
2247FSTATVFS
2248FTRUNCATE
2249
2250""".strip().split():
2251 s = s.strip()
2252 print("""
2253#ifdef HAVE_{s}
2254 #define PATH_HAVE_{s} 1
2255#else
2256 #define PATH_HAVE_{s} 0
2257#endif
2258
2259""".rstrip().format(s=s))
2260[python start generated code]*/
2261
2262#ifdef HAVE_FACCESSAT
2263 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2264#else
2265 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2266#endif
2267
2268#ifdef HAVE_FCHMODAT
2269 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2270#else
2271 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2272#endif
2273
2274#ifdef HAVE_FCHOWNAT
2275 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2276#else
2277 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2278#endif
2279
2280#ifdef HAVE_FSTATAT
2281 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2282#else
2283 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2284#endif
2285
2286#ifdef HAVE_LINKAT
2287 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2288#else
2289 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2290#endif
2291
2292#ifdef HAVE_MKDIRAT
2293 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2294#else
2295 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2296#endif
2297
2298#ifdef HAVE_MKFIFOAT
2299 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2300#else
2301 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2302#endif
2303
2304#ifdef HAVE_MKNODAT
2305 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2306#else
2307 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2308#endif
2309
2310#ifdef HAVE_OPENAT
2311 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2312#else
2313 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2314#endif
2315
2316#ifdef HAVE_READLINKAT
2317 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2318#else
2319 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2320#endif
2321
2322#ifdef HAVE_SYMLINKAT
2323 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2324#else
2325 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2326#endif
2327
2328#ifdef HAVE_UNLINKAT
2329 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2330#else
2331 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2332#endif
2333
2334#ifdef HAVE_FCHDIR
2335 #define PATH_HAVE_FCHDIR 1
2336#else
2337 #define PATH_HAVE_FCHDIR 0
2338#endif
2339
2340#ifdef HAVE_FCHMOD
2341 #define PATH_HAVE_FCHMOD 1
2342#else
2343 #define PATH_HAVE_FCHMOD 0
2344#endif
2345
2346#ifdef HAVE_FCHOWN
2347 #define PATH_HAVE_FCHOWN 1
2348#else
2349 #define PATH_HAVE_FCHOWN 0
2350#endif
2351
2352#ifdef HAVE_FDOPENDIR
2353 #define PATH_HAVE_FDOPENDIR 1
2354#else
2355 #define PATH_HAVE_FDOPENDIR 0
2356#endif
2357
2358#ifdef HAVE_FEXECVE
2359 #define PATH_HAVE_FEXECVE 1
2360#else
2361 #define PATH_HAVE_FEXECVE 0
2362#endif
2363
2364#ifdef HAVE_FPATHCONF
2365 #define PATH_HAVE_FPATHCONF 1
2366#else
2367 #define PATH_HAVE_FPATHCONF 0
2368#endif
2369
2370#ifdef HAVE_FSTATVFS
2371 #define PATH_HAVE_FSTATVFS 1
2372#else
2373 #define PATH_HAVE_FSTATVFS 0
2374#endif
2375
2376#ifdef HAVE_FTRUNCATE
2377 #define PATH_HAVE_FTRUNCATE 1
2378#else
2379 #define PATH_HAVE_FTRUNCATE 0
2380#endif
2381/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002382
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002383#ifdef MS_WINDOWS
2384 #undef PATH_HAVE_FTRUNCATE
2385 #define PATH_HAVE_FTRUNCATE 1
2386#endif
Larry Hastings31826802013-10-19 00:09:25 -07002387
Larry Hastings61272b72014-01-07 12:41:53 -08002388/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002389
2390class path_t_converter(CConverter):
2391
2392 type = "path_t"
2393 impl_by_reference = True
2394 parse_by_reference = True
2395
2396 converter = 'path_converter'
2397
2398 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002399 # right now path_t doesn't support default values.
2400 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002401 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002402 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002403
Larry Hastings2f936352014-08-05 14:04:04 +10002404 if self.c_default not in (None, 'Py_None'):
2405 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002406
2407 self.nullable = nullable
2408 self.allow_fd = allow_fd
2409
Larry Hastings7726ac92014-01-31 22:03:12 -08002410 def pre_render(self):
2411 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002412 if isinstance(value, str):
2413 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002414 return str(int(bool(value)))
2415
2416 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002417 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002418 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002419 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002420 strify(self.nullable),
2421 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002422 )
2423
2424 def cleanup(self):
2425 return "path_cleanup(&" + self.name + ");\n"
2426
2427
2428class dir_fd_converter(CConverter):
2429 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002430
Larry Hastings2f936352014-08-05 14:04:04 +10002431 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002432 if self.default in (unspecified, None):
2433 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002434 if isinstance(requires, str):
2435 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2436 else:
2437 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002438
Larry Hastings2f936352014-08-05 14:04:04 +10002439class fildes_converter(CConverter):
2440 type = 'int'
2441 converter = 'fildes_converter'
2442
2443class uid_t_converter(CConverter):
2444 type = "uid_t"
2445 converter = '_Py_Uid_Converter'
2446
2447class gid_t_converter(CConverter):
2448 type = "gid_t"
2449 converter = '_Py_Gid_Converter'
2450
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002451class dev_t_converter(CConverter):
2452 type = 'dev_t'
2453 converter = '_Py_Dev_Converter'
2454
2455class dev_t_return_converter(unsigned_long_return_converter):
2456 type = 'dev_t'
2457 conversion_fn = '_PyLong_FromDev'
2458 unsigned_cast = '(dev_t)'
2459
Larry Hastings2f936352014-08-05 14:04:04 +10002460class FSConverter_converter(CConverter):
2461 type = 'PyObject *'
2462 converter = 'PyUnicode_FSConverter'
2463 def converter_init(self):
2464 if self.default is not unspecified:
2465 fail("FSConverter_converter does not support default values")
2466 self.c_default = 'NULL'
2467
2468 def cleanup(self):
2469 return "Py_XDECREF(" + self.name + ");\n"
2470
2471class pid_t_converter(CConverter):
2472 type = 'pid_t'
2473 format_unit = '" _Py_PARSE_PID "'
2474
2475class idtype_t_converter(int_converter):
2476 type = 'idtype_t'
2477
2478class id_t_converter(CConverter):
2479 type = 'id_t'
2480 format_unit = '" _Py_PARSE_PID "'
2481
Benjamin Petersonca470632016-09-06 13:47:26 -07002482class intptr_t_converter(CConverter):
2483 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002484 format_unit = '" _Py_PARSE_INTPTR "'
2485
2486class Py_off_t_converter(CConverter):
2487 type = 'Py_off_t'
2488 converter = 'Py_off_t_converter'
2489
2490class Py_off_t_return_converter(long_return_converter):
2491 type = 'Py_off_t'
2492 conversion_fn = 'PyLong_FromPy_off_t'
2493
2494class path_confname_converter(CConverter):
2495 type="int"
2496 converter="conv_path_confname"
2497
2498class confstr_confname_converter(path_confname_converter):
2499 converter='conv_confstr_confname'
2500
2501class sysconf_confname_converter(path_confname_converter):
2502 converter="conv_sysconf_confname"
2503
2504class sched_param_converter(CConverter):
2505 type = 'struct sched_param'
2506 converter = 'convert_sched_param'
2507 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002508
Larry Hastings61272b72014-01-07 12:41:53 -08002509[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002510/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002511
Larry Hastings61272b72014-01-07 12:41:53 -08002512/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002513
Larry Hastings2a727912014-01-16 11:32:01 -08002514os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002515
2516 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002517 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002518 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002519
2520 *
2521
Larry Hastings2f936352014-08-05 14:04:04 +10002522 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002523 If not None, it should be a file descriptor open to a directory,
2524 and path should be a relative string; path will then be relative to
2525 that directory.
2526
2527 follow_symlinks: bool = True
2528 If False, and the last element of the path is a symbolic link,
2529 stat will examine the symbolic link itself instead of the file
2530 the link points to.
2531
2532Perform a stat system call on the given path.
2533
2534dir_fd and follow_symlinks may not be implemented
2535 on your platform. If they are unavailable, using them will raise a
2536 NotImplementedError.
2537
2538It's an error to use dir_fd or follow_symlinks when specifying path as
2539 an open file descriptor.
2540
Larry Hastings61272b72014-01-07 12:41:53 -08002541[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002542
Larry Hastings31826802013-10-19 00:09:25 -07002543static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002544os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002545/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002546{
2547 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2548}
2549
Larry Hastings2f936352014-08-05 14:04:04 +10002550
2551/*[clinic input]
2552os.lstat
2553
2554 path : path_t
2555
2556 *
2557
2558 dir_fd : dir_fd(requires='fstatat') = None
2559
2560Perform a stat system call on the given path, without following symbolic links.
2561
2562Like stat(), but do not follow symbolic links.
2563Equivalent to stat(path, follow_symlinks=False).
2564[clinic start generated code]*/
2565
Larry Hastings2f936352014-08-05 14:04:04 +10002566static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002567os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2568/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002569{
2570 int follow_symlinks = 0;
2571 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2572}
Larry Hastings31826802013-10-19 00:09:25 -07002573
Larry Hastings2f936352014-08-05 14:04:04 +10002574
Larry Hastings61272b72014-01-07 12:41:53 -08002575/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002576os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002577
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002578 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002579 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002580
2581 mode: int
2582 Operating-system mode bitfield. Can be F_OK to test existence,
2583 or the inclusive-OR of R_OK, W_OK, and X_OK.
2584
2585 *
2586
Larry Hastings2f936352014-08-05 14:04:04 +10002587 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002588 If not None, it should be a file descriptor open to a directory,
2589 and path should be relative; path will then be relative to that
2590 directory.
2591
2592 effective_ids: bool = False
2593 If True, access will use the effective uid/gid instead of
2594 the real uid/gid.
2595
2596 follow_symlinks: bool = True
2597 If False, and the last element of the path is a symbolic link,
2598 access will examine the symbolic link itself instead of the file
2599 the link points to.
2600
2601Use the real uid/gid to test for access to a path.
2602
2603{parameters}
2604dir_fd, effective_ids, and follow_symlinks may not be implemented
2605 on your platform. If they are unavailable, using them will raise a
2606 NotImplementedError.
2607
2608Note that most operations will use the effective uid/gid, therefore this
2609 routine can be used in a suid/sgid environment to test if the invoking user
2610 has the specified access to the path.
2611
Larry Hastings61272b72014-01-07 12:41:53 -08002612[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002613
Larry Hastings2f936352014-08-05 14:04:04 +10002614static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002615os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002616 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002617/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002618{
Larry Hastings2f936352014-08-05 14:04:04 +10002619 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002620
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002621#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002622 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002623#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002624 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002625#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002626
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627#ifndef HAVE_FACCESSAT
2628 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002629 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002630
2631 if (effective_ids) {
2632 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002633 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002634 }
2635#endif
2636
2637#ifdef MS_WINDOWS
2638 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002639 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002640 Py_END_ALLOW_THREADS
2641
2642 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002643 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002644 * * we didn't get a -1, and
2645 * * write access wasn't requested,
2646 * * or the file isn't read-only,
2647 * * or it's a directory.
2648 * (Directories cannot be read-only on Windows.)
2649 */
Larry Hastings2f936352014-08-05 14:04:04 +10002650 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002651 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002652 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002653 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002654#else
2655
2656 Py_BEGIN_ALLOW_THREADS
2657#ifdef HAVE_FACCESSAT
2658 if ((dir_fd != DEFAULT_DIR_FD) ||
2659 effective_ids ||
2660 !follow_symlinks) {
2661 int flags = 0;
2662 if (!follow_symlinks)
2663 flags |= AT_SYMLINK_NOFOLLOW;
2664 if (effective_ids)
2665 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002666 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002667 }
2668 else
2669#endif
Larry Hastings31826802013-10-19 00:09:25 -07002670 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002671 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002672 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002673#endif
2674
Larry Hastings9cf065c2012-06-22 16:30:09 -07002675 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002676}
2677
Guido van Rossumd371ff11999-01-25 16:12:23 +00002678#ifndef F_OK
2679#define F_OK 0
2680#endif
2681#ifndef R_OK
2682#define R_OK 4
2683#endif
2684#ifndef W_OK
2685#define W_OK 2
2686#endif
2687#ifndef X_OK
2688#define X_OK 1
2689#endif
2690
Larry Hastings31826802013-10-19 00:09:25 -07002691
Guido van Rossumd371ff11999-01-25 16:12:23 +00002692#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002693/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002694os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002695
2696 fd: int
2697 Integer file descriptor handle.
2698
2699 /
2700
2701Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002702[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002703
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002704static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002705os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002706/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002707{
2708 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002709
Larry Hastings31826802013-10-19 00:09:25 -07002710 ret = ttyname(fd);
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002711 if (ret == NULL) {
2712 return posix_error();
2713 }
2714 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002715}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002716#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002717
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002718#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002719/*[clinic input]
2720os.ctermid
2721
2722Return the name of the controlling terminal for this process.
2723[clinic start generated code]*/
2724
Larry Hastings2f936352014-08-05 14:04:04 +10002725static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002726os_ctermid_impl(PyObject *module)
2727/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002728{
Victor Stinner8c62be82010-05-06 00:08:46 +00002729 char *ret;
2730 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002731
Greg Wardb48bc172000-03-01 21:51:56 +00002732#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002733 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002734#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002735 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002736#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002737 if (ret == NULL)
2738 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002739 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002740}
Larry Hastings2f936352014-08-05 14:04:04 +10002741#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002742
Larry Hastings2f936352014-08-05 14:04:04 +10002743
2744/*[clinic input]
2745os.chdir
2746
2747 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2748
2749Change the current working directory to the specified path.
2750
2751path may always be specified as a string.
2752On some platforms, path may also be specified as an open file descriptor.
2753 If this functionality is unavailable, using it raises an exception.
2754[clinic start generated code]*/
2755
Larry Hastings2f936352014-08-05 14:04:04 +10002756static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002757os_chdir_impl(PyObject *module, path_t *path)
2758/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002759{
2760 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002761
2762 Py_BEGIN_ALLOW_THREADS
2763#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002764 /* on unix, success = 0, on windows, success = !0 */
2765 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002766#else
2767#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002768 if (path->fd != -1)
2769 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002770 else
2771#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002772 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002773#endif
2774 Py_END_ALLOW_THREADS
2775
2776 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002777 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002778 }
2779
Larry Hastings2f936352014-08-05 14:04:04 +10002780 Py_RETURN_NONE;
2781}
2782
2783
2784#ifdef HAVE_FCHDIR
2785/*[clinic input]
2786os.fchdir
2787
2788 fd: fildes
2789
2790Change to the directory of the given file descriptor.
2791
2792fd must be opened on a directory, not a file.
2793Equivalent to os.chdir(fd).
2794
2795[clinic start generated code]*/
2796
Fred Drake4d1e64b2002-04-15 19:40:07 +00002797static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002798os_fchdir_impl(PyObject *module, int fd)
2799/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002800{
Larry Hastings2f936352014-08-05 14:04:04 +10002801 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002802}
2803#endif /* HAVE_FCHDIR */
2804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002805
Larry Hastings2f936352014-08-05 14:04:04 +10002806/*[clinic input]
2807os.chmod
2808
2809 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002810 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002811 On some platforms, path may also be specified as an open file descriptor.
2812 If this functionality is unavailable, using it raises an exception.
2813
2814 mode: int
2815 Operating-system mode bitfield.
2816
2817 *
2818
2819 dir_fd : dir_fd(requires='fchmodat') = None
2820 If not None, it should be a file descriptor open to a directory,
2821 and path should be relative; path will then be relative to that
2822 directory.
2823
2824 follow_symlinks: bool = True
2825 If False, and the last element of the path is a symbolic link,
2826 chmod will modify the symbolic link itself instead of the file
2827 the link points to.
2828
2829Change the access permissions of a file.
2830
2831It is an error to use dir_fd or follow_symlinks when specifying path as
2832 an open file descriptor.
2833dir_fd and follow_symlinks may not be implemented on your platform.
2834 If they are unavailable, using them will raise a NotImplementedError.
2835
2836[clinic start generated code]*/
2837
Larry Hastings2f936352014-08-05 14:04:04 +10002838static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002839os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002840 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002841/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002842{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002843 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002845#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002846 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002847#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002848
Larry Hastings9cf065c2012-06-22 16:30:09 -07002849#ifdef HAVE_FCHMODAT
2850 int fchmodat_nofollow_unsupported = 0;
2851#endif
2852
Larry Hastings9cf065c2012-06-22 16:30:09 -07002853#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2854 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002855 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002856#endif
2857
2858#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002859 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002860 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002861 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002862 result = 0;
2863 else {
2864 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002865 attr &= ~FILE_ATTRIBUTE_READONLY;
2866 else
2867 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002868 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002869 }
2870 Py_END_ALLOW_THREADS
2871
2872 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002873 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002874 }
2875#else /* MS_WINDOWS */
2876 Py_BEGIN_ALLOW_THREADS
2877#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002878 if (path->fd != -1)
2879 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002880 else
2881#endif
2882#ifdef HAVE_LCHMOD
2883 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002884 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002885 else
2886#endif
2887#ifdef HAVE_FCHMODAT
2888 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2889 /*
2890 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2891 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002892 * and then says it isn't implemented yet.
2893 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002894 *
2895 * Once it is supported, os.chmod will automatically
2896 * support dir_fd and follow_symlinks=False. (Hopefully.)
2897 * Until then, we need to be careful what exception we raise.
2898 */
Larry Hastings2f936352014-08-05 14:04:04 +10002899 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002900 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2901 /*
2902 * But wait! We can't throw the exception without allowing threads,
2903 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2904 */
2905 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002906 result &&
2907 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2908 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002909 }
2910 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002911#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002912 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002913 Py_END_ALLOW_THREADS
2914
2915 if (result) {
2916#ifdef HAVE_FCHMODAT
2917 if (fchmodat_nofollow_unsupported) {
2918 if (dir_fd != DEFAULT_DIR_FD)
2919 dir_fd_and_follow_symlinks_invalid("chmod",
2920 dir_fd, follow_symlinks);
2921 else
2922 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002923 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002924 }
2925 else
2926#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002927 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002928 }
2929#endif
2930
Larry Hastings2f936352014-08-05 14:04:04 +10002931 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002932}
2933
Larry Hastings9cf065c2012-06-22 16:30:09 -07002934
Christian Heimes4e30a842007-11-30 22:12:06 +00002935#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002936/*[clinic input]
2937os.fchmod
2938
2939 fd: int
2940 mode: int
2941
2942Change the access permissions of the file given by file descriptor fd.
2943
2944Equivalent to os.chmod(fd, mode).
2945[clinic start generated code]*/
2946
Larry Hastings2f936352014-08-05 14:04:04 +10002947static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002948os_fchmod_impl(PyObject *module, int fd, int mode)
2949/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002950{
2951 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002952 int async_err = 0;
2953
2954 do {
2955 Py_BEGIN_ALLOW_THREADS
2956 res = fchmod(fd, mode);
2957 Py_END_ALLOW_THREADS
2958 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2959 if (res != 0)
2960 return (!async_err) ? posix_error() : NULL;
2961
Victor Stinner8c62be82010-05-06 00:08:46 +00002962 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002963}
2964#endif /* HAVE_FCHMOD */
2965
Larry Hastings2f936352014-08-05 14:04:04 +10002966
Christian Heimes4e30a842007-11-30 22:12:06 +00002967#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002968/*[clinic input]
2969os.lchmod
2970
2971 path: path_t
2972 mode: int
2973
2974Change the access permissions of a file, without following symbolic links.
2975
2976If path is a symlink, this affects the link itself rather than the target.
2977Equivalent to chmod(path, mode, follow_symlinks=False)."
2978[clinic start generated code]*/
2979
Larry Hastings2f936352014-08-05 14:04:04 +10002980static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002981os_lchmod_impl(PyObject *module, path_t *path, int mode)
2982/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002983{
Victor Stinner8c62be82010-05-06 00:08:46 +00002984 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002985 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002986 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002987 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002988 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002989 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002990 return NULL;
2991 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002992 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002993}
2994#endif /* HAVE_LCHMOD */
2995
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002996
Thomas Wouterscf297e42007-02-23 15:07:44 +00002997#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002998/*[clinic input]
2999os.chflags
3000
3001 path: path_t
3002 flags: unsigned_long(bitwise=True)
3003 follow_symlinks: bool=True
3004
3005Set file flags.
3006
3007If follow_symlinks is False, and the last element of the path is a symbolic
3008 link, chflags will change flags on the symbolic link itself instead of the
3009 file the link points to.
3010follow_symlinks may not be implemented on your platform. If it is
3011unavailable, using it will raise a NotImplementedError.
3012
3013[clinic start generated code]*/
3014
Larry Hastings2f936352014-08-05 14:04:04 +10003015static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003016os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003017 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003018/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003019{
3020 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003021
3022#ifndef HAVE_LCHFLAGS
3023 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003024 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003025#endif
3026
Victor Stinner8c62be82010-05-06 00:08:46 +00003027 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003028#ifdef HAVE_LCHFLAGS
3029 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003030 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003031 else
3032#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003033 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003034 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003035
Larry Hastings2f936352014-08-05 14:04:04 +10003036 if (result)
3037 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003038
Larry Hastings2f936352014-08-05 14:04:04 +10003039 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003040}
3041#endif /* HAVE_CHFLAGS */
3042
Larry Hastings2f936352014-08-05 14:04:04 +10003043
Thomas Wouterscf297e42007-02-23 15:07:44 +00003044#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003045/*[clinic input]
3046os.lchflags
3047
3048 path: path_t
3049 flags: unsigned_long(bitwise=True)
3050
3051Set file flags.
3052
3053This function will not follow symbolic links.
3054Equivalent to chflags(path, flags, follow_symlinks=False).
3055[clinic start generated code]*/
3056
Larry Hastings2f936352014-08-05 14:04:04 +10003057static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003058os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3059/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003060{
Victor Stinner8c62be82010-05-06 00:08:46 +00003061 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003062 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003063 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003064 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003065 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003066 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003067 }
Victor Stinner292c8352012-10-30 02:17:38 +01003068 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003069}
3070#endif /* HAVE_LCHFLAGS */
3071
Larry Hastings2f936352014-08-05 14:04:04 +10003072
Martin v. Löwis244edc82001-10-04 22:44:26 +00003073#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003074/*[clinic input]
3075os.chroot
3076 path: path_t
3077
3078Change root directory to path.
3079
3080[clinic start generated code]*/
3081
Larry Hastings2f936352014-08-05 14:04:04 +10003082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003083os_chroot_impl(PyObject *module, path_t *path)
3084/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003085{
3086 int res;
3087 Py_BEGIN_ALLOW_THREADS
3088 res = chroot(path->narrow);
3089 Py_END_ALLOW_THREADS
3090 if (res < 0)
3091 return path_error(path);
3092 Py_RETURN_NONE;
3093}
3094#endif /* HAVE_CHROOT */
3095
Martin v. Löwis244edc82001-10-04 22:44:26 +00003096
Guido van Rossum21142a01999-01-08 21:05:37 +00003097#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003098/*[clinic input]
3099os.fsync
3100
3101 fd: fildes
3102
3103Force write of fd to disk.
3104[clinic start generated code]*/
3105
Larry Hastings2f936352014-08-05 14:04:04 +10003106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003107os_fsync_impl(PyObject *module, int fd)
3108/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003109{
3110 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003111}
3112#endif /* HAVE_FSYNC */
3113
Larry Hastings2f936352014-08-05 14:04:04 +10003114
Ross Lagerwall7807c352011-03-17 20:20:30 +02003115#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003116/*[clinic input]
3117os.sync
3118
3119Force write of everything to disk.
3120[clinic start generated code]*/
3121
Larry Hastings2f936352014-08-05 14:04:04 +10003122static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003123os_sync_impl(PyObject *module)
3124/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003125{
3126 Py_BEGIN_ALLOW_THREADS
3127 sync();
3128 Py_END_ALLOW_THREADS
3129 Py_RETURN_NONE;
3130}
Larry Hastings2f936352014-08-05 14:04:04 +10003131#endif /* HAVE_SYNC */
3132
Ross Lagerwall7807c352011-03-17 20:20:30 +02003133
Guido van Rossum21142a01999-01-08 21:05:37 +00003134#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003135#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003136extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3137#endif
3138
Larry Hastings2f936352014-08-05 14:04:04 +10003139/*[clinic input]
3140os.fdatasync
3141
3142 fd: fildes
3143
3144Force write of fd to disk without forcing update of metadata.
3145[clinic start generated code]*/
3146
Larry Hastings2f936352014-08-05 14:04:04 +10003147static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003148os_fdatasync_impl(PyObject *module, int fd)
3149/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003150{
3151 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003152}
3153#endif /* HAVE_FDATASYNC */
3154
3155
Fredrik Lundh10723342000-07-10 16:38:09 +00003156#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003157/*[clinic input]
3158os.chown
3159
3160 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003161 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003162
3163 uid: uid_t
3164
3165 gid: gid_t
3166
3167 *
3168
3169 dir_fd : dir_fd(requires='fchownat') = None
3170 If not None, it should be a file descriptor open to a directory,
3171 and path should be relative; path will then be relative to that
3172 directory.
3173
3174 follow_symlinks: bool = True
3175 If False, and the last element of the path is a symbolic link,
3176 stat will examine the symbolic link itself instead of the file
3177 the link points to.
3178
3179Change the owner and group id of path to the numeric uid and gid.\
3180
3181path may always be specified as a string.
3182On some platforms, path may also be specified as an open file descriptor.
3183 If this functionality is unavailable, using it raises an exception.
3184If dir_fd is not None, it should be a file descriptor open to a directory,
3185 and path should be relative; path will then be relative to that directory.
3186If follow_symlinks is False, and the last element of the path is a symbolic
3187 link, chown will modify the symbolic link itself instead of the file the
3188 link points to.
3189It is an error to use dir_fd or follow_symlinks when specifying path as
3190 an open file descriptor.
3191dir_fd and follow_symlinks may not be implemented on your platform.
3192 If they are unavailable, using them will raise a NotImplementedError.
3193
3194[clinic start generated code]*/
3195
Larry Hastings2f936352014-08-05 14:04:04 +10003196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003197os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003198 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003199/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003200{
3201 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003202
3203#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3204 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003205 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003206#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003207 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3208 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3209 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003210
3211#ifdef __APPLE__
3212 /*
3213 * This is for Mac OS X 10.3, which doesn't have lchown.
3214 * (But we still have an lchown symbol because of weak-linking.)
3215 * It doesn't have fchownat either. So there's no possibility
3216 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003217 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003218 if ((!follow_symlinks) && (lchown == NULL)) {
3219 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003220 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003221 }
3222#endif
3223
Victor Stinner8c62be82010-05-06 00:08:46 +00003224 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003225#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003226 if (path->fd != -1)
3227 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003228 else
3229#endif
3230#ifdef HAVE_LCHOWN
3231 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003232 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003233 else
3234#endif
3235#ifdef HAVE_FCHOWNAT
3236 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003237 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003238 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3239 else
3240#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003241 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003242 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003243
Larry Hastings2f936352014-08-05 14:04:04 +10003244 if (result)
3245 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003246
Larry Hastings2f936352014-08-05 14:04:04 +10003247 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003248}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003249#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003250
Larry Hastings2f936352014-08-05 14:04:04 +10003251
Christian Heimes4e30a842007-11-30 22:12:06 +00003252#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003253/*[clinic input]
3254os.fchown
3255
3256 fd: int
3257 uid: uid_t
3258 gid: gid_t
3259
3260Change the owner and group id of the file specified by file descriptor.
3261
3262Equivalent to os.chown(fd, uid, gid).
3263
3264[clinic start generated code]*/
3265
Larry Hastings2f936352014-08-05 14:04:04 +10003266static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003267os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3268/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003269{
Victor Stinner8c62be82010-05-06 00:08:46 +00003270 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003271 int async_err = 0;
3272
3273 do {
3274 Py_BEGIN_ALLOW_THREADS
3275 res = fchown(fd, uid, gid);
3276 Py_END_ALLOW_THREADS
3277 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3278 if (res != 0)
3279 return (!async_err) ? posix_error() : NULL;
3280
Victor Stinner8c62be82010-05-06 00:08:46 +00003281 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003282}
3283#endif /* HAVE_FCHOWN */
3284
Larry Hastings2f936352014-08-05 14:04:04 +10003285
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003286#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003287/*[clinic input]
3288os.lchown
3289
3290 path : path_t
3291 uid: uid_t
3292 gid: gid_t
3293
3294Change the owner and group id of path to the numeric uid and gid.
3295
3296This function will not follow symbolic links.
3297Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3298[clinic start generated code]*/
3299
Larry Hastings2f936352014-08-05 14:04:04 +10003300static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003301os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3302/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003303{
Victor Stinner8c62be82010-05-06 00:08:46 +00003304 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003305 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003306 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003307 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003308 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003309 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003310 }
Larry Hastings2f936352014-08-05 14:04:04 +10003311 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003312}
3313#endif /* HAVE_LCHOWN */
3314
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003315
Barry Warsaw53699e91996-12-10 23:23:01 +00003316static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003317posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003318{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003319 char *buf, *tmpbuf;
3320 char *cwd;
3321 const size_t chunk = 1024;
3322 size_t buflen = 0;
3323 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003324
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003325#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003326 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003327 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003328 wchar_t *wbuf2 = wbuf;
3329 PyObject *resobj;
3330 DWORD len;
3331 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003332 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003333 /* If the buffer is large enough, len does not include the
3334 terminating \0. If the buffer is too small, len includes
3335 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003336 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003337 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003338 if (wbuf2)
3339 len = GetCurrentDirectoryW(len, wbuf2);
3340 }
3341 Py_END_ALLOW_THREADS
3342 if (!wbuf2) {
3343 PyErr_NoMemory();
3344 return NULL;
3345 }
3346 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003347 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003348 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003349 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003350 }
3351 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003352 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003353 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 return resobj;
3355 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003356
3357 if (win32_warn_bytes_api())
3358 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003359#endif
3360
Victor Stinner4403d7d2015-04-25 00:16:10 +02003361 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003363 do {
3364 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003365#ifdef MS_WINDOWS
3366 if (buflen > INT_MAX) {
3367 PyErr_NoMemory();
3368 break;
3369 }
3370#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003371 tmpbuf = PyMem_RawRealloc(buf, buflen);
3372 if (tmpbuf == NULL)
3373 break;
3374
3375 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003376#ifdef MS_WINDOWS
3377 cwd = getcwd(buf, (int)buflen);
3378#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003379 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003380#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003381 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003382 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003383
3384 if (cwd == NULL) {
3385 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003386 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003387 }
3388
Victor Stinner8c62be82010-05-06 00:08:46 +00003389 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003390 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3391 else
3392 obj = PyUnicode_DecodeFSDefault(buf);
3393 PyMem_RawFree(buf);
3394
3395 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003396}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003397
Larry Hastings2f936352014-08-05 14:04:04 +10003398
3399/*[clinic input]
3400os.getcwd
3401
3402Return a unicode string representing the current working directory.
3403[clinic start generated code]*/
3404
Larry Hastings2f936352014-08-05 14:04:04 +10003405static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003406os_getcwd_impl(PyObject *module)
3407/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003408{
3409 return posix_getcwd(0);
3410}
3411
Larry Hastings2f936352014-08-05 14:04:04 +10003412
3413/*[clinic input]
3414os.getcwdb
3415
3416Return a bytes string representing the current working directory.
3417[clinic start generated code]*/
3418
Larry Hastings2f936352014-08-05 14:04:04 +10003419static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003420os_getcwdb_impl(PyObject *module)
3421/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003422{
3423 return posix_getcwd(1);
3424}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003425
Larry Hastings2f936352014-08-05 14:04:04 +10003426
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3428#define HAVE_LINK 1
3429#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003430
Guido van Rossumb6775db1994-08-01 11:34:53 +00003431#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003432/*[clinic input]
3433
3434os.link
3435
3436 src : path_t
3437 dst : path_t
3438 *
3439 src_dir_fd : dir_fd = None
3440 dst_dir_fd : dir_fd = None
3441 follow_symlinks: bool = True
3442
3443Create a hard link to a file.
3444
3445If either src_dir_fd or dst_dir_fd is not None, it should be a file
3446 descriptor open to a directory, and the respective path string (src or dst)
3447 should be relative; the path will then be relative to that directory.
3448If follow_symlinks is False, and the last element of src is a symbolic
3449 link, link will create a link to the symbolic link itself instead of the
3450 file the link points to.
3451src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3452 platform. If they are unavailable, using them will raise a
3453 NotImplementedError.
3454[clinic start generated code]*/
3455
Larry Hastings2f936352014-08-05 14:04:04 +10003456static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003457os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003458 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003459/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003460{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003462 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463#else
3464 int result;
3465#endif
3466
Larry Hastings9cf065c2012-06-22 16:30:09 -07003467#ifndef HAVE_LINKAT
3468 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3469 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003470 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 }
3472#endif
3473
Steve Dowercc16be82016-09-08 10:35:16 -07003474#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003475 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476 PyErr_SetString(PyExc_NotImplementedError,
3477 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003478 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479 }
Steve Dowercc16be82016-09-08 10:35:16 -07003480#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003481
Brian Curtin1b9df392010-11-24 20:24:31 +00003482#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003484 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003485 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003486
Larry Hastings2f936352014-08-05 14:04:04 +10003487 if (!result)
3488 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489#else
3490 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003491#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003492 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3493 (dst_dir_fd != DEFAULT_DIR_FD) ||
3494 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003495 result = linkat(src_dir_fd, src->narrow,
3496 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3498 else
Steve Dowercc16be82016-09-08 10:35:16 -07003499#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003500 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003502
Larry Hastings2f936352014-08-05 14:04:04 +10003503 if (result)
3504 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003505#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506
Larry Hastings2f936352014-08-05 14:04:04 +10003507 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003508}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003509#endif
3510
Brian Curtin1b9df392010-11-24 20:24:31 +00003511
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003512#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003513static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003514_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003515{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516 PyObject *v;
3517 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3518 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003519 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003521 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003522 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003523
Steve Dowercc16be82016-09-08 10:35:16 -07003524 WIN32_FIND_DATAW wFileData;
3525 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003526
Steve Dowercc16be82016-09-08 10:35:16 -07003527 if (!path->wide) { /* Default arg: "." */
3528 po_wchars = L".";
3529 len = 1;
3530 } else {
3531 po_wchars = path->wide;
3532 len = wcslen(path->wide);
3533 }
3534 /* The +5 is so we can append "\\*.*\0" */
3535 wnamebuf = PyMem_New(wchar_t, len + 5);
3536 if (!wnamebuf) {
3537 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003538 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 }
Steve Dowercc16be82016-09-08 10:35:16 -07003540 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003542 wchar_t wch = wnamebuf[len-1];
3543 if (wch != SEP && wch != ALTSEP && wch != L':')
3544 wnamebuf[len++] = SEP;
3545 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 }
Steve Dowercc16be82016-09-08 10:35:16 -07003547 if ((list = PyList_New(0)) == NULL) {
3548 goto exit;
3549 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003550 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003551 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003552 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 if (hFindFile == INVALID_HANDLE_VALUE) {
3554 int error = GetLastError();
3555 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556 goto exit;
3557 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003558 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003559 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 }
3561 do {
3562 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003563 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3564 wcscmp(wFileData.cFileName, L"..") != 0) {
3565 v = PyUnicode_FromWideChar(wFileData.cFileName,
3566 wcslen(wFileData.cFileName));
3567 if (path->narrow && v) {
3568 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3569 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003570 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 Py_DECREF(list);
3572 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003573 break;
3574 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003577 Py_DECREF(list);
3578 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003579 break;
3580 }
3581 Py_DECREF(v);
3582 }
3583 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003584 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 Py_END_ALLOW_THREADS
3586 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3587 it got to the end of the directory. */
3588 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003589 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003590 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003591 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003592 }
3593 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003594
Larry Hastings9cf065c2012-06-22 16:30:09 -07003595exit:
3596 if (hFindFile != INVALID_HANDLE_VALUE) {
3597 if (FindClose(hFindFile) == FALSE) {
3598 if (list != NULL) {
3599 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003600 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 }
3602 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003603 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003604 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003605
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003607} /* end of _listdir_windows_no_opendir */
3608
3609#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3610
3611static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003612_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003613{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003614 PyObject *v;
3615 DIR *dirp = NULL;
3616 struct dirent *ep;
3617 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003618#ifdef HAVE_FDOPENDIR
3619 int fd = -1;
3620#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003621
Victor Stinner8c62be82010-05-06 00:08:46 +00003622 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003624 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003626 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003627 if (fd == -1)
3628 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003629
Larry Hastingsfdaea062012-06-25 04:42:23 -07003630 return_str = 1;
3631
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632 Py_BEGIN_ALLOW_THREADS
3633 dirp = fdopendir(fd);
3634 Py_END_ALLOW_THREADS
3635 }
3636 else
3637#endif
3638 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003639 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003640 if (path->narrow) {
3641 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003642 /* only return bytes if they specified a bytes-like object */
3643 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003644 }
3645 else {
3646 name = ".";
3647 return_str = 1;
3648 }
3649
Larry Hastings9cf065c2012-06-22 16:30:09 -07003650 Py_BEGIN_ALLOW_THREADS
3651 dirp = opendir(name);
3652 Py_END_ALLOW_THREADS
3653 }
3654
3655 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003656 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003657#ifdef HAVE_FDOPENDIR
3658 if (fd != -1) {
3659 Py_BEGIN_ALLOW_THREADS
3660 close(fd);
3661 Py_END_ALLOW_THREADS
3662 }
3663#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003664 goto exit;
3665 }
3666 if ((list = PyList_New(0)) == NULL) {
3667 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003668 }
3669 for (;;) {
3670 errno = 0;
3671 Py_BEGIN_ALLOW_THREADS
3672 ep = readdir(dirp);
3673 Py_END_ALLOW_THREADS
3674 if (ep == NULL) {
3675 if (errno == 0) {
3676 break;
3677 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003678 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003679 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003680 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003681 }
3682 }
3683 if (ep->d_name[0] == '.' &&
3684 (NAMLEN(ep) == 1 ||
3685 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3686 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003687 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003688 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3689 else
3690 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003691 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003692 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003693 break;
3694 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003695 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003697 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003698 break;
3699 }
3700 Py_DECREF(v);
3701 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003702
Larry Hastings9cf065c2012-06-22 16:30:09 -07003703exit:
3704 if (dirp != NULL) {
3705 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003706#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003707 if (fd > -1)
3708 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003709#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 closedir(dirp);
3711 Py_END_ALLOW_THREADS
3712 }
3713
Larry Hastings9cf065c2012-06-22 16:30:09 -07003714 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003715} /* end of _posix_listdir */
3716#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003717
Larry Hastings2f936352014-08-05 14:04:04 +10003718
3719/*[clinic input]
3720os.listdir
3721
3722 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3723
3724Return a list containing the names of the files in the directory.
3725
BNMetricsb9427072018-11-02 15:20:19 +00003726path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003727 the filenames returned will also be bytes; in all other circumstances
3728 the filenames returned will be str.
3729If path is None, uses the path='.'.
3730On some platforms, path may also be specified as an open file descriptor;\
3731 the file descriptor must refer to a directory.
3732 If this functionality is unavailable, using it raises NotImplementedError.
3733
3734The list is in arbitrary order. It does not include the special
3735entries '.' and '..' even if they are present in the directory.
3736
3737
3738[clinic start generated code]*/
3739
Larry Hastings2f936352014-08-05 14:04:04 +10003740static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003741os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003742/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003743{
3744#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3745 return _listdir_windows_no_opendir(path, NULL);
3746#else
3747 return _posix_listdir(path, NULL);
3748#endif
3749}
3750
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003751#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003752/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003753/*[clinic input]
3754os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003755
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003756 path: path_t
3757 /
3758
3759[clinic start generated code]*/
3760
3761static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003762os__getfullpathname_impl(PyObject *module, path_t *path)
3763/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003764{
Steve Dowercc16be82016-09-08 10:35:16 -07003765 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3766 wchar_t *wtemp;
3767 DWORD result;
3768 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003769
Steve Dowercc16be82016-09-08 10:35:16 -07003770 result = GetFullPathNameW(path->wide,
3771 Py_ARRAY_LENGTH(woutbuf),
3772 woutbuf, &wtemp);
3773 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3774 woutbufp = PyMem_New(wchar_t, result);
3775 if (!woutbufp)
3776 return PyErr_NoMemory();
3777 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003778 }
Steve Dowercc16be82016-09-08 10:35:16 -07003779 if (result) {
3780 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3781 if (path->narrow)
3782 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3783 } else
3784 v = win32_error_object("GetFullPathNameW", path->object);
3785 if (woutbufp != woutbuf)
3786 PyMem_Free(woutbufp);
3787 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003788}
Brian Curtind40e6f72010-07-08 21:39:08 +00003789
Brian Curtind25aef52011-06-13 15:16:04 -05003790
Larry Hastings2f936352014-08-05 14:04:04 +10003791/*[clinic input]
3792os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003793
Steve Dower23ad6d02018-02-22 10:39:10 -08003794 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003795 /
3796
3797A helper function for samepath on windows.
3798[clinic start generated code]*/
3799
Larry Hastings2f936352014-08-05 14:04:04 +10003800static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003801os__getfinalpathname_impl(PyObject *module, path_t *path)
3802/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003803{
3804 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003805 wchar_t buf[MAXPATHLEN], *target_path = buf;
3806 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003807 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003808 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003809
Steve Dower23ad6d02018-02-22 10:39:10 -08003810 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003811 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003812 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003813 0, /* desired access */
3814 0, /* share mode */
3815 NULL, /* security attributes */
3816 OPEN_EXISTING,
3817 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3818 FILE_FLAG_BACKUP_SEMANTICS,
3819 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003820 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003821
Steve Dower23ad6d02018-02-22 10:39:10 -08003822 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003823 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003824 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003825
3826 /* We have a good handle to the target, use it to determine the
3827 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003828 while (1) {
3829 Py_BEGIN_ALLOW_THREADS
3830 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3831 buf_size, VOLUME_NAME_DOS);
3832 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003833
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003834 if (!result_length) {
3835 result = win32_error_object("GetFinalPathNameByHandleW",
3836 path->object);
3837 goto cleanup;
3838 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003839
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003840 if (result_length < buf_size) {
3841 break;
3842 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003843
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003844 wchar_t *tmp;
3845 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3846 result_length * sizeof(*tmp));
3847 if (!tmp) {
3848 result = PyErr_NoMemory();
3849 goto cleanup;
3850 }
3851
3852 buf_size = result_length;
3853 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003854 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003855
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003856 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003857 if (path->narrow)
3858 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003859
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003860cleanup:
3861 if (target_path != buf) {
3862 PyMem_Free(target_path);
3863 }
3864 CloseHandle(hFile);
3865 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003866}
Brian Curtin62857742010-09-06 17:07:27 +00003867
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003868/*[clinic input]
3869os._isdir
3870
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003871 path as arg: object
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003872 /
3873
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003874Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003875[clinic start generated code]*/
3876
Brian Curtin9c669cc2011-06-08 18:17:18 -05003877static PyObject *
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003878os__isdir(PyObject *module, PyObject *arg)
3879/*[clinic end generated code: output=404f334d85d4bf25 input=36cb6785874d479e]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003880{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003881 DWORD attributes;
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003882 path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0);
3883
3884 if (!path_converter(arg, &path)) {
3885 if (PyErr_ExceptionMatches(PyExc_ValueError)) {
3886 PyErr_Clear();
3887 Py_RETURN_FALSE;
3888 }
3889 return NULL;
3890 }
Brian Curtin9c669cc2011-06-08 18:17:18 -05003891
Steve Dowerb22a6772016-07-17 20:49:38 -07003892 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003893 attributes = GetFileAttributesW(path.wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003894 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003895
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003896 path_cleanup(&path);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003897 if (attributes == INVALID_FILE_ATTRIBUTES)
3898 Py_RETURN_FALSE;
3899
Brian Curtin9c669cc2011-06-08 18:17:18 -05003900 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3901 Py_RETURN_TRUE;
3902 else
3903 Py_RETURN_FALSE;
3904}
Tim Golden6b528062013-08-01 12:44:00 +01003905
Tim Golden6b528062013-08-01 12:44:00 +01003906
Larry Hastings2f936352014-08-05 14:04:04 +10003907/*[clinic input]
3908os._getvolumepathname
3909
Steve Dower23ad6d02018-02-22 10:39:10 -08003910 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003911
3912A helper function for ismount on Win32.
3913[clinic start generated code]*/
3914
Larry Hastings2f936352014-08-05 14:04:04 +10003915static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003916os__getvolumepathname_impl(PyObject *module, path_t *path)
3917/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003918{
3919 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003920 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003921 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003922 BOOL ret;
3923
Tim Golden6b528062013-08-01 12:44:00 +01003924 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003925 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003926
Victor Stinner850a18e2017-10-24 16:53:32 -07003927 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003928 PyErr_SetString(PyExc_OverflowError, "path too long");
3929 return NULL;
3930 }
3931
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003932 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003933 if (mountpath == NULL)
3934 return PyErr_NoMemory();
3935
3936 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003937 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003938 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003939 Py_END_ALLOW_THREADS
3940
3941 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003942 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003943 goto exit;
3944 }
3945 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003946 if (path->narrow)
3947 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003948
3949exit:
3950 PyMem_Free(mountpath);
3951 return result;
3952}
Tim Golden6b528062013-08-01 12:44:00 +01003953
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003954#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003955
Larry Hastings2f936352014-08-05 14:04:04 +10003956
3957/*[clinic input]
3958os.mkdir
3959
3960 path : path_t
3961
3962 mode: int = 0o777
3963
3964 *
3965
3966 dir_fd : dir_fd(requires='mkdirat') = None
3967
3968# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3969
3970Create a directory.
3971
3972If dir_fd is not None, it should be a file descriptor open to a directory,
3973 and path should be relative; path will then be relative to that directory.
3974dir_fd may not be implemented on your platform.
3975 If it is unavailable, using it will raise a NotImplementedError.
3976
3977The mode argument is ignored on Windows.
3978[clinic start generated code]*/
3979
Larry Hastings2f936352014-08-05 14:04:04 +10003980static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003981os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3982/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003983{
3984 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003985
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003986#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003987 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003988 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003989 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003990
Larry Hastings2f936352014-08-05 14:04:04 +10003991 if (!result)
3992 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003993#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003994 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003995#if HAVE_MKDIRAT
3996 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003997 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003998 else
3999#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004000#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004001 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004002#else
Larry Hastings2f936352014-08-05 14:04:04 +10004003 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004004#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004005 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004006 if (result < 0)
4007 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004008#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004009 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004010}
4011
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004012
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004013/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4014#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004015#include <sys/resource.h>
4016#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004017
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004018
4019#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004020/*[clinic input]
4021os.nice
4022
4023 increment: int
4024 /
4025
4026Add increment to the priority of process and return the new priority.
4027[clinic start generated code]*/
4028
Larry Hastings2f936352014-08-05 14:04:04 +10004029static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004030os_nice_impl(PyObject *module, int increment)
4031/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004032{
4033 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004034
Victor Stinner8c62be82010-05-06 00:08:46 +00004035 /* There are two flavours of 'nice': one that returns the new
4036 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004037 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004038 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004039
Victor Stinner8c62be82010-05-06 00:08:46 +00004040 If we are of the nice family that returns the new priority, we
4041 need to clear errno before the call, and check if errno is filled
4042 before calling posix_error() on a returnvalue of -1, because the
4043 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004044
Victor Stinner8c62be82010-05-06 00:08:46 +00004045 errno = 0;
4046 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004047#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004048 if (value == 0)
4049 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004050#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004051 if (value == -1 && errno != 0)
4052 /* either nice() or getpriority() returned an error */
4053 return posix_error();
4054 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004055}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004056#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004057
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004058
4059#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004060/*[clinic input]
4061os.getpriority
4062
4063 which: int
4064 who: int
4065
4066Return program scheduling priority.
4067[clinic start generated code]*/
4068
Larry Hastings2f936352014-08-05 14:04:04 +10004069static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004070os_getpriority_impl(PyObject *module, int which, int who)
4071/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004072{
4073 int retval;
4074
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004075 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004076 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004077 if (errno != 0)
4078 return posix_error();
4079 return PyLong_FromLong((long)retval);
4080}
4081#endif /* HAVE_GETPRIORITY */
4082
4083
4084#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004085/*[clinic input]
4086os.setpriority
4087
4088 which: int
4089 who: int
4090 priority: int
4091
4092Set program scheduling priority.
4093[clinic start generated code]*/
4094
Larry Hastings2f936352014-08-05 14:04:04 +10004095static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004096os_setpriority_impl(PyObject *module, int which, int who, int priority)
4097/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004098{
4099 int retval;
4100
4101 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004102 if (retval == -1)
4103 return posix_error();
4104 Py_RETURN_NONE;
4105}
4106#endif /* HAVE_SETPRIORITY */
4107
4108
Barry Warsaw53699e91996-12-10 23:23:01 +00004109static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004110internal_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 +00004111{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004112 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004114
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004115#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004116 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004117 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004118#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004119 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004120#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004121
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4123 (dst_dir_fd != DEFAULT_DIR_FD);
4124#ifndef HAVE_RENAMEAT
4125 if (dir_fd_specified) {
4126 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004127 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004128 }
4129#endif
4130
Larry Hastings9cf065c2012-06-22 16:30:09 -07004131#ifdef MS_WINDOWS
4132 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004133 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134 Py_END_ALLOW_THREADS
4135
Larry Hastings2f936352014-08-05 14:04:04 +10004136 if (!result)
4137 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004138
4139#else
Steve Dowercc16be82016-09-08 10:35:16 -07004140 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4141 PyErr_Format(PyExc_ValueError,
4142 "%s: src and dst must be the same type", function_name);
4143 return NULL;
4144 }
4145
Larry Hastings9cf065c2012-06-22 16:30:09 -07004146 Py_BEGIN_ALLOW_THREADS
4147#ifdef HAVE_RENAMEAT
4148 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004149 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004150 else
4151#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004152 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004153 Py_END_ALLOW_THREADS
4154
Larry Hastings2f936352014-08-05 14:04:04 +10004155 if (result)
4156 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004157#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004158 Py_RETURN_NONE;
4159}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004160
Larry Hastings2f936352014-08-05 14:04:04 +10004161
4162/*[clinic input]
4163os.rename
4164
4165 src : path_t
4166 dst : path_t
4167 *
4168 src_dir_fd : dir_fd = None
4169 dst_dir_fd : dir_fd = None
4170
4171Rename a file or directory.
4172
4173If either src_dir_fd or dst_dir_fd is not None, it should be a file
4174 descriptor open to a directory, and the respective path string (src or dst)
4175 should be relative; the path will then be relative to that directory.
4176src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4177 If they are unavailable, using them will raise a NotImplementedError.
4178[clinic start generated code]*/
4179
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004180static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004181os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004182 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004183/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004184{
Larry Hastings2f936352014-08-05 14:04:04 +10004185 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004186}
4187
Larry Hastings2f936352014-08-05 14:04:04 +10004188
4189/*[clinic input]
4190os.replace = os.rename
4191
4192Rename a file or directory, overwriting the destination.
4193
4194If either src_dir_fd or dst_dir_fd is not None, it should be a file
4195 descriptor open to a directory, and the respective path string (src or dst)
4196 should be relative; the path will then be relative to that directory.
4197src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004198 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004199[clinic start generated code]*/
4200
Larry Hastings2f936352014-08-05 14:04:04 +10004201static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004202os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4203 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004204/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004205{
4206 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4207}
4208
4209
4210/*[clinic input]
4211os.rmdir
4212
4213 path: path_t
4214 *
4215 dir_fd: dir_fd(requires='unlinkat') = None
4216
4217Remove a directory.
4218
4219If dir_fd is not None, it should be a file descriptor open to a directory,
4220 and path should be relative; path will then be relative to that directory.
4221dir_fd may not be implemented on your platform.
4222 If it is unavailable, using it will raise a NotImplementedError.
4223[clinic start generated code]*/
4224
Larry Hastings2f936352014-08-05 14:04:04 +10004225static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004226os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4227/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004228{
4229 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004230
4231 Py_BEGIN_ALLOW_THREADS
4232#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004233 /* Windows, success=1, UNIX, success=0 */
4234 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004235#else
4236#ifdef HAVE_UNLINKAT
4237 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004238 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004239 else
4240#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004241 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004242#endif
4243 Py_END_ALLOW_THREADS
4244
Larry Hastings2f936352014-08-05 14:04:04 +10004245 if (result)
4246 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004247
Larry Hastings2f936352014-08-05 14:04:04 +10004248 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004249}
4250
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004251
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004252#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004253#ifdef MS_WINDOWS
4254/*[clinic input]
4255os.system -> long
4256
4257 command: Py_UNICODE
4258
4259Execute the command in a subshell.
4260[clinic start generated code]*/
4261
Larry Hastings2f936352014-08-05 14:04:04 +10004262static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004263os_system_impl(PyObject *module, const Py_UNICODE *command)
4264/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004265{
4266 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004267 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004268 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004269 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004270 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004271 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004272 return result;
4273}
4274#else /* MS_WINDOWS */
4275/*[clinic input]
4276os.system -> long
4277
4278 command: FSConverter
4279
4280Execute the command in a subshell.
4281[clinic start generated code]*/
4282
Larry Hastings2f936352014-08-05 14:04:04 +10004283static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004284os_system_impl(PyObject *module, PyObject *command)
4285/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004286{
4287 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004288 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004289 Py_BEGIN_ALLOW_THREADS
4290 result = system(bytes);
4291 Py_END_ALLOW_THREADS
4292 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004293}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004294#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004295#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004296
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004297
Larry Hastings2f936352014-08-05 14:04:04 +10004298/*[clinic input]
4299os.umask
4300
4301 mask: int
4302 /
4303
4304Set the current numeric umask and return the previous umask.
4305[clinic start generated code]*/
4306
Larry Hastings2f936352014-08-05 14:04:04 +10004307static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004308os_umask_impl(PyObject *module, int mask)
4309/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004310{
4311 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004312 if (i < 0)
4313 return posix_error();
4314 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004315}
4316
Brian Curtind40e6f72010-07-08 21:39:08 +00004317#ifdef MS_WINDOWS
4318
4319/* override the default DeleteFileW behavior so that directory
4320symlinks can be removed with this function, the same as with
4321Unix symlinks */
4322BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4323{
4324 WIN32_FILE_ATTRIBUTE_DATA info;
4325 WIN32_FIND_DATAW find_data;
4326 HANDLE find_data_handle;
4327 int is_directory = 0;
4328 int is_link = 0;
4329
4330 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4331 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004332
Brian Curtind40e6f72010-07-08 21:39:08 +00004333 /* Get WIN32_FIND_DATA structure for the path to determine if
4334 it is a symlink */
4335 if(is_directory &&
4336 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4337 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4338
4339 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004340 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4341 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4342 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4343 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004344 FindClose(find_data_handle);
4345 }
4346 }
4347 }
4348
4349 if (is_directory && is_link)
4350 return RemoveDirectoryW(lpFileName);
4351
4352 return DeleteFileW(lpFileName);
4353}
4354#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004356
Larry Hastings2f936352014-08-05 14:04:04 +10004357/*[clinic input]
4358os.unlink
4359
4360 path: path_t
4361 *
4362 dir_fd: dir_fd(requires='unlinkat')=None
4363
4364Remove a file (same as remove()).
4365
4366If dir_fd is not None, it should be a file descriptor open to a directory,
4367 and path should be relative; path will then be relative to that directory.
4368dir_fd may not be implemented on your platform.
4369 If it is unavailable, using it will raise a NotImplementedError.
4370
4371[clinic start generated code]*/
4372
Larry Hastings2f936352014-08-05 14:04:04 +10004373static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004374os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4375/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004376{
4377 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004378
4379 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004380 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004381#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004382 /* Windows, success=1, UNIX, success=0 */
4383 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004384#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004385#ifdef HAVE_UNLINKAT
4386 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004387 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004388 else
4389#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004390 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004391#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004392 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004393 Py_END_ALLOW_THREADS
4394
Larry Hastings2f936352014-08-05 14:04:04 +10004395 if (result)
4396 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -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
Larry Hastings2f936352014-08-05 14:04:04 +10004402/*[clinic input]
4403os.remove = os.unlink
4404
4405Remove a file (same as unlink()).
4406
4407If dir_fd is not None, it should be a file descriptor open to a directory,
4408 and path should be relative; path will then be relative to that directory.
4409dir_fd may not be implemented on your platform.
4410 If it is unavailable, using it will raise a NotImplementedError.
4411[clinic start generated code]*/
4412
Larry Hastings2f936352014-08-05 14:04:04 +10004413static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004414os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4415/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004416{
4417 return os_unlink_impl(module, path, dir_fd);
4418}
4419
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004420
Larry Hastings605a62d2012-06-24 04:33:36 -07004421static PyStructSequence_Field uname_result_fields[] = {
4422 {"sysname", "operating system name"},
4423 {"nodename", "name of machine on network (implementation-defined)"},
4424 {"release", "operating system release"},
4425 {"version", "operating system version"},
4426 {"machine", "hardware identifier"},
4427 {NULL}
4428};
4429
4430PyDoc_STRVAR(uname_result__doc__,
4431"uname_result: Result from os.uname().\n\n\
4432This object may be accessed either as a tuple of\n\
4433 (sysname, nodename, release, version, machine),\n\
4434or via the attributes sysname, nodename, release, version, and machine.\n\
4435\n\
4436See os.uname for more information.");
4437
4438static PyStructSequence_Desc uname_result_desc = {
4439 "uname_result", /* name */
4440 uname_result__doc__, /* doc */
4441 uname_result_fields,
4442 5
4443};
4444
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004445static PyTypeObject* UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07004446
4447
4448#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004449/*[clinic input]
4450os.uname
4451
4452Return an object identifying the current operating system.
4453
4454The object behaves like a named tuple with the following fields:
4455 (sysname, nodename, release, version, machine)
4456
4457[clinic start generated code]*/
4458
Larry Hastings2f936352014-08-05 14:04:04 +10004459static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004460os_uname_impl(PyObject *module)
4461/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004462{
Victor Stinner8c62be82010-05-06 00:08:46 +00004463 struct utsname u;
4464 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004465 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004466
Victor Stinner8c62be82010-05-06 00:08:46 +00004467 Py_BEGIN_ALLOW_THREADS
4468 res = uname(&u);
4469 Py_END_ALLOW_THREADS
4470 if (res < 0)
4471 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004472
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004473 value = PyStructSequence_New(UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004474 if (value == NULL)
4475 return NULL;
4476
4477#define SET(i, field) \
4478 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004479 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004480 if (!o) { \
4481 Py_DECREF(value); \
4482 return NULL; \
4483 } \
4484 PyStructSequence_SET_ITEM(value, i, o); \
4485 } \
4486
4487 SET(0, u.sysname);
4488 SET(1, u.nodename);
4489 SET(2, u.release);
4490 SET(3, u.version);
4491 SET(4, u.machine);
4492
4493#undef SET
4494
4495 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004496}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004497#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004498
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004499
Larry Hastings9cf065c2012-06-22 16:30:09 -07004500
4501typedef struct {
4502 int now;
4503 time_t atime_s;
4504 long atime_ns;
4505 time_t mtime_s;
4506 long mtime_ns;
4507} utime_t;
4508
4509/*
Victor Stinner484df002014-10-09 13:52:31 +02004510 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004511 * they also intentionally leak the declaration of a pointer named "time"
4512 */
4513#define UTIME_TO_TIMESPEC \
4514 struct timespec ts[2]; \
4515 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004516 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004517 time = NULL; \
4518 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004519 ts[0].tv_sec = ut->atime_s; \
4520 ts[0].tv_nsec = ut->atime_ns; \
4521 ts[1].tv_sec = ut->mtime_s; \
4522 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004523 time = ts; \
4524 } \
4525
4526#define UTIME_TO_TIMEVAL \
4527 struct timeval tv[2]; \
4528 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004529 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004530 time = NULL; \
4531 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004532 tv[0].tv_sec = ut->atime_s; \
4533 tv[0].tv_usec = ut->atime_ns / 1000; \
4534 tv[1].tv_sec = ut->mtime_s; \
4535 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004536 time = tv; \
4537 } \
4538
4539#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004540 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004541 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004542 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004543 time = NULL; \
4544 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004545 u.actime = ut->atime_s; \
4546 u.modtime = ut->mtime_s; \
4547 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004548 }
4549
4550#define UTIME_TO_TIME_T \
4551 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004552 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004553 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004554 time = NULL; \
4555 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004556 timet[0] = ut->atime_s; \
4557 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004558 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004559 } \
4560
4561
Victor Stinner528a9ab2015-09-03 21:30:26 +02004562#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004563
4564static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004565utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004566{
4567#ifdef HAVE_UTIMENSAT
4568 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4569 UTIME_TO_TIMESPEC;
4570 return utimensat(dir_fd, path, time, flags);
4571#elif defined(HAVE_FUTIMESAT)
4572 UTIME_TO_TIMEVAL;
4573 /*
4574 * follow_symlinks will never be false here;
4575 * we only allow !follow_symlinks and dir_fd together
4576 * if we have utimensat()
4577 */
4578 assert(follow_symlinks);
4579 return futimesat(dir_fd, path, time);
4580#endif
4581}
4582
Larry Hastings2f936352014-08-05 14:04:04 +10004583 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4584#else
4585 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586#endif
4587
Victor Stinner528a9ab2015-09-03 21:30:26 +02004588#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004589
4590static int
Victor Stinner484df002014-10-09 13:52:31 +02004591utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592{
4593#ifdef HAVE_FUTIMENS
4594 UTIME_TO_TIMESPEC;
4595 return futimens(fd, time);
4596#else
4597 UTIME_TO_TIMEVAL;
4598 return futimes(fd, time);
4599#endif
4600}
4601
Larry Hastings2f936352014-08-05 14:04:04 +10004602 #define PATH_UTIME_HAVE_FD 1
4603#else
4604 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004605#endif
4606
Victor Stinner5ebae872015-09-22 01:29:33 +02004607#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4608# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4609#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004610
Victor Stinner4552ced2015-09-21 22:37:15 +02004611#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004612
4613static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004614utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004615{
4616#ifdef HAVE_UTIMENSAT
4617 UTIME_TO_TIMESPEC;
4618 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4619#else
4620 UTIME_TO_TIMEVAL;
4621 return lutimes(path, time);
4622#endif
4623}
4624
4625#endif
4626
4627#ifndef MS_WINDOWS
4628
4629static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004630utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631{
4632#ifdef HAVE_UTIMENSAT
4633 UTIME_TO_TIMESPEC;
4634 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4635#elif defined(HAVE_UTIMES)
4636 UTIME_TO_TIMEVAL;
4637 return utimes(path, time);
4638#elif defined(HAVE_UTIME_H)
4639 UTIME_TO_UTIMBUF;
4640 return utime(path, time);
4641#else
4642 UTIME_TO_TIME_T;
4643 return utime(path, time);
4644#endif
4645}
4646
4647#endif
4648
Larry Hastings76ad59b2012-05-03 00:30:07 -07004649static int
4650split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4651{
4652 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004653 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004654 divmod = PyNumber_Divmod(py_long, billion);
4655 if (!divmod)
4656 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004657 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4658 PyErr_Format(PyExc_TypeError,
4659 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4660 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4661 goto exit;
4662 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004663 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4664 if ((*s == -1) && PyErr_Occurred())
4665 goto exit;
4666 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004667 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004668 goto exit;
4669
4670 result = 1;
4671exit:
4672 Py_XDECREF(divmod);
4673 return result;
4674}
4675
Larry Hastings2f936352014-08-05 14:04:04 +10004676
4677/*[clinic input]
4678os.utime
4679
4680 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4681 times: object = NULL
4682 *
4683 ns: object = NULL
4684 dir_fd: dir_fd(requires='futimensat') = None
4685 follow_symlinks: bool=True
4686
Martin Panter0ff89092015-09-09 01:56:53 +00004687# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004688
4689Set the access and modified time of path.
4690
4691path may always be specified as a string.
4692On some platforms, path may also be specified as an open file descriptor.
4693 If this functionality is unavailable, using it raises an exception.
4694
4695If times is not None, it must be a tuple (atime, mtime);
4696 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004697If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004698 atime_ns and mtime_ns should be expressed as integer nanoseconds
4699 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004700If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004701Specifying tuples for both times and ns is an error.
4702
4703If dir_fd is not None, it should be a file descriptor open to a directory,
4704 and path should be relative; path will then be relative to that directory.
4705If follow_symlinks is False, and the last element of the path is a symbolic
4706 link, utime will modify the symbolic link itself instead of the file the
4707 link points to.
4708It is an error to use dir_fd or follow_symlinks when specifying path
4709 as an open file descriptor.
4710dir_fd and follow_symlinks may not be available on your platform.
4711 If they are unavailable, using them will raise a NotImplementedError.
4712
4713[clinic start generated code]*/
4714
Larry Hastings2f936352014-08-05 14:04:04 +10004715static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004716os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4717 int dir_fd, int follow_symlinks)
4718/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004719{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720#ifdef MS_WINDOWS
4721 HANDLE hFile;
4722 FILETIME atime, mtime;
4723#else
4724 int result;
4725#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004726
Larry Hastings2f936352014-08-05 14:04:04 +10004727 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004728
Christian Heimesb3c87242013-08-01 00:08:16 +02004729 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004730
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731 if (times && (times != Py_None) && ns) {
4732 PyErr_SetString(PyExc_ValueError,
4733 "utime: you may specify either 'times'"
4734 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004735 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004736 }
4737
4738 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004739 time_t a_sec, m_sec;
4740 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004741 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742 PyErr_SetString(PyExc_TypeError,
4743 "utime: 'times' must be either"
4744 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004745 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004746 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004748 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004749 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004750 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004751 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004752 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004753 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004754 utime.atime_s = a_sec;
4755 utime.atime_ns = a_nsec;
4756 utime.mtime_s = m_sec;
4757 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004758 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004759 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004760 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004761 PyErr_SetString(PyExc_TypeError,
4762 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004763 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004764 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004766 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004767 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004768 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004770 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004771 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004772 }
4773 else {
4774 /* times and ns are both None/unspecified. use "now". */
4775 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004776 }
4777
Victor Stinner4552ced2015-09-21 22:37:15 +02004778#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004779 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004780 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004781#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004782
Larry Hastings2f936352014-08-05 14:04:04 +10004783 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4784 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4785 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004786 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004787
Larry Hastings9cf065c2012-06-22 16:30:09 -07004788#if !defined(HAVE_UTIMENSAT)
4789 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004790 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004791 "utime: cannot use dir_fd and follow_symlinks "
4792 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004793 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004794 }
4795#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004796
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004797#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004798 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004799 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4800 NULL, OPEN_EXISTING,
4801 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004802 Py_END_ALLOW_THREADS
4803 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004804 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004805 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004806 }
4807
Larry Hastings9cf065c2012-06-22 16:30:09 -07004808 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004809 GetSystemTimeAsFileTime(&mtime);
4810 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004811 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004812 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004813 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4814 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004815 }
4816 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4817 /* Avoid putting the file name into the error here,
4818 as that may confuse the user into believing that
4819 something is wrong with the file, when it also
4820 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004821 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004822 CloseHandle(hFile);
4823 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004824 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004825 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004826#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004827 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004828
Victor Stinner4552ced2015-09-21 22:37:15 +02004829#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004830 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004831 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004832 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004833#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004834
Victor Stinner528a9ab2015-09-03 21:30:26 +02004835#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004836 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004837 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004838 else
4839#endif
4840
Victor Stinner528a9ab2015-09-03 21:30:26 +02004841#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004842 if (path->fd != -1)
4843 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004844 else
4845#endif
4846
Larry Hastings2f936352014-08-05 14:04:04 +10004847 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004848
4849 Py_END_ALLOW_THREADS
4850
4851 if (result < 0) {
4852 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004853 posix_error();
4854 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004855 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004856
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004857#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004858
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004859 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004860}
4861
Guido van Rossum3b066191991-06-04 19:40:25 +00004862/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004863
Larry Hastings2f936352014-08-05 14:04:04 +10004864
4865/*[clinic input]
4866os._exit
4867
4868 status: int
4869
4870Exit to the system with specified status, without normal exit processing.
4871[clinic start generated code]*/
4872
Larry Hastings2f936352014-08-05 14:04:04 +10004873static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004874os__exit_impl(PyObject *module, int status)
4875/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004876{
4877 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004878 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004879}
4880
Steve Dowercc16be82016-09-08 10:35:16 -07004881#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4882#define EXECV_CHAR wchar_t
4883#else
4884#define EXECV_CHAR char
4885#endif
4886
pxinwrf2d7ac72019-05-21 18:46:37 +08004887#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004888static void
Steve Dowercc16be82016-09-08 10:35:16 -07004889free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004890{
Victor Stinner8c62be82010-05-06 00:08:46 +00004891 Py_ssize_t i;
4892 for (i = 0; i < count; i++)
4893 PyMem_Free(array[i]);
4894 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004895}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004896
Berker Peksag81816462016-09-15 20:19:47 +03004897static int
4898fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004899{
Victor Stinner8c62be82010-05-06 00:08:46 +00004900 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004901 PyObject *ub;
4902 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004903#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004904 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004905 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004906 *out = PyUnicode_AsWideCharString(ub, &size);
4907 if (*out)
4908 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004909#else
Berker Peksag81816462016-09-15 20:19:47 +03004910 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004911 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004912 size = PyBytes_GET_SIZE(ub);
4913 *out = PyMem_Malloc(size + 1);
4914 if (*out) {
4915 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4916 result = 1;
4917 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004918 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004919#endif
Berker Peksag81816462016-09-15 20:19:47 +03004920 Py_DECREF(ub);
4921 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004922}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004923#endif
4924
pxinwrf2d7ac72019-05-21 18:46:37 +08004925#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07004926static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004927parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4928{
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 Py_ssize_t i, pos, envc;
4930 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004931 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004932 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004933
Victor Stinner8c62be82010-05-06 00:08:46 +00004934 i = PyMapping_Size(env);
4935 if (i < 0)
4936 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004937 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 if (envlist == NULL) {
4939 PyErr_NoMemory();
4940 return NULL;
4941 }
4942 envc = 0;
4943 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004944 if (!keys)
4945 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004946 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004947 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004948 goto error;
4949 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4950 PyErr_Format(PyExc_TypeError,
4951 "env.keys() or env.values() is not a list");
4952 goto error;
4953 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004954
Victor Stinner8c62be82010-05-06 00:08:46 +00004955 for (pos = 0; pos < i; pos++) {
4956 key = PyList_GetItem(keys, pos);
4957 val = PyList_GetItem(vals, pos);
4958 if (!key || !val)
4959 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004960
Berker Peksag81816462016-09-15 20:19:47 +03004961#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4962 if (!PyUnicode_FSDecoder(key, &key2))
4963 goto error;
4964 if (!PyUnicode_FSDecoder(val, &val2)) {
4965 Py_DECREF(key2);
4966 goto error;
4967 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004968 /* Search from index 1 because on Windows starting '=' is allowed for
4969 defining hidden environment variables. */
4970 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4971 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4972 {
4973 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004974 Py_DECREF(key2);
4975 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004976 goto error;
4977 }
Berker Peksag81816462016-09-15 20:19:47 +03004978 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4979#else
4980 if (!PyUnicode_FSConverter(key, &key2))
4981 goto error;
4982 if (!PyUnicode_FSConverter(val, &val2)) {
4983 Py_DECREF(key2);
4984 goto error;
4985 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004986 if (PyBytes_GET_SIZE(key2) == 0 ||
4987 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4988 {
4989 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004990 Py_DECREF(key2);
4991 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004992 goto error;
4993 }
Berker Peksag81816462016-09-15 20:19:47 +03004994 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4995 PyBytes_AS_STRING(val2));
4996#endif
4997 Py_DECREF(key2);
4998 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004999 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005000 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005001
5002 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5003 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005004 goto error;
5005 }
Berker Peksag81816462016-09-15 20:19:47 +03005006
Steve Dowercc16be82016-09-08 10:35:16 -07005007 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005008 }
5009 Py_DECREF(vals);
5010 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005011
Victor Stinner8c62be82010-05-06 00:08:46 +00005012 envlist[envc] = 0;
5013 *envc_ptr = envc;
5014 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005015
5016error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005017 Py_XDECREF(keys);
5018 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005019 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005020 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005021}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005022
Steve Dowercc16be82016-09-08 10:35:16 -07005023static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005024parse_arglist(PyObject* argv, Py_ssize_t *argc)
5025{
5026 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005027 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005028 if (argvlist == NULL) {
5029 PyErr_NoMemory();
5030 return NULL;
5031 }
5032 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005033 PyObject* item = PySequence_ITEM(argv, i);
5034 if (item == NULL)
5035 goto fail;
5036 if (!fsconvert_strdup(item, &argvlist[i])) {
5037 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005038 goto fail;
5039 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005040 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005041 }
5042 argvlist[*argc] = NULL;
5043 return argvlist;
5044fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005045 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005046 free_string_array(argvlist, *argc);
5047 return NULL;
5048}
Steve Dowercc16be82016-09-08 10:35:16 -07005049
Ross Lagerwall7807c352011-03-17 20:20:30 +02005050#endif
5051
Larry Hastings2f936352014-08-05 14:04:04 +10005052
Ross Lagerwall7807c352011-03-17 20:20:30 +02005053#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005054/*[clinic input]
5055os.execv
5056
Steve Dowercc16be82016-09-08 10:35:16 -07005057 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005058 Path of executable file.
5059 argv: object
5060 Tuple or list of strings.
5061 /
5062
5063Execute an executable path with arguments, replacing current process.
5064[clinic start generated code]*/
5065
Larry Hastings2f936352014-08-05 14:04:04 +10005066static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005067os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5068/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005069{
Steve Dowercc16be82016-09-08 10:35:16 -07005070 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005071 Py_ssize_t argc;
5072
5073 /* execv has two arguments: (path, argv), where
5074 argv is a list or tuple of strings. */
5075
Ross Lagerwall7807c352011-03-17 20:20:30 +02005076 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5077 PyErr_SetString(PyExc_TypeError,
5078 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005079 return NULL;
5080 }
5081 argc = PySequence_Size(argv);
5082 if (argc < 1) {
5083 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005084 return NULL;
5085 }
5086
5087 argvlist = parse_arglist(argv, &argc);
5088 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005089 return NULL;
5090 }
Steve Dowerbce26262016-11-19 19:17:26 -08005091 if (!argvlist[0][0]) {
5092 PyErr_SetString(PyExc_ValueError,
5093 "execv() arg 2 first element cannot be empty");
5094 free_string_array(argvlist, argc);
5095 return NULL;
5096 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005097
Steve Dowerbce26262016-11-19 19:17:26 -08005098 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005099#ifdef HAVE_WEXECV
5100 _wexecv(path->wide, argvlist);
5101#else
5102 execv(path->narrow, argvlist);
5103#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005104 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005105
5106 /* If we get here it's definitely an error */
5107
5108 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005109 return posix_error();
5110}
5111
Larry Hastings2f936352014-08-05 14:04:04 +10005112
5113/*[clinic input]
5114os.execve
5115
5116 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5117 Path of executable file.
5118 argv: object
5119 Tuple or list of strings.
5120 env: object
5121 Dictionary of strings mapping to strings.
5122
5123Execute an executable path with arguments, replacing current process.
5124[clinic start generated code]*/
5125
Larry Hastings2f936352014-08-05 14:04:04 +10005126static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005127os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5128/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005129{
Steve Dowercc16be82016-09-08 10:35:16 -07005130 EXECV_CHAR **argvlist = NULL;
5131 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005132 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005133
Victor Stinner8c62be82010-05-06 00:08:46 +00005134 /* execve has three arguments: (path, argv, env), where
5135 argv is a list or tuple of strings and env is a dictionary
5136 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005137
Ross Lagerwall7807c352011-03-17 20:20:30 +02005138 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005139 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005140 "execve: argv must be a tuple or list");
5141 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005142 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005143 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005144 if (argc < 1) {
5145 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5146 return NULL;
5147 }
5148
Victor Stinner8c62be82010-05-06 00:08:46 +00005149 if (!PyMapping_Check(env)) {
5150 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005151 "execve: environment must be a mapping object");
5152 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005154
Ross Lagerwall7807c352011-03-17 20:20:30 +02005155 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005156 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005157 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005158 }
Steve Dowerbce26262016-11-19 19:17:26 -08005159 if (!argvlist[0][0]) {
5160 PyErr_SetString(PyExc_ValueError,
5161 "execve: argv first element cannot be empty");
5162 goto fail;
5163 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005164
Victor Stinner8c62be82010-05-06 00:08:46 +00005165 envlist = parse_envlist(env, &envc);
5166 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005167 goto fail;
5168
Steve Dowerbce26262016-11-19 19:17:26 -08005169 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005170#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005171 if (path->fd > -1)
5172 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005173 else
5174#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005175#ifdef HAVE_WEXECV
5176 _wexecve(path->wide, argvlist, envlist);
5177#else
Larry Hastings2f936352014-08-05 14:04:04 +10005178 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005179#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005180 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005181
5182 /* If we get here it's definitely an error */
5183
Alexey Izbyshev83460312018-10-20 03:28:22 +03005184 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005185
Steve Dowercc16be82016-09-08 10:35:16 -07005186 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005187 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005188 if (argvlist)
5189 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005190 return NULL;
5191}
Steve Dowercc16be82016-09-08 10:35:16 -07005192
Larry Hastings9cf065c2012-06-22 16:30:09 -07005193#endif /* HAVE_EXECV */
5194
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005195#ifdef HAVE_POSIX_SPAWN
5196
5197enum posix_spawn_file_actions_identifier {
5198 POSIX_SPAWN_OPEN,
5199 POSIX_SPAWN_CLOSE,
5200 POSIX_SPAWN_DUP2
5201};
5202
William Orr81574b82018-10-01 22:19:56 -07005203#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005204static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005205convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005206#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005207
5208static int
Victor Stinner325e4ba2019-02-01 15:47:24 +01005209parse_posix_spawn_flags(const char *func_name, PyObject *setpgroup,
5210 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005211 PyObject *setsigdef, PyObject *scheduler,
5212 posix_spawnattr_t *attrp)
5213{
5214 long all_flags = 0;
5215
5216 errno = posix_spawnattr_init(attrp);
5217 if (errno) {
5218 posix_error();
5219 return -1;
5220 }
5221
5222 if (setpgroup) {
5223 pid_t pgid = PyLong_AsPid(setpgroup);
5224 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5225 goto fail;
5226 }
5227 errno = posix_spawnattr_setpgroup(attrp, pgid);
5228 if (errno) {
5229 posix_error();
5230 goto fail;
5231 }
5232 all_flags |= POSIX_SPAWN_SETPGROUP;
5233 }
5234
5235 if (resetids) {
5236 all_flags |= POSIX_SPAWN_RESETIDS;
5237 }
5238
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005239 if (setsid) {
5240#ifdef POSIX_SPAWN_SETSID
5241 all_flags |= POSIX_SPAWN_SETSID;
5242#elif defined(POSIX_SPAWN_SETSID_NP)
5243 all_flags |= POSIX_SPAWN_SETSID_NP;
5244#else
5245 argument_unavailable_error(func_name, "setsid");
5246 return -1;
5247#endif
5248 }
5249
Pablo Galindo254a4662018-09-07 16:44:24 +01005250 if (setsigmask) {
5251 sigset_t set;
5252 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5253 goto fail;
5254 }
5255 errno = posix_spawnattr_setsigmask(attrp, &set);
5256 if (errno) {
5257 posix_error();
5258 goto fail;
5259 }
5260 all_flags |= POSIX_SPAWN_SETSIGMASK;
5261 }
5262
5263 if (setsigdef) {
5264 sigset_t set;
5265 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5266 goto fail;
5267 }
5268 errno = posix_spawnattr_setsigdefault(attrp, &set);
5269 if (errno) {
5270 posix_error();
5271 goto fail;
5272 }
5273 all_flags |= POSIX_SPAWN_SETSIGDEF;
5274 }
5275
5276 if (scheduler) {
5277#ifdef POSIX_SPAWN_SETSCHEDULER
5278 PyObject *py_schedpolicy;
5279 struct sched_param schedparam;
5280
5281 if (!PyArg_ParseTuple(scheduler, "OO&"
5282 ";A scheduler tuple must have two elements",
5283 &py_schedpolicy, convert_sched_param, &schedparam)) {
5284 goto fail;
5285 }
5286 if (py_schedpolicy != Py_None) {
5287 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5288
5289 if (schedpolicy == -1 && PyErr_Occurred()) {
5290 goto fail;
5291 }
5292 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5293 if (errno) {
5294 posix_error();
5295 goto fail;
5296 }
5297 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5298 }
5299 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5300 if (errno) {
5301 posix_error();
5302 goto fail;
5303 }
5304 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5305#else
5306 PyErr_SetString(PyExc_NotImplementedError,
5307 "The scheduler option is not supported in this system.");
5308 goto fail;
5309#endif
5310 }
5311
5312 errno = posix_spawnattr_setflags(attrp, all_flags);
5313 if (errno) {
5314 posix_error();
5315 goto fail;
5316 }
5317
5318 return 0;
5319
5320fail:
5321 (void)posix_spawnattr_destroy(attrp);
5322 return -1;
5323}
5324
5325static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005326parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005327 posix_spawn_file_actions_t *file_actionsp,
5328 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005329{
5330 PyObject *seq;
5331 PyObject *file_action = NULL;
5332 PyObject *tag_obj;
5333
5334 seq = PySequence_Fast(file_actions,
5335 "file_actions must be a sequence or None");
5336 if (seq == NULL) {
5337 return -1;
5338 }
5339
5340 errno = posix_spawn_file_actions_init(file_actionsp);
5341 if (errno) {
5342 posix_error();
5343 Py_DECREF(seq);
5344 return -1;
5345 }
5346
5347 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5348 file_action = PySequence_Fast_GET_ITEM(seq, i);
5349 Py_INCREF(file_action);
5350 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5351 PyErr_SetString(PyExc_TypeError,
5352 "Each file_actions element must be a non-empty tuple");
5353 goto fail;
5354 }
5355 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5356 if (tag == -1 && PyErr_Occurred()) {
5357 goto fail;
5358 }
5359
5360 /* Populate the file_actions object */
5361 switch (tag) {
5362 case POSIX_SPAWN_OPEN: {
5363 int fd, oflag;
5364 PyObject *path;
5365 unsigned long mode;
5366 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5367 ";A open file_action tuple must have 5 elements",
5368 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5369 &oflag, &mode))
5370 {
5371 goto fail;
5372 }
Pablo Galindocb970732018-06-19 09:19:50 +01005373 if (PyList_Append(temp_buffer, path)) {
5374 Py_DECREF(path);
5375 goto fail;
5376 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005377 errno = posix_spawn_file_actions_addopen(file_actionsp,
5378 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005379 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005380 if (errno) {
5381 posix_error();
5382 goto fail;
5383 }
5384 break;
5385 }
5386 case POSIX_SPAWN_CLOSE: {
5387 int fd;
5388 if (!PyArg_ParseTuple(file_action, "Oi"
5389 ";A close file_action tuple must have 2 elements",
5390 &tag_obj, &fd))
5391 {
5392 goto fail;
5393 }
5394 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5395 if (errno) {
5396 posix_error();
5397 goto fail;
5398 }
5399 break;
5400 }
5401 case POSIX_SPAWN_DUP2: {
5402 int fd1, fd2;
5403 if (!PyArg_ParseTuple(file_action, "Oii"
5404 ";A dup2 file_action tuple must have 3 elements",
5405 &tag_obj, &fd1, &fd2))
5406 {
5407 goto fail;
5408 }
5409 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5410 fd1, fd2);
5411 if (errno) {
5412 posix_error();
5413 goto fail;
5414 }
5415 break;
5416 }
5417 default: {
5418 PyErr_SetString(PyExc_TypeError,
5419 "Unknown file_actions identifier");
5420 goto fail;
5421 }
5422 }
5423 Py_DECREF(file_action);
5424 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005425
Serhiy Storchakaef347532018-05-01 16:45:04 +03005426 Py_DECREF(seq);
5427 return 0;
5428
5429fail:
5430 Py_DECREF(seq);
5431 Py_DECREF(file_action);
5432 (void)posix_spawn_file_actions_destroy(file_actionsp);
5433 return -1;
5434}
5435
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005436
5437static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005438py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5439 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005440 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005441 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005442{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005443 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005444 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005445 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005446 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005447 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005448 posix_spawnattr_t attr;
5449 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005450 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005451 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005452 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005453 pid_t pid;
5454 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005455
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005456 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005457 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005458 like posix.environ. */
5459
Serhiy Storchakaef347532018-05-01 16:45:04 +03005460 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005461 PyErr_Format(PyExc_TypeError,
5462 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005463 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005464 }
5465 argc = PySequence_Size(argv);
5466 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005467 PyErr_Format(PyExc_ValueError,
5468 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005469 return NULL;
5470 }
5471
5472 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005473 PyErr_Format(PyExc_TypeError,
5474 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005475 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005476 }
5477
5478 argvlist = parse_arglist(argv, &argc);
5479 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005480 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005481 }
5482 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005483 PyErr_Format(PyExc_ValueError,
5484 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005485 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005486 }
5487
5488 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005489 if (envlist == NULL) {
5490 goto exit;
5491 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005492
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005493 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005494 /* There is a bug in old versions of glibc that makes some of the
5495 * helper functions for manipulating file actions not copy the provided
5496 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5497 * copy the value of path for some old versions of glibc (<2.20).
5498 * The use of temp_buffer here is a workaround that keeps the
5499 * python objects that own the buffers alive until posix_spawn gets called.
5500 * Check https://bugs.python.org/issue33630 and
5501 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5502 temp_buffer = PyList_New(0);
5503 if (!temp_buffer) {
5504 goto exit;
5505 }
5506 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005507 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005508 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005509 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005510 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005511
Victor Stinner325e4ba2019-02-01 15:47:24 +01005512 if (parse_posix_spawn_flags(func_name, setpgroup, resetids, setsid,
5513 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005514 goto exit;
5515 }
5516 attrp = &attr;
5517
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005518 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005519#ifdef HAVE_POSIX_SPAWNP
5520 if (use_posix_spawnp) {
5521 err_code = posix_spawnp(&pid, path->narrow,
5522 file_actionsp, attrp, argvlist, envlist);
5523 }
5524 else
5525#endif /* HAVE_POSIX_SPAWNP */
5526 {
5527 err_code = posix_spawn(&pid, path->narrow,
5528 file_actionsp, attrp, argvlist, envlist);
5529 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005530 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005531
Serhiy Storchakaef347532018-05-01 16:45:04 +03005532 if (err_code) {
5533 errno = err_code;
5534 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005535 goto exit;
5536 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005537#ifdef _Py_MEMORY_SANITIZER
5538 __msan_unpoison(&pid, sizeof(pid));
5539#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005540 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005541
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005542exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005543 if (file_actionsp) {
5544 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005545 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005546 if (attrp) {
5547 (void)posix_spawnattr_destroy(attrp);
5548 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005549 if (envlist) {
5550 free_string_array(envlist, envc);
5551 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005552 if (argvlist) {
5553 free_string_array(argvlist, argc);
5554 }
Pablo Galindocb970732018-06-19 09:19:50 +01005555 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005556 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005557}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005558
5559
5560/*[clinic input]
5561
5562os.posix_spawn
5563 path: path_t
5564 Path of executable file.
5565 argv: object
5566 Tuple or list of strings.
5567 env: object
5568 Dictionary of strings mapping to strings.
5569 /
5570 *
5571 file_actions: object(c_default='NULL') = ()
5572 A sequence of file action tuples.
5573 setpgroup: object = NULL
5574 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5575 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005576 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5577 setsid: bool(accept={int}) = False
5578 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005579 setsigmask: object(c_default='NULL') = ()
5580 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5581 setsigdef: object(c_default='NULL') = ()
5582 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5583 scheduler: object = NULL
5584 A tuple with the scheduler policy (optional) and parameters.
5585
5586Execute the program specified by path in a new process.
5587[clinic start generated code]*/
5588
5589static PyObject *
5590os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5591 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005592 PyObject *setpgroup, int resetids, int setsid,
5593 PyObject *setsigmask, PyObject *setsigdef,
5594 PyObject *scheduler)
5595/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005596{
5597 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005598 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005599 scheduler);
5600}
5601 #endif /* HAVE_POSIX_SPAWN */
5602
5603
5604
5605#ifdef HAVE_POSIX_SPAWNP
5606/*[clinic input]
5607
5608os.posix_spawnp
5609 path: path_t
5610 Path of executable file.
5611 argv: object
5612 Tuple or list of strings.
5613 env: object
5614 Dictionary of strings mapping to strings.
5615 /
5616 *
5617 file_actions: object(c_default='NULL') = ()
5618 A sequence of file action tuples.
5619 setpgroup: object = NULL
5620 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5621 resetids: bool(accept={int}) = False
5622 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005623 setsid: bool(accept={int}) = False
5624 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005625 setsigmask: object(c_default='NULL') = ()
5626 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5627 setsigdef: object(c_default='NULL') = ()
5628 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5629 scheduler: object = NULL
5630 A tuple with the scheduler policy (optional) and parameters.
5631
5632Execute the program specified by path in a new process.
5633[clinic start generated code]*/
5634
5635static PyObject *
5636os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5637 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005638 PyObject *setpgroup, int resetids, int setsid,
5639 PyObject *setsigmask, PyObject *setsigdef,
5640 PyObject *scheduler)
5641/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005642{
5643 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005644 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005645 scheduler);
5646}
5647#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005648
pxinwrf2d7ac72019-05-21 18:46:37 +08005649#ifdef HAVE_RTPSPAWN
5650static intptr_t
5651_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5652 const char *envp[])
5653{
5654 RTP_ID rtpid;
5655 int status;
5656 pid_t res;
5657 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005658
pxinwrf2d7ac72019-05-21 18:46:37 +08005659 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5660 uStackSize=0 cannot be used, the default stack size is too small for
5661 Python. */
5662 if (envp) {
5663 rtpid = rtpSpawn(rtpFileName, argv, envp,
5664 100, 0x1000000, 0, VX_FP_TASK);
5665 }
5666 else {
5667 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5668 100, 0x1000000, 0, VX_FP_TASK);
5669 }
5670 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5671 do {
5672 res = waitpid((pid_t)rtpid, &status, 0);
5673 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5674
5675 if (res < 0)
5676 return RTP_ID_ERROR;
5677 return ((intptr_t)status);
5678 }
5679 return ((intptr_t)rtpid);
5680}
5681#endif
5682
5683#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10005684/*[clinic input]
5685os.spawnv
5686
5687 mode: int
5688 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005689 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005690 Path of executable file.
5691 argv: object
5692 Tuple or list of strings.
5693 /
5694
5695Execute the program specified by path in a new process.
5696[clinic start generated code]*/
5697
Larry Hastings2f936352014-08-05 14:04:04 +10005698static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005699os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5700/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005701{
Steve Dowercc16be82016-09-08 10:35:16 -07005702 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005703 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005704 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005705 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005706 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005707
Victor Stinner8c62be82010-05-06 00:08:46 +00005708 /* spawnv has three arguments: (mode, path, argv), where
5709 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005710
Victor Stinner8c62be82010-05-06 00:08:46 +00005711 if (PyList_Check(argv)) {
5712 argc = PyList_Size(argv);
5713 getitem = PyList_GetItem;
5714 }
5715 else if (PyTuple_Check(argv)) {
5716 argc = PyTuple_Size(argv);
5717 getitem = PyTuple_GetItem;
5718 }
5719 else {
5720 PyErr_SetString(PyExc_TypeError,
5721 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005722 return NULL;
5723 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005724 if (argc == 0) {
5725 PyErr_SetString(PyExc_ValueError,
5726 "spawnv() arg 2 cannot be empty");
5727 return NULL;
5728 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005729
Steve Dowercc16be82016-09-08 10:35:16 -07005730 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005731 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005732 return PyErr_NoMemory();
5733 }
5734 for (i = 0; i < argc; i++) {
5735 if (!fsconvert_strdup((*getitem)(argv, i),
5736 &argvlist[i])) {
5737 free_string_array(argvlist, i);
5738 PyErr_SetString(
5739 PyExc_TypeError,
5740 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005741 return NULL;
5742 }
Steve Dower93ff8722016-11-19 19:03:54 -08005743 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005744 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005745 PyErr_SetString(
5746 PyExc_ValueError,
5747 "spawnv() arg 2 first element cannot be empty");
5748 return NULL;
5749 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005750 }
5751 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005752
pxinwrf2d7ac72019-05-21 18:46:37 +08005753#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005754 if (mode == _OLD_P_OVERLAY)
5755 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005756#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005757
Victor Stinner8c62be82010-05-06 00:08:46 +00005758 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005759 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005760#ifdef HAVE_WSPAWNV
5761 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005762#elif defined(HAVE_RTPSPAWN)
5763 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07005764#else
5765 spawnval = _spawnv(mode, path->narrow, argvlist);
5766#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005767 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005768 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005769
Victor Stinner8c62be82010-05-06 00:08:46 +00005770 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005771
Victor Stinner8c62be82010-05-06 00:08:46 +00005772 if (spawnval == -1)
5773 return posix_error();
5774 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005775 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005776}
5777
Larry Hastings2f936352014-08-05 14:04:04 +10005778/*[clinic input]
5779os.spawnve
5780
5781 mode: int
5782 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005783 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005784 Path of executable file.
5785 argv: object
5786 Tuple or list of strings.
5787 env: object
5788 Dictionary of strings mapping to strings.
5789 /
5790
5791Execute the program specified by path in a new process.
5792[clinic start generated code]*/
5793
Larry Hastings2f936352014-08-05 14:04:04 +10005794static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005795os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005796 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005797/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005798{
Steve Dowercc16be82016-09-08 10:35:16 -07005799 EXECV_CHAR **argvlist;
5800 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005801 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005802 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005803 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005804 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005805 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005806
Victor Stinner8c62be82010-05-06 00:08:46 +00005807 /* spawnve has four arguments: (mode, path, argv, env), where
5808 argv is a list or tuple of strings and env is a dictionary
5809 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005810
Victor Stinner8c62be82010-05-06 00:08:46 +00005811 if (PyList_Check(argv)) {
5812 argc = PyList_Size(argv);
5813 getitem = PyList_GetItem;
5814 }
5815 else if (PyTuple_Check(argv)) {
5816 argc = PyTuple_Size(argv);
5817 getitem = PyTuple_GetItem;
5818 }
5819 else {
5820 PyErr_SetString(PyExc_TypeError,
5821 "spawnve() arg 2 must be a tuple or list");
5822 goto fail_0;
5823 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005824 if (argc == 0) {
5825 PyErr_SetString(PyExc_ValueError,
5826 "spawnve() arg 2 cannot be empty");
5827 goto fail_0;
5828 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005829 if (!PyMapping_Check(env)) {
5830 PyErr_SetString(PyExc_TypeError,
5831 "spawnve() arg 3 must be a mapping object");
5832 goto fail_0;
5833 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005834
Steve Dowercc16be82016-09-08 10:35:16 -07005835 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005836 if (argvlist == NULL) {
5837 PyErr_NoMemory();
5838 goto fail_0;
5839 }
5840 for (i = 0; i < argc; i++) {
5841 if (!fsconvert_strdup((*getitem)(argv, i),
5842 &argvlist[i]))
5843 {
5844 lastarg = i;
5845 goto fail_1;
5846 }
Steve Dowerbce26262016-11-19 19:17:26 -08005847 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005848 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005849 PyErr_SetString(
5850 PyExc_ValueError,
5851 "spawnv() arg 2 first element cannot be empty");
5852 goto fail_1;
5853 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005854 }
5855 lastarg = argc;
5856 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005857
Victor Stinner8c62be82010-05-06 00:08:46 +00005858 envlist = parse_envlist(env, &envc);
5859 if (envlist == NULL)
5860 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005861
pxinwrf2d7ac72019-05-21 18:46:37 +08005862#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005863 if (mode == _OLD_P_OVERLAY)
5864 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005865#endif
Tim Peters25059d32001-12-07 20:35:43 +00005866
Victor Stinner8c62be82010-05-06 00:08:46 +00005867 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005868 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005869#ifdef HAVE_WSPAWNV
5870 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005871#elif defined(HAVE_RTPSPAWN)
5872 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
5873 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005874#else
5875 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5876#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005877 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005878 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005879
Victor Stinner8c62be82010-05-06 00:08:46 +00005880 if (spawnval == -1)
5881 (void) posix_error();
5882 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005883 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005884
Victor Stinner8c62be82010-05-06 00:08:46 +00005885 while (--envc >= 0)
5886 PyMem_DEL(envlist[envc]);
5887 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005888 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005889 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005890 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005891 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005892}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005893
Guido van Rossuma1065681999-01-25 23:20:23 +00005894#endif /* HAVE_SPAWNV */
5895
5896
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005897#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005898
5899/* Helper function to validate arguments.
5900 Returns 0 on success. non-zero on failure with a TypeError raised.
5901 If obj is non-NULL it must be callable. */
5902static int
5903check_null_or_callable(PyObject *obj, const char* obj_name)
5904{
5905 if (obj && !PyCallable_Check(obj)) {
5906 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5907 obj_name, Py_TYPE(obj)->tp_name);
5908 return -1;
5909 }
5910 return 0;
5911}
5912
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005913/*[clinic input]
5914os.register_at_fork
5915
Gregory P. Smith163468a2017-05-29 10:03:41 -07005916 *
5917 before: object=NULL
5918 A callable to be called in the parent before the fork() syscall.
5919 after_in_child: object=NULL
5920 A callable to be called in the child after fork().
5921 after_in_parent: object=NULL
5922 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005923
Gregory P. Smith163468a2017-05-29 10:03:41 -07005924Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005925
Gregory P. Smith163468a2017-05-29 10:03:41 -07005926'before' callbacks are called in reverse order.
5927'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005928
5929[clinic start generated code]*/
5930
5931static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005932os_register_at_fork_impl(PyObject *module, PyObject *before,
5933 PyObject *after_in_child, PyObject *after_in_parent)
5934/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005935{
5936 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005937
Gregory P. Smith163468a2017-05-29 10:03:41 -07005938 if (!before && !after_in_child && !after_in_parent) {
5939 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5940 return NULL;
5941 }
5942 if (check_null_or_callable(before, "before") ||
5943 check_null_or_callable(after_in_child, "after_in_child") ||
5944 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005945 return NULL;
5946 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02005947 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005948
Gregory P. Smith163468a2017-05-29 10:03:41 -07005949 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005950 return NULL;
5951 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005952 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005953 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005954 }
5955 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5956 return NULL;
5957 }
5958 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005959}
5960#endif /* HAVE_FORK */
5961
5962
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005963#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005964/*[clinic input]
5965os.fork1
5966
5967Fork a child process with a single multiplexed (i.e., not bound) thread.
5968
5969Return 0 to child process and PID of child to parent process.
5970[clinic start generated code]*/
5971
Larry Hastings2f936352014-08-05 14:04:04 +10005972static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005973os_fork1_impl(PyObject *module)
5974/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005975{
Victor Stinner8c62be82010-05-06 00:08:46 +00005976 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005977
Eric Snow59032962018-09-14 14:17:20 -07005978 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5979 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5980 return NULL;
5981 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005982 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005983 pid = fork1();
5984 if (pid == 0) {
5985 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005986 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005987 } else {
5988 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005989 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005990 }
5991 if (pid == -1)
5992 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005993 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005994}
Larry Hastings2f936352014-08-05 14:04:04 +10005995#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005996
5997
Guido van Rossumad0ee831995-03-01 10:34:45 +00005998#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005999/*[clinic input]
6000os.fork
6001
6002Fork a child process.
6003
6004Return 0 to child process and PID of child to parent process.
6005[clinic start generated code]*/
6006
Larry Hastings2f936352014-08-05 14:04:04 +10006007static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006008os_fork_impl(PyObject *module)
6009/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006010{
Victor Stinner8c62be82010-05-06 00:08:46 +00006011 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006012
Eric Snow59032962018-09-14 14:17:20 -07006013 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6014 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6015 return NULL;
6016 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006017 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 pid = fork();
6019 if (pid == 0) {
6020 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006021 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006022 } else {
6023 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006024 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006025 }
6026 if (pid == -1)
6027 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006029}
Larry Hastings2f936352014-08-05 14:04:04 +10006030#endif /* HAVE_FORK */
6031
Guido van Rossum85e3b011991-06-03 12:42:10 +00006032
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006033#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006034#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006035/*[clinic input]
6036os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006037
Larry Hastings2f936352014-08-05 14:04:04 +10006038 policy: int
6039
6040Get the maximum scheduling priority for policy.
6041[clinic start generated code]*/
6042
Larry Hastings2f936352014-08-05 14:04:04 +10006043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006044os_sched_get_priority_max_impl(PyObject *module, int policy)
6045/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006046{
6047 int max;
6048
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006049 max = sched_get_priority_max(policy);
6050 if (max < 0)
6051 return posix_error();
6052 return PyLong_FromLong(max);
6053}
6054
Larry Hastings2f936352014-08-05 14:04:04 +10006055
6056/*[clinic input]
6057os.sched_get_priority_min
6058
6059 policy: int
6060
6061Get the minimum scheduling priority for policy.
6062[clinic start generated code]*/
6063
Larry Hastings2f936352014-08-05 14:04:04 +10006064static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006065os_sched_get_priority_min_impl(PyObject *module, int policy)
6066/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006067{
6068 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006069 if (min < 0)
6070 return posix_error();
6071 return PyLong_FromLong(min);
6072}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006073#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6074
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006075
Larry Hastings2f936352014-08-05 14:04:04 +10006076#ifdef HAVE_SCHED_SETSCHEDULER
6077/*[clinic input]
6078os.sched_getscheduler
6079 pid: pid_t
6080 /
6081
6082Get the scheduling policy for the process identifiedy by pid.
6083
6084Passing 0 for pid returns the scheduling policy for the calling process.
6085[clinic start generated code]*/
6086
Larry Hastings2f936352014-08-05 14:04:04 +10006087static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006088os_sched_getscheduler_impl(PyObject *module, pid_t pid)
6089/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006090{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006091 int policy;
6092
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006093 policy = sched_getscheduler(pid);
6094 if (policy < 0)
6095 return posix_error();
6096 return PyLong_FromLong(policy);
6097}
Larry Hastings2f936352014-08-05 14:04:04 +10006098#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006099
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006100
William Orr81574b82018-10-01 22:19:56 -07006101#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006102/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006103class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006104
6105@classmethod
6106os.sched_param.__new__
6107
6108 sched_priority: object
6109 A scheduling parameter.
6110
6111Current has only one field: sched_priority");
6112[clinic start generated code]*/
6113
Larry Hastings2f936352014-08-05 14:04:04 +10006114static PyObject *
6115os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006116/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006117{
6118 PyObject *res;
6119
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006120 res = PyStructSequence_New(type);
6121 if (!res)
6122 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006123 Py_INCREF(sched_priority);
6124 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006125 return res;
6126}
6127
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006128
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006129PyDoc_VAR(os_sched_param__doc__);
6130
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006131static PyStructSequence_Field sched_param_fields[] = {
6132 {"sched_priority", "the scheduling priority"},
6133 {0}
6134};
6135
6136static PyStructSequence_Desc sched_param_desc = {
6137 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006138 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006139 sched_param_fields,
6140 1
6141};
6142
6143static int
6144convert_sched_param(PyObject *param, struct sched_param *res)
6145{
6146 long priority;
6147
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006148 if (Py_TYPE(param) != SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006149 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6150 return 0;
6151 }
6152 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6153 if (priority == -1 && PyErr_Occurred())
6154 return 0;
6155 if (priority > INT_MAX || priority < INT_MIN) {
6156 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6157 return 0;
6158 }
6159 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6160 return 1;
6161}
William Orr81574b82018-10-01 22:19:56 -07006162#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006163
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006164
6165#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006166/*[clinic input]
6167os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006168
Larry Hastings2f936352014-08-05 14:04:04 +10006169 pid: pid_t
6170 policy: int
6171 param: sched_param
6172 /
6173
6174Set the scheduling policy for the process identified by pid.
6175
6176If pid is 0, the calling process is changed.
6177param is an instance of sched_param.
6178[clinic start generated code]*/
6179
Larry Hastings2f936352014-08-05 14:04:04 +10006180static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006181os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006182 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006183/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006184{
Jesus Cea9c822272011-09-10 01:40:52 +02006185 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006186 ** sched_setscheduler() returns 0 in Linux, but the previous
6187 ** scheduling policy under Solaris/Illumos, and others.
6188 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006189 */
Larry Hastings2f936352014-08-05 14:04:04 +10006190 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006191 return posix_error();
6192 Py_RETURN_NONE;
6193}
Larry Hastings2f936352014-08-05 14:04:04 +10006194#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006195
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006196
6197#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006198/*[clinic input]
6199os.sched_getparam
6200 pid: pid_t
6201 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006202
Larry Hastings2f936352014-08-05 14:04:04 +10006203Returns scheduling parameters for the process identified by pid.
6204
6205If pid is 0, returns parameters for the calling process.
6206Return value is an instance of sched_param.
6207[clinic start generated code]*/
6208
Larry Hastings2f936352014-08-05 14:04:04 +10006209static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006210os_sched_getparam_impl(PyObject *module, pid_t pid)
6211/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006212{
6213 struct sched_param param;
6214 PyObject *result;
6215 PyObject *priority;
6216
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006217 if (sched_getparam(pid, &param))
6218 return posix_error();
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006219 result = PyStructSequence_New(SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006220 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006221 return NULL;
6222 priority = PyLong_FromLong(param.sched_priority);
6223 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006224 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006225 return NULL;
6226 }
Larry Hastings2f936352014-08-05 14:04:04 +10006227 PyStructSequence_SET_ITEM(result, 0, priority);
6228 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006229}
6230
Larry Hastings2f936352014-08-05 14:04:04 +10006231
6232/*[clinic input]
6233os.sched_setparam
6234 pid: pid_t
6235 param: sched_param
6236 /
6237
6238Set scheduling parameters for the process identified by pid.
6239
6240If pid is 0, sets parameters for the calling process.
6241param should be an instance of sched_param.
6242[clinic start generated code]*/
6243
Larry Hastings2f936352014-08-05 14:04:04 +10006244static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006245os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006246 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006247/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006248{
6249 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006250 return posix_error();
6251 Py_RETURN_NONE;
6252}
Larry Hastings2f936352014-08-05 14:04:04 +10006253#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006254
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006255
6256#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006257/*[clinic input]
6258os.sched_rr_get_interval -> double
6259 pid: pid_t
6260 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006261
Larry Hastings2f936352014-08-05 14:04:04 +10006262Return the round-robin quantum for the process identified by pid, in seconds.
6263
6264Value returned is a float.
6265[clinic start generated code]*/
6266
Larry Hastings2f936352014-08-05 14:04:04 +10006267static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006268os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6269/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006270{
6271 struct timespec interval;
6272 if (sched_rr_get_interval(pid, &interval)) {
6273 posix_error();
6274 return -1.0;
6275 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006276#ifdef _Py_MEMORY_SANITIZER
6277 __msan_unpoison(&interval, sizeof(interval));
6278#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006279 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6280}
6281#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006282
Larry Hastings2f936352014-08-05 14:04:04 +10006283
6284/*[clinic input]
6285os.sched_yield
6286
6287Voluntarily relinquish the CPU.
6288[clinic start generated code]*/
6289
Larry Hastings2f936352014-08-05 14:04:04 +10006290static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006291os_sched_yield_impl(PyObject *module)
6292/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006293{
6294 if (sched_yield())
6295 return posix_error();
6296 Py_RETURN_NONE;
6297}
6298
Benjamin Peterson2740af82011-08-02 17:41:34 -05006299#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006300/* The minimum number of CPUs allocated in a cpu_set_t */
6301static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006302
Larry Hastings2f936352014-08-05 14:04:04 +10006303/*[clinic input]
6304os.sched_setaffinity
6305 pid: pid_t
6306 mask : object
6307 /
6308
6309Set the CPU affinity of the process identified by pid to mask.
6310
6311mask should be an iterable of integers identifying CPUs.
6312[clinic start generated code]*/
6313
Larry Hastings2f936352014-08-05 14:04:04 +10006314static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006315os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6316/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006317{
Antoine Pitrou84869872012-08-04 16:16:35 +02006318 int ncpus;
6319 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006320 cpu_set_t *cpu_set = NULL;
6321 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006322
Larry Hastings2f936352014-08-05 14:04:04 +10006323 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006324 if (iterator == NULL)
6325 return NULL;
6326
6327 ncpus = NCPUS_START;
6328 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006329 cpu_set = CPU_ALLOC(ncpus);
6330 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006331 PyErr_NoMemory();
6332 goto error;
6333 }
Larry Hastings2f936352014-08-05 14:04:04 +10006334 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006335
6336 while ((item = PyIter_Next(iterator))) {
6337 long cpu;
6338 if (!PyLong_Check(item)) {
6339 PyErr_Format(PyExc_TypeError,
6340 "expected an iterator of ints, "
6341 "but iterator yielded %R",
6342 Py_TYPE(item));
6343 Py_DECREF(item);
6344 goto error;
6345 }
6346 cpu = PyLong_AsLong(item);
6347 Py_DECREF(item);
6348 if (cpu < 0) {
6349 if (!PyErr_Occurred())
6350 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6351 goto error;
6352 }
6353 if (cpu > INT_MAX - 1) {
6354 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6355 goto error;
6356 }
6357 if (cpu >= ncpus) {
6358 /* Grow CPU mask to fit the CPU number */
6359 int newncpus = ncpus;
6360 cpu_set_t *newmask;
6361 size_t newsetsize;
6362 while (newncpus <= cpu) {
6363 if (newncpus > INT_MAX / 2)
6364 newncpus = cpu + 1;
6365 else
6366 newncpus = newncpus * 2;
6367 }
6368 newmask = CPU_ALLOC(newncpus);
6369 if (newmask == NULL) {
6370 PyErr_NoMemory();
6371 goto error;
6372 }
6373 newsetsize = CPU_ALLOC_SIZE(newncpus);
6374 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006375 memcpy(newmask, cpu_set, setsize);
6376 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006377 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006378 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006379 ncpus = newncpus;
6380 }
Larry Hastings2f936352014-08-05 14:04:04 +10006381 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006382 }
6383 Py_CLEAR(iterator);
6384
Larry Hastings2f936352014-08-05 14:04:04 +10006385 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006386 posix_error();
6387 goto error;
6388 }
Larry Hastings2f936352014-08-05 14:04:04 +10006389 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006390 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006391
6392error:
Larry Hastings2f936352014-08-05 14:04:04 +10006393 if (cpu_set)
6394 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006395 Py_XDECREF(iterator);
6396 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006397}
6398
Larry Hastings2f936352014-08-05 14:04:04 +10006399
6400/*[clinic input]
6401os.sched_getaffinity
6402 pid: pid_t
6403 /
6404
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006405Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006406
6407The affinity is returned as a set of CPU identifiers.
6408[clinic start generated code]*/
6409
Larry Hastings2f936352014-08-05 14:04:04 +10006410static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006411os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006412/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006413{
Antoine Pitrou84869872012-08-04 16:16:35 +02006414 int cpu, ncpus, count;
6415 size_t setsize;
6416 cpu_set_t *mask = NULL;
6417 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006418
Antoine Pitrou84869872012-08-04 16:16:35 +02006419 ncpus = NCPUS_START;
6420 while (1) {
6421 setsize = CPU_ALLOC_SIZE(ncpus);
6422 mask = CPU_ALLOC(ncpus);
6423 if (mask == NULL)
6424 return PyErr_NoMemory();
6425 if (sched_getaffinity(pid, setsize, mask) == 0)
6426 break;
6427 CPU_FREE(mask);
6428 if (errno != EINVAL)
6429 return posix_error();
6430 if (ncpus > INT_MAX / 2) {
6431 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6432 "a large enough CPU set");
6433 return NULL;
6434 }
6435 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006436 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006437
6438 res = PySet_New(NULL);
6439 if (res == NULL)
6440 goto error;
6441 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6442 if (CPU_ISSET_S(cpu, setsize, mask)) {
6443 PyObject *cpu_num = PyLong_FromLong(cpu);
6444 --count;
6445 if (cpu_num == NULL)
6446 goto error;
6447 if (PySet_Add(res, cpu_num)) {
6448 Py_DECREF(cpu_num);
6449 goto error;
6450 }
6451 Py_DECREF(cpu_num);
6452 }
6453 }
6454 CPU_FREE(mask);
6455 return res;
6456
6457error:
6458 if (mask)
6459 CPU_FREE(mask);
6460 Py_XDECREF(res);
6461 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006462}
6463
Benjamin Peterson2740af82011-08-02 17:41:34 -05006464#endif /* HAVE_SCHED_SETAFFINITY */
6465
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006466#endif /* HAVE_SCHED_H */
6467
Larry Hastings2f936352014-08-05 14:04:04 +10006468
Neal Norwitzb59798b2003-03-21 01:43:31 +00006469/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006470/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6471#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006472#define DEV_PTY_FILE "/dev/ptc"
6473#define HAVE_DEV_PTMX
6474#else
6475#define DEV_PTY_FILE "/dev/ptmx"
6476#endif
6477
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006478#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006479#ifdef HAVE_PTY_H
6480#include <pty.h>
6481#else
6482#ifdef HAVE_LIBUTIL_H
6483#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006484#else
6485#ifdef HAVE_UTIL_H
6486#include <util.h>
6487#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006488#endif /* HAVE_LIBUTIL_H */
6489#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006490#ifdef HAVE_STROPTS_H
6491#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006492#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006493#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006494
Larry Hastings2f936352014-08-05 14:04:04 +10006495
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006496#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006497/*[clinic input]
6498os.openpty
6499
6500Open a pseudo-terminal.
6501
6502Return a tuple of (master_fd, slave_fd) containing open file descriptors
6503for both the master and slave ends.
6504[clinic start generated code]*/
6505
Larry Hastings2f936352014-08-05 14:04:04 +10006506static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006507os_openpty_impl(PyObject *module)
6508/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006509{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006510 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006511#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006512 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006513#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006514#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006515 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006516#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006517 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006518#endif
6519#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006520
Thomas Wouters70c21a12000-07-14 14:28:33 +00006521#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006522 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006523 goto posix_error;
6524
6525 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6526 goto error;
6527 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6528 goto error;
6529
Neal Norwitzb59798b2003-03-21 01:43:31 +00006530#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006531 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6532 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006533 goto posix_error;
6534 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6535 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006536
Victor Stinnerdaf45552013-08-28 00:53:59 +02006537 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006538 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006539 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006540
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006541#else
Victor Stinner000de532013-11-25 23:19:58 +01006542 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006543 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006544 goto posix_error;
6545
Victor Stinner8c62be82010-05-06 00:08:46 +00006546 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006547
Victor Stinner8c62be82010-05-06 00:08:46 +00006548 /* change permission of slave */
6549 if (grantpt(master_fd) < 0) {
6550 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006551 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006553
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 /* unlock slave */
6555 if (unlockpt(master_fd) < 0) {
6556 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006557 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006558 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006559
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006561
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 slave_name = ptsname(master_fd); /* get name of slave */
6563 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006564 goto posix_error;
6565
6566 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006567 if (slave_fd == -1)
6568 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006569
6570 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6571 goto posix_error;
6572
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006573#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006574 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6575 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006576#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006577 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006578#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006579#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006580#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006581
Victor Stinner8c62be82010-05-06 00:08:46 +00006582 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006583
Victor Stinnerdaf45552013-08-28 00:53:59 +02006584posix_error:
6585 posix_error();
6586error:
6587 if (master_fd != -1)
6588 close(master_fd);
6589 if (slave_fd != -1)
6590 close(slave_fd);
6591 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006592}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006593#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006594
Larry Hastings2f936352014-08-05 14:04:04 +10006595
Fred Drake8cef4cf2000-06-28 16:40:38 +00006596#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006597/*[clinic input]
6598os.forkpty
6599
6600Fork a new process with a new pseudo-terminal as controlling tty.
6601
6602Returns a tuple of (pid, master_fd).
6603Like fork(), return pid of 0 to the child process,
6604and pid of child to the parent process.
6605To both, return fd of newly opened pseudo-terminal.
6606[clinic start generated code]*/
6607
Larry Hastings2f936352014-08-05 14:04:04 +10006608static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006609os_forkpty_impl(PyObject *module)
6610/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006611{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006612 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006614
Eric Snow59032962018-09-14 14:17:20 -07006615 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6616 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6617 return NULL;
6618 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006619 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006620 pid = forkpty(&master_fd, NULL, NULL, NULL);
6621 if (pid == 0) {
6622 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006623 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006624 } else {
6625 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006626 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006627 }
6628 if (pid == -1)
6629 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006630 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006631}
Larry Hastings2f936352014-08-05 14:04:04 +10006632#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006633
Ross Lagerwall7807c352011-03-17 20:20:30 +02006634
Guido van Rossumad0ee831995-03-01 10:34:45 +00006635#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006636/*[clinic input]
6637os.getegid
6638
6639Return the current process's effective group id.
6640[clinic start generated code]*/
6641
Larry Hastings2f936352014-08-05 14:04:04 +10006642static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006643os_getegid_impl(PyObject *module)
6644/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006645{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006646 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006647}
Larry Hastings2f936352014-08-05 14:04:04 +10006648#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006649
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006650
Guido van Rossumad0ee831995-03-01 10:34:45 +00006651#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006652/*[clinic input]
6653os.geteuid
6654
6655Return the current process's effective user id.
6656[clinic start generated code]*/
6657
Larry Hastings2f936352014-08-05 14:04:04 +10006658static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006659os_geteuid_impl(PyObject *module)
6660/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006661{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006662 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006663}
Larry Hastings2f936352014-08-05 14:04:04 +10006664#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006666
Guido van Rossumad0ee831995-03-01 10:34:45 +00006667#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006668/*[clinic input]
6669os.getgid
6670
6671Return the current process's group id.
6672[clinic start generated code]*/
6673
Larry Hastings2f936352014-08-05 14:04:04 +10006674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006675os_getgid_impl(PyObject *module)
6676/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006677{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006678 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006679}
Larry Hastings2f936352014-08-05 14:04:04 +10006680#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006681
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006682
Berker Peksag39404992016-09-15 20:45:16 +03006683#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006684/*[clinic input]
6685os.getpid
6686
6687Return the current process id.
6688[clinic start generated code]*/
6689
Larry Hastings2f936352014-08-05 14:04:04 +10006690static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006691os_getpid_impl(PyObject *module)
6692/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006693{
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006695}
Berker Peksag39404992016-09-15 20:45:16 +03006696#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006697
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006698#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006699
6700/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006701PyDoc_STRVAR(posix_getgrouplist__doc__,
6702"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6703Returns a list of groups to which a user belongs.\n\n\
6704 user: username to lookup\n\
6705 group: base group id of the user");
6706
6707static PyObject *
6708posix_getgrouplist(PyObject *self, PyObject *args)
6709{
6710#ifdef NGROUPS_MAX
6711#define MAX_GROUPS NGROUPS_MAX
6712#else
6713 /* defined to be 16 on Solaris7, so this should be a small number */
6714#define MAX_GROUPS 64
6715#endif
6716
6717 const char *user;
6718 int i, ngroups;
6719 PyObject *list;
6720#ifdef __APPLE__
6721 int *groups, basegid;
6722#else
6723 gid_t *groups, basegid;
6724#endif
6725 ngroups = MAX_GROUPS;
6726
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006727#ifdef __APPLE__
6728 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006729 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006730#else
6731 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6732 _Py_Gid_Converter, &basegid))
6733 return NULL;
6734#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006735
6736#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006737 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006738#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006739 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006740#endif
6741 if (groups == NULL)
6742 return PyErr_NoMemory();
6743
6744 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6745 PyMem_Del(groups);
6746 return posix_error();
6747 }
6748
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006749#ifdef _Py_MEMORY_SANITIZER
6750 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6751 __msan_unpoison(&ngroups, sizeof(ngroups));
6752 __msan_unpoison(groups, ngroups*sizeof(*groups));
6753#endif
6754
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006755 list = PyList_New(ngroups);
6756 if (list == NULL) {
6757 PyMem_Del(groups);
6758 return NULL;
6759 }
6760
6761 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006762#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006763 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006764#else
6765 PyObject *o = _PyLong_FromGid(groups[i]);
6766#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006767 if (o == NULL) {
6768 Py_DECREF(list);
6769 PyMem_Del(groups);
6770 return NULL;
6771 }
6772 PyList_SET_ITEM(list, i, o);
6773 }
6774
6775 PyMem_Del(groups);
6776
6777 return list;
6778}
Larry Hastings2f936352014-08-05 14:04:04 +10006779#endif /* HAVE_GETGROUPLIST */
6780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006781
Fred Drakec9680921999-12-13 16:37:25 +00006782#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006783/*[clinic input]
6784os.getgroups
6785
6786Return list of supplemental group IDs for the process.
6787[clinic start generated code]*/
6788
Larry Hastings2f936352014-08-05 14:04:04 +10006789static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006790os_getgroups_impl(PyObject *module)
6791/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006792{
6793 PyObject *result = NULL;
6794
Fred Drakec9680921999-12-13 16:37:25 +00006795#ifdef NGROUPS_MAX
6796#define MAX_GROUPS NGROUPS_MAX
6797#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006798 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006799#define MAX_GROUPS 64
6800#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006802
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006803 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006804 * This is a helper variable to store the intermediate result when
6805 * that happens.
6806 *
6807 * To keep the code readable the OSX behaviour is unconditional,
6808 * according to the POSIX spec this should be safe on all unix-y
6809 * systems.
6810 */
6811 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006813
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006814#ifdef __APPLE__
6815 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6816 * there are more groups than can fit in grouplist. Therefore, on OS X
6817 * always first call getgroups with length 0 to get the actual number
6818 * of groups.
6819 */
6820 n = getgroups(0, NULL);
6821 if (n < 0) {
6822 return posix_error();
6823 } else if (n <= MAX_GROUPS) {
6824 /* groups will fit in existing array */
6825 alt_grouplist = grouplist;
6826 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006827 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006828 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006829 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006830 }
6831 }
6832
6833 n = getgroups(n, alt_grouplist);
6834 if (n == -1) {
6835 if (alt_grouplist != grouplist) {
6836 PyMem_Free(alt_grouplist);
6837 }
6838 return posix_error();
6839 }
6840#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006842 if (n < 0) {
6843 if (errno == EINVAL) {
6844 n = getgroups(0, NULL);
6845 if (n == -1) {
6846 return posix_error();
6847 }
6848 if (n == 0) {
6849 /* Avoid malloc(0) */
6850 alt_grouplist = grouplist;
6851 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006852 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006853 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006854 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006855 }
6856 n = getgroups(n, alt_grouplist);
6857 if (n == -1) {
6858 PyMem_Free(alt_grouplist);
6859 return posix_error();
6860 }
6861 }
6862 } else {
6863 return posix_error();
6864 }
6865 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006866#endif
6867
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006868 result = PyList_New(n);
6869 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 int i;
6871 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006872 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006874 Py_DECREF(result);
6875 result = NULL;
6876 break;
Fred Drakec9680921999-12-13 16:37:25 +00006877 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006879 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006880 }
6881
6882 if (alt_grouplist != grouplist) {
6883 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006885
Fred Drakec9680921999-12-13 16:37:25 +00006886 return result;
6887}
Larry Hastings2f936352014-08-05 14:04:04 +10006888#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006889
Antoine Pitroub7572f02009-12-02 20:46:48 +00006890#ifdef HAVE_INITGROUPS
6891PyDoc_STRVAR(posix_initgroups__doc__,
6892"initgroups(username, gid) -> None\n\n\
6893Call the system initgroups() to initialize the group access list with all of\n\
6894the groups of which the specified username is a member, plus the specified\n\
6895group id.");
6896
Larry Hastings2f936352014-08-05 14:04:04 +10006897/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006898static PyObject *
6899posix_initgroups(PyObject *self, PyObject *args)
6900{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006901 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006902 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006903 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006904#ifdef __APPLE__
6905 int gid;
6906#else
6907 gid_t gid;
6908#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006909
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006910#ifdef __APPLE__
6911 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6912 PyUnicode_FSConverter, &oname,
6913 &gid))
6914#else
6915 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6916 PyUnicode_FSConverter, &oname,
6917 _Py_Gid_Converter, &gid))
6918#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006920 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006921
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006922 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006923 Py_DECREF(oname);
6924 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006926
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006927 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006928}
Larry Hastings2f936352014-08-05 14:04:04 +10006929#endif /* HAVE_INITGROUPS */
6930
Antoine Pitroub7572f02009-12-02 20:46:48 +00006931
Martin v. Löwis606edc12002-06-13 21:09:11 +00006932#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006933/*[clinic input]
6934os.getpgid
6935
6936 pid: pid_t
6937
6938Call the system call getpgid(), and return the result.
6939[clinic start generated code]*/
6940
Larry Hastings2f936352014-08-05 14:04:04 +10006941static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006942os_getpgid_impl(PyObject *module, pid_t pid)
6943/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006944{
6945 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 if (pgid < 0)
6947 return posix_error();
6948 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006949}
6950#endif /* HAVE_GETPGID */
6951
6952
Guido van Rossumb6775db1994-08-01 11:34:53 +00006953#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006954/*[clinic input]
6955os.getpgrp
6956
6957Return the current process group id.
6958[clinic start generated code]*/
6959
Larry Hastings2f936352014-08-05 14:04:04 +10006960static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006961os_getpgrp_impl(PyObject *module)
6962/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006963{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006964#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006965 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006966#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006968#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006969}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006970#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006971
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006972
Guido van Rossumb6775db1994-08-01 11:34:53 +00006973#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006974/*[clinic input]
6975os.setpgrp
6976
6977Make the current process the leader of its process group.
6978[clinic start generated code]*/
6979
Larry Hastings2f936352014-08-05 14:04:04 +10006980static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006981os_setpgrp_impl(PyObject *module)
6982/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006983{
Guido van Rossum64933891994-10-20 21:56:42 +00006984#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006985 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006986#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006987 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006988#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006989 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006990 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006991}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006992#endif /* HAVE_SETPGRP */
6993
Guido van Rossumad0ee831995-03-01 10:34:45 +00006994#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006995
6996#ifdef MS_WINDOWS
6997#include <tlhelp32.h>
6998
6999static PyObject*
7000win32_getppid()
7001{
7002 HANDLE snapshot;
7003 pid_t mypid;
7004 PyObject* result = NULL;
7005 BOOL have_record;
7006 PROCESSENTRY32 pe;
7007
7008 mypid = getpid(); /* This function never fails */
7009
7010 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7011 if (snapshot == INVALID_HANDLE_VALUE)
7012 return PyErr_SetFromWindowsErr(GetLastError());
7013
7014 pe.dwSize = sizeof(pe);
7015 have_record = Process32First(snapshot, &pe);
7016 while (have_record) {
7017 if (mypid == (pid_t)pe.th32ProcessID) {
7018 /* We could cache the ulong value in a static variable. */
7019 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7020 break;
7021 }
7022
7023 have_record = Process32Next(snapshot, &pe);
7024 }
7025
7026 /* If our loop exits and our pid was not found (result will be NULL)
7027 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7028 * error anyway, so let's raise it. */
7029 if (!result)
7030 result = PyErr_SetFromWindowsErr(GetLastError());
7031
7032 CloseHandle(snapshot);
7033
7034 return result;
7035}
7036#endif /*MS_WINDOWS*/
7037
Larry Hastings2f936352014-08-05 14:04:04 +10007038
7039/*[clinic input]
7040os.getppid
7041
7042Return the parent's process id.
7043
7044If the parent process has already exited, Windows machines will still
7045return its id; others systems will return the id of the 'init' process (1).
7046[clinic start generated code]*/
7047
Larry Hastings2f936352014-08-05 14:04:04 +10007048static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007049os_getppid_impl(PyObject *module)
7050/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007051{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007052#ifdef MS_WINDOWS
7053 return win32_getppid();
7054#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007056#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007057}
7058#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007060
Fred Drake12c6e2d1999-12-14 21:25:03 +00007061#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007062/*[clinic input]
7063os.getlogin
7064
7065Return the actual login name.
7066[clinic start generated code]*/
7067
Larry Hastings2f936352014-08-05 14:04:04 +10007068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007069os_getlogin_impl(PyObject *module)
7070/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007071{
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007073#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007074 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007075 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007076
7077 if (GetUserNameW(user_name, &num_chars)) {
7078 /* num_chars is the number of unicode chars plus null terminator */
7079 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007080 }
7081 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007082 result = PyErr_SetFromWindowsErr(GetLastError());
7083#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 char *name;
7085 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007086
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 errno = 0;
7088 name = getlogin();
7089 if (name == NULL) {
7090 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007091 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007092 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007093 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 }
7095 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007096 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007098#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007099 return result;
7100}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007101#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007102
Larry Hastings2f936352014-08-05 14:04:04 +10007103
Guido van Rossumad0ee831995-03-01 10:34:45 +00007104#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007105/*[clinic input]
7106os.getuid
7107
7108Return the current process's user id.
7109[clinic start generated code]*/
7110
Larry Hastings2f936352014-08-05 14:04:04 +10007111static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007112os_getuid_impl(PyObject *module)
7113/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007114{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007115 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007116}
Larry Hastings2f936352014-08-05 14:04:04 +10007117#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007119
Brian Curtineb24d742010-04-12 17:16:38 +00007120#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007121#define HAVE_KILL
7122#endif /* MS_WINDOWS */
7123
7124#ifdef HAVE_KILL
7125/*[clinic input]
7126os.kill
7127
7128 pid: pid_t
7129 signal: Py_ssize_t
7130 /
7131
7132Kill a process with a signal.
7133[clinic start generated code]*/
7134
Larry Hastings2f936352014-08-05 14:04:04 +10007135static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007136os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7137/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007138#ifndef MS_WINDOWS
7139{
7140 if (kill(pid, (int)signal) == -1)
7141 return posix_error();
7142 Py_RETURN_NONE;
7143}
7144#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00007145{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007146 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007147 DWORD sig = (DWORD)signal;
7148 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007149 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007150
Victor Stinner8c62be82010-05-06 00:08:46 +00007151 /* Console processes which share a common console can be sent CTRL+C or
7152 CTRL+BREAK events, provided they handle said events. */
7153 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007154 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007155 err = GetLastError();
7156 PyErr_SetFromWindowsErr(err);
7157 }
7158 else
7159 Py_RETURN_NONE;
7160 }
Brian Curtineb24d742010-04-12 17:16:38 +00007161
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7163 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007164 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 if (handle == NULL) {
7166 err = GetLastError();
7167 return PyErr_SetFromWindowsErr(err);
7168 }
Brian Curtineb24d742010-04-12 17:16:38 +00007169
Victor Stinner8c62be82010-05-06 00:08:46 +00007170 if (TerminateProcess(handle, sig) == 0) {
7171 err = GetLastError();
7172 result = PyErr_SetFromWindowsErr(err);
7173 } else {
7174 Py_INCREF(Py_None);
7175 result = Py_None;
7176 }
Brian Curtineb24d742010-04-12 17:16:38 +00007177
Victor Stinner8c62be82010-05-06 00:08:46 +00007178 CloseHandle(handle);
7179 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00007180}
Larry Hastings2f936352014-08-05 14:04:04 +10007181#endif /* !MS_WINDOWS */
7182#endif /* HAVE_KILL */
7183
7184
7185#ifdef HAVE_KILLPG
7186/*[clinic input]
7187os.killpg
7188
7189 pgid: pid_t
7190 signal: int
7191 /
7192
7193Kill a process group with a signal.
7194[clinic start generated code]*/
7195
Larry Hastings2f936352014-08-05 14:04:04 +10007196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007197os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7198/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007199{
7200 /* XXX some man pages make the `pgid` parameter an int, others
7201 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7202 take the same type. Moreover, pid_t is always at least as wide as
7203 int (else compilation of this module fails), which is safe. */
7204 if (killpg(pgid, signal) == -1)
7205 return posix_error();
7206 Py_RETURN_NONE;
7207}
7208#endif /* HAVE_KILLPG */
7209
Brian Curtineb24d742010-04-12 17:16:38 +00007210
Guido van Rossumc0125471996-06-28 18:55:32 +00007211#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007212#ifdef HAVE_SYS_LOCK_H
7213#include <sys/lock.h>
7214#endif
7215
Larry Hastings2f936352014-08-05 14:04:04 +10007216/*[clinic input]
7217os.plock
7218 op: int
7219 /
7220
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007221Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007222[clinic start generated code]*/
7223
Larry Hastings2f936352014-08-05 14:04:04 +10007224static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007225os_plock_impl(PyObject *module, int op)
7226/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007227{
Victor Stinner8c62be82010-05-06 00:08:46 +00007228 if (plock(op) == -1)
7229 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007230 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007231}
Larry Hastings2f936352014-08-05 14:04:04 +10007232#endif /* HAVE_PLOCK */
7233
Guido van Rossumc0125471996-06-28 18:55:32 +00007234
Guido van Rossumb6775db1994-08-01 11:34:53 +00007235#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007236/*[clinic input]
7237os.setuid
7238
7239 uid: uid_t
7240 /
7241
7242Set the current process's user id.
7243[clinic start generated code]*/
7244
Larry Hastings2f936352014-08-05 14:04:04 +10007245static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007246os_setuid_impl(PyObject *module, uid_t uid)
7247/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007248{
Victor Stinner8c62be82010-05-06 00:08:46 +00007249 if (setuid(uid) < 0)
7250 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007251 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007252}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007253#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007254
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007255
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007256#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007257/*[clinic input]
7258os.seteuid
7259
7260 euid: uid_t
7261 /
7262
7263Set the current process's effective user id.
7264[clinic start generated code]*/
7265
Larry Hastings2f936352014-08-05 14:04:04 +10007266static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007267os_seteuid_impl(PyObject *module, uid_t euid)
7268/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007269{
7270 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007271 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007272 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007273}
7274#endif /* HAVE_SETEUID */
7275
Larry Hastings2f936352014-08-05 14:04:04 +10007276
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007277#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007278/*[clinic input]
7279os.setegid
7280
7281 egid: gid_t
7282 /
7283
7284Set the current process's effective group id.
7285[clinic start generated code]*/
7286
Larry Hastings2f936352014-08-05 14:04:04 +10007287static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007288os_setegid_impl(PyObject *module, gid_t egid)
7289/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007290{
7291 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007292 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007293 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007294}
7295#endif /* HAVE_SETEGID */
7296
Larry Hastings2f936352014-08-05 14:04:04 +10007297
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007298#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007299/*[clinic input]
7300os.setreuid
7301
7302 ruid: uid_t
7303 euid: uid_t
7304 /
7305
7306Set the current process's real and effective user ids.
7307[clinic start generated code]*/
7308
Larry Hastings2f936352014-08-05 14:04:04 +10007309static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007310os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7311/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007312{
Victor Stinner8c62be82010-05-06 00:08:46 +00007313 if (setreuid(ruid, euid) < 0) {
7314 return posix_error();
7315 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007316 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007317 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007318}
7319#endif /* HAVE_SETREUID */
7320
Larry Hastings2f936352014-08-05 14:04:04 +10007321
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007322#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007323/*[clinic input]
7324os.setregid
7325
7326 rgid: gid_t
7327 egid: gid_t
7328 /
7329
7330Set the current process's real and effective group ids.
7331[clinic start generated code]*/
7332
Larry Hastings2f936352014-08-05 14:04:04 +10007333static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007334os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7335/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007336{
7337 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007338 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007339 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007340}
7341#endif /* HAVE_SETREGID */
7342
Larry Hastings2f936352014-08-05 14:04:04 +10007343
Guido van Rossumb6775db1994-08-01 11:34:53 +00007344#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007345/*[clinic input]
7346os.setgid
7347 gid: gid_t
7348 /
7349
7350Set the current process's group id.
7351[clinic start generated code]*/
7352
Larry Hastings2f936352014-08-05 14:04:04 +10007353static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007354os_setgid_impl(PyObject *module, gid_t gid)
7355/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007356{
Victor Stinner8c62be82010-05-06 00:08:46 +00007357 if (setgid(gid) < 0)
7358 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007359 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007360}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007361#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007362
Larry Hastings2f936352014-08-05 14:04:04 +10007363
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007364#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007365/*[clinic input]
7366os.setgroups
7367
7368 groups: object
7369 /
7370
7371Set the groups of the current process to list.
7372[clinic start generated code]*/
7373
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007374static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007375os_setgroups(PyObject *module, PyObject *groups)
7376/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007377{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007378 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007379 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007380
Victor Stinner8c62be82010-05-06 00:08:46 +00007381 if (!PySequence_Check(groups)) {
7382 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7383 return NULL;
7384 }
7385 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007386 if (len < 0) {
7387 return NULL;
7388 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007389 if (len > MAX_GROUPS) {
7390 PyErr_SetString(PyExc_ValueError, "too many groups");
7391 return NULL;
7392 }
7393 for(i = 0; i < len; i++) {
7394 PyObject *elem;
7395 elem = PySequence_GetItem(groups, i);
7396 if (!elem)
7397 return NULL;
7398 if (!PyLong_Check(elem)) {
7399 PyErr_SetString(PyExc_TypeError,
7400 "groups must be integers");
7401 Py_DECREF(elem);
7402 return NULL;
7403 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007404 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007405 Py_DECREF(elem);
7406 return NULL;
7407 }
7408 }
7409 Py_DECREF(elem);
7410 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007411
Victor Stinner8c62be82010-05-06 00:08:46 +00007412 if (setgroups(len, grouplist) < 0)
7413 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007414 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007415}
7416#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007417
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007418#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7419static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007420wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007421{
Victor Stinner8c62be82010-05-06 00:08:46 +00007422 PyObject *result;
7423 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007424 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007425
Victor Stinner8c62be82010-05-06 00:08:46 +00007426 if (pid == -1)
7427 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007428
Victor Stinner8c62be82010-05-06 00:08:46 +00007429 if (struct_rusage == NULL) {
7430 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7431 if (m == NULL)
7432 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007433 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007434 Py_DECREF(m);
7435 if (struct_rusage == NULL)
7436 return NULL;
7437 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007438
Victor Stinner8c62be82010-05-06 00:08:46 +00007439 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7440 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7441 if (!result)
7442 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007443
7444#ifndef doubletime
7445#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7446#endif
7447
Victor Stinner8c62be82010-05-06 00:08:46 +00007448 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007449 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007450 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007451 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007452#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007453 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7454 SET_INT(result, 2, ru->ru_maxrss);
7455 SET_INT(result, 3, ru->ru_ixrss);
7456 SET_INT(result, 4, ru->ru_idrss);
7457 SET_INT(result, 5, ru->ru_isrss);
7458 SET_INT(result, 6, ru->ru_minflt);
7459 SET_INT(result, 7, ru->ru_majflt);
7460 SET_INT(result, 8, ru->ru_nswap);
7461 SET_INT(result, 9, ru->ru_inblock);
7462 SET_INT(result, 10, ru->ru_oublock);
7463 SET_INT(result, 11, ru->ru_msgsnd);
7464 SET_INT(result, 12, ru->ru_msgrcv);
7465 SET_INT(result, 13, ru->ru_nsignals);
7466 SET_INT(result, 14, ru->ru_nvcsw);
7467 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007468#undef SET_INT
7469
Victor Stinner8c62be82010-05-06 00:08:46 +00007470 if (PyErr_Occurred()) {
7471 Py_DECREF(result);
7472 return NULL;
7473 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007474
Victor Stinner8c62be82010-05-06 00:08:46 +00007475 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007476}
7477#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7478
Larry Hastings2f936352014-08-05 14:04:04 +10007479
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007480#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007481/*[clinic input]
7482os.wait3
7483
7484 options: int
7485Wait for completion of a child process.
7486
7487Returns a tuple of information about the child process:
7488 (pid, status, rusage)
7489[clinic start generated code]*/
7490
Larry Hastings2f936352014-08-05 14:04:04 +10007491static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007492os_wait3_impl(PyObject *module, int options)
7493/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007494{
Victor Stinner8c62be82010-05-06 00:08:46 +00007495 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007496 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007497 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007498 WAIT_TYPE status;
7499 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007500
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007501 do {
7502 Py_BEGIN_ALLOW_THREADS
7503 pid = wait3(&status, options, &ru);
7504 Py_END_ALLOW_THREADS
7505 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7506 if (pid < 0)
7507 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007508
Victor Stinner4195b5c2012-02-08 23:03:19 +01007509 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007510}
7511#endif /* HAVE_WAIT3 */
7512
Larry Hastings2f936352014-08-05 14:04:04 +10007513
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007514#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007515/*[clinic input]
7516
7517os.wait4
7518
7519 pid: pid_t
7520 options: int
7521
7522Wait for completion of a specific child process.
7523
7524Returns a tuple of information about the child process:
7525 (pid, status, rusage)
7526[clinic start generated code]*/
7527
Larry Hastings2f936352014-08-05 14:04:04 +10007528static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007529os_wait4_impl(PyObject *module, pid_t pid, int options)
7530/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007531{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007532 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007533 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007534 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007535 WAIT_TYPE status;
7536 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007537
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007538 do {
7539 Py_BEGIN_ALLOW_THREADS
7540 res = wait4(pid, &status, options, &ru);
7541 Py_END_ALLOW_THREADS
7542 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7543 if (res < 0)
7544 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007545
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007546 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007547}
7548#endif /* HAVE_WAIT4 */
7549
Larry Hastings2f936352014-08-05 14:04:04 +10007550
Ross Lagerwall7807c352011-03-17 20:20:30 +02007551#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007552/*[clinic input]
7553os.waitid
7554
7555 idtype: idtype_t
7556 Must be one of be P_PID, P_PGID or P_ALL.
7557 id: id_t
7558 The id to wait on.
7559 options: int
7560 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7561 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7562 /
7563
7564Returns the result of waiting for a process or processes.
7565
7566Returns either waitid_result or None if WNOHANG is specified and there are
7567no children in a waitable state.
7568[clinic start generated code]*/
7569
Larry Hastings2f936352014-08-05 14:04:04 +10007570static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007571os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7572/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007573{
7574 PyObject *result;
7575 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007576 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007577 siginfo_t si;
7578 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007579
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007580 do {
7581 Py_BEGIN_ALLOW_THREADS
7582 res = waitid(idtype, id, &si, options);
7583 Py_END_ALLOW_THREADS
7584 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7585 if (res < 0)
7586 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007587
7588 if (si.si_pid == 0)
7589 Py_RETURN_NONE;
7590
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007591 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007592 if (!result)
7593 return NULL;
7594
7595 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007596 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007597 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7598 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7599 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7600 if (PyErr_Occurred()) {
7601 Py_DECREF(result);
7602 return NULL;
7603 }
7604
7605 return result;
7606}
Larry Hastings2f936352014-08-05 14:04:04 +10007607#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007608
Larry Hastings2f936352014-08-05 14:04:04 +10007609
7610#if defined(HAVE_WAITPID)
7611/*[clinic input]
7612os.waitpid
7613 pid: pid_t
7614 options: int
7615 /
7616
7617Wait for completion of a given child process.
7618
7619Returns a tuple of information regarding the child process:
7620 (pid, status)
7621
7622The options argument is ignored on Windows.
7623[clinic start generated code]*/
7624
Larry Hastings2f936352014-08-05 14:04:04 +10007625static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007626os_waitpid_impl(PyObject *module, pid_t pid, int options)
7627/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007628{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007629 pid_t res;
7630 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007631 WAIT_TYPE status;
7632 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007633
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007634 do {
7635 Py_BEGIN_ALLOW_THREADS
7636 res = waitpid(pid, &status, options);
7637 Py_END_ALLOW_THREADS
7638 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7639 if (res < 0)
7640 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007641
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007642 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007643}
Tim Petersab034fa2002-02-01 11:27:43 +00007644#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007645/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007646/*[clinic input]
7647os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007648 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007649 options: int
7650 /
7651
7652Wait for completion of a given process.
7653
7654Returns a tuple of information regarding the process:
7655 (pid, status << 8)
7656
7657The options argument is ignored on Windows.
7658[clinic start generated code]*/
7659
Larry Hastings2f936352014-08-05 14:04:04 +10007660static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007661os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007662/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007663{
7664 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007665 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007666 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007667
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007668 do {
7669 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007670 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007671 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007672 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007673 Py_END_ALLOW_THREADS
7674 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007675 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007676 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007677
Victor Stinner8c62be82010-05-06 00:08:46 +00007678 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007679 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007680}
Larry Hastings2f936352014-08-05 14:04:04 +10007681#endif
7682
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007683
Guido van Rossumad0ee831995-03-01 10:34:45 +00007684#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007685/*[clinic input]
7686os.wait
7687
7688Wait for completion of a child process.
7689
7690Returns a tuple of information about the child process:
7691 (pid, status)
7692[clinic start generated code]*/
7693
Larry Hastings2f936352014-08-05 14:04:04 +10007694static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007695os_wait_impl(PyObject *module)
7696/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007697{
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007699 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007700 WAIT_TYPE status;
7701 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007702
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007703 do {
7704 Py_BEGIN_ALLOW_THREADS
7705 pid = wait(&status);
7706 Py_END_ALLOW_THREADS
7707 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7708 if (pid < 0)
7709 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007710
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007712}
Larry Hastings2f936352014-08-05 14:04:04 +10007713#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007714
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007715
Larry Hastings9cf065c2012-06-22 16:30:09 -07007716#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007717/*[clinic input]
7718os.readlink
7719
7720 path: path_t
7721 *
7722 dir_fd: dir_fd(requires='readlinkat') = None
7723
7724Return a string representing the path to which the symbolic link points.
7725
7726If dir_fd is not None, it should be a file descriptor open to a directory,
7727and path should be relative; path will then be relative to that directory.
7728
7729dir_fd may not be implemented on your platform. If it is unavailable,
7730using it will raise a NotImplementedError.
7731[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007732
Barry Warsaw53699e91996-12-10 23:23:01 +00007733static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007734os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7735/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007736{
Berker Peksage0b5b202018-08-15 13:03:41 +03007737#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007738 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007739 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007740
7741 Py_BEGIN_ALLOW_THREADS
7742#ifdef HAVE_READLINKAT
7743 if (dir_fd != DEFAULT_DIR_FD)
7744 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7745 else
7746#endif
7747 length = readlink(path->narrow, buffer, MAXPATHLEN);
7748 Py_END_ALLOW_THREADS
7749
7750 if (length < 0) {
7751 return path_error(path);
7752 }
7753 buffer[length] = '\0';
7754
7755 if (PyUnicode_Check(path->object))
7756 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7757 else
7758 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007759#elif defined(MS_WINDOWS)
7760 DWORD n_bytes_returned;
7761 DWORD io_result;
7762 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007763 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7764 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
7765 const wchar_t *print_name;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007766 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007767
Larry Hastings2f936352014-08-05 14:04:04 +10007768 /* First get a handle to the reparse point */
7769 Py_BEGIN_ALLOW_THREADS
7770 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007771 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007772 0,
7773 0,
7774 0,
7775 OPEN_EXISTING,
7776 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7777 0);
7778 Py_END_ALLOW_THREADS
7779
Berker Peksage0b5b202018-08-15 13:03:41 +03007780 if (reparse_point_handle == INVALID_HANDLE_VALUE) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007781 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007782 }
Larry Hastings2f936352014-08-05 14:04:04 +10007783
7784 Py_BEGIN_ALLOW_THREADS
7785 /* New call DeviceIoControl to read the reparse point */
7786 io_result = DeviceIoControl(
7787 reparse_point_handle,
7788 FSCTL_GET_REPARSE_POINT,
7789 0, 0, /* in buffer */
7790 target_buffer, sizeof(target_buffer),
7791 &n_bytes_returned,
7792 0 /* we're not using OVERLAPPED_IO */
7793 );
7794 CloseHandle(reparse_point_handle);
7795 Py_END_ALLOW_THREADS
7796
Berker Peksage0b5b202018-08-15 13:03:41 +03007797 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007798 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007799 }
Larry Hastings2f936352014-08-05 14:04:04 +10007800
7801 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7802 {
7803 PyErr_SetString(PyExc_ValueError,
7804 "not a symbolic link");
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007805 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007806 }
SSE43c34aad2018-02-13 00:10:35 +07007807 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7808 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007809
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007810 result = PyUnicode_FromWideChar(print_name,
7811 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
7812 if (path->narrow) {
7813 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Berker Peksage0b5b202018-08-15 13:03:41 +03007814 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007815 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007816#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007817}
Berker Peksage0b5b202018-08-15 13:03:41 +03007818#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007819
Larry Hastings9cf065c2012-06-22 16:30:09 -07007820#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007821
7822#if defined(MS_WINDOWS)
7823
Steve Dower6921e732018-03-05 14:26:08 -08007824/* Remove the last portion of the path - return 0 on success */
7825static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007826_dirnameW(WCHAR *path)
7827{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007828 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007829 size_t length = wcsnlen_s(path, MAX_PATH);
7830 if (length == MAX_PATH) {
7831 return -1;
7832 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007833
7834 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007835 for(ptr = path + length; ptr != path; ptr--) {
7836 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007837 break;
Steve Dower6921e732018-03-05 14:26:08 -08007838 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007839 }
7840 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007841 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007842}
7843
Victor Stinner31b3b922013-06-05 01:49:17 +02007844/* Is this path absolute? */
7845static int
7846_is_absW(const WCHAR *path)
7847{
Steve Dower6921e732018-03-05 14:26:08 -08007848 return path[0] == L'\\' || path[0] == L'/' ||
7849 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007850}
7851
Steve Dower6921e732018-03-05 14:26:08 -08007852/* join root and rest with a backslash - return 0 on success */
7853static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007854_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7855{
Victor Stinner31b3b922013-06-05 01:49:17 +02007856 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007857 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007858 }
7859
Steve Dower6921e732018-03-05 14:26:08 -08007860 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7861 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007862 }
Steve Dower6921e732018-03-05 14:26:08 -08007863
7864 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7865 return -1;
7866 }
7867
7868 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007869}
7870
Victor Stinner31b3b922013-06-05 01:49:17 +02007871/* Return True if the path at src relative to dest is a directory */
7872static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007873_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007874{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007875 WIN32_FILE_ATTRIBUTE_DATA src_info;
7876 WCHAR dest_parent[MAX_PATH];
7877 WCHAR src_resolved[MAX_PATH] = L"";
7878
7879 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007880 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7881 _dirnameW(dest_parent)) {
7882 return 0;
7883 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007884 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007885 if (_joinW(src_resolved, dest_parent, src)) {
7886 return 0;
7887 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007888 return (
7889 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7890 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7891 );
7892}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007893#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007894
Larry Hastings2f936352014-08-05 14:04:04 +10007895
7896/*[clinic input]
7897os.symlink
7898 src: path_t
7899 dst: path_t
7900 target_is_directory: bool = False
7901 *
7902 dir_fd: dir_fd(requires='symlinkat')=None
7903
7904# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7905
7906Create a symbolic link pointing to src named dst.
7907
7908target_is_directory is required on Windows if the target is to be
7909 interpreted as a directory. (On Windows, symlink requires
7910 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7911 target_is_directory is ignored on non-Windows platforms.
7912
7913If dir_fd is not None, it should be a file descriptor open to a directory,
7914 and path should be relative; path will then be relative to that directory.
7915dir_fd may not be implemented on your platform.
7916 If it is unavailable, using it will raise a NotImplementedError.
7917
7918[clinic start generated code]*/
7919
Larry Hastings2f936352014-08-05 14:04:04 +10007920static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007921os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007922 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007923/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007924{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007925#ifdef MS_WINDOWS
7926 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007927 DWORD flags = 0;
7928
7929 /* Assumed true, set to false if detected to not be available. */
7930 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007931#else
7932 int result;
7933#endif
7934
Larry Hastings9cf065c2012-06-22 16:30:09 -07007935#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007936
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007937 if (windows_has_symlink_unprivileged_flag) {
7938 /* Allow non-admin symlinks if system allows it. */
7939 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
7940 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007941
Larry Hastings9cf065c2012-06-22 16:30:09 -07007942 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007943 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007944 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
7945 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
7946 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
7947 }
7948
7949 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08007950 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007951 Py_END_ALLOW_THREADS
7952
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007953 if (windows_has_symlink_unprivileged_flag && !result &&
7954 ERROR_INVALID_PARAMETER == GetLastError()) {
7955
7956 Py_BEGIN_ALLOW_THREADS
7957 _Py_BEGIN_SUPPRESS_IPH
7958 /* This error might be caused by
7959 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
7960 Try again, and update windows_has_symlink_unprivileged_flag if we
7961 are successful this time.
7962
7963 NOTE: There is a risk of a race condition here if there are other
7964 conditions than the flag causing ERROR_INVALID_PARAMETER, and
7965 another process (or thread) changes that condition in between our
7966 calls to CreateSymbolicLink.
7967 */
7968 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
7969 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
7970 _Py_END_SUPPRESS_IPH
7971 Py_END_ALLOW_THREADS
7972
7973 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
7974 windows_has_symlink_unprivileged_flag = FALSE;
7975 }
7976 }
7977
Larry Hastings2f936352014-08-05 14:04:04 +10007978 if (!result)
7979 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007980
7981#else
7982
Steve Dower6921e732018-03-05 14:26:08 -08007983 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7984 PyErr_SetString(PyExc_ValueError,
7985 "symlink: src and dst must be the same type");
7986 return NULL;
7987 }
7988
Larry Hastings9cf065c2012-06-22 16:30:09 -07007989 Py_BEGIN_ALLOW_THREADS
7990#if HAVE_SYMLINKAT
7991 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007992 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007993 else
7994#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007995 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007996 Py_END_ALLOW_THREADS
7997
Larry Hastings2f936352014-08-05 14:04:04 +10007998 if (result)
7999 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008000#endif
8001
Larry Hastings2f936352014-08-05 14:04:04 +10008002 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008003}
8004#endif /* HAVE_SYMLINK */
8005
Larry Hastings9cf065c2012-06-22 16:30:09 -07008006
Brian Curtind40e6f72010-07-08 21:39:08 +00008007
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008008
Larry Hastings605a62d2012-06-24 04:33:36 -07008009static PyStructSequence_Field times_result_fields[] = {
8010 {"user", "user time"},
8011 {"system", "system time"},
8012 {"children_user", "user time of children"},
8013 {"children_system", "system time of children"},
8014 {"elapsed", "elapsed time since an arbitrary point in the past"},
8015 {NULL}
8016};
8017
8018PyDoc_STRVAR(times_result__doc__,
8019"times_result: Result from os.times().\n\n\
8020This object may be accessed either as a tuple of\n\
8021 (user, system, children_user, children_system, elapsed),\n\
8022or via the attributes user, system, children_user, children_system,\n\
8023and elapsed.\n\
8024\n\
8025See os.times for more information.");
8026
8027static PyStructSequence_Desc times_result_desc = {
8028 "times_result", /* name */
8029 times_result__doc__, /* doc */
8030 times_result_fields,
8031 5
8032};
8033
Eddie Elizondo474eedf2018-11-13 04:09:31 -08008034static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07008035
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008036#ifdef MS_WINDOWS
8037#define HAVE_TIMES /* mandatory, for the method table */
8038#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008039
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008040#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008041
8042static PyObject *
8043build_times_result(double user, double system,
8044 double children_user, double children_system,
8045 double elapsed)
8046{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08008047 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008048 if (value == NULL)
8049 return NULL;
8050
8051#define SET(i, field) \
8052 { \
8053 PyObject *o = PyFloat_FromDouble(field); \
8054 if (!o) { \
8055 Py_DECREF(value); \
8056 return NULL; \
8057 } \
8058 PyStructSequence_SET_ITEM(value, i, o); \
8059 } \
8060
8061 SET(0, user);
8062 SET(1, system);
8063 SET(2, children_user);
8064 SET(3, children_system);
8065 SET(4, elapsed);
8066
8067#undef SET
8068
8069 return value;
8070}
8071
Larry Hastings605a62d2012-06-24 04:33:36 -07008072
Larry Hastings2f936352014-08-05 14:04:04 +10008073#ifndef MS_WINDOWS
8074#define NEED_TICKS_PER_SECOND
8075static long ticks_per_second = -1;
8076#endif /* MS_WINDOWS */
8077
8078/*[clinic input]
8079os.times
8080
8081Return a collection containing process timing information.
8082
8083The object returned behaves like a named tuple with these fields:
8084 (utime, stime, cutime, cstime, elapsed_time)
8085All fields are floating point numbers.
8086[clinic start generated code]*/
8087
Larry Hastings2f936352014-08-05 14:04:04 +10008088static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008089os_times_impl(PyObject *module)
8090/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008091#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008092{
Victor Stinner8c62be82010-05-06 00:08:46 +00008093 FILETIME create, exit, kernel, user;
8094 HANDLE hProc;
8095 hProc = GetCurrentProcess();
8096 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8097 /* The fields of a FILETIME structure are the hi and lo part
8098 of a 64-bit value expressed in 100 nanosecond units.
8099 1e7 is one second in such units; 1e-7 the inverse.
8100 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8101 */
Larry Hastings605a62d2012-06-24 04:33:36 -07008102 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00008103 (double)(user.dwHighDateTime*429.4967296 +
8104 user.dwLowDateTime*1e-7),
8105 (double)(kernel.dwHighDateTime*429.4967296 +
8106 kernel.dwLowDateTime*1e-7),
8107 (double)0,
8108 (double)0,
8109 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008110}
Larry Hastings2f936352014-08-05 14:04:04 +10008111#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008112{
Larry Hastings2f936352014-08-05 14:04:04 +10008113
8114
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008115 struct tms t;
8116 clock_t c;
8117 errno = 0;
8118 c = times(&t);
8119 if (c == (clock_t) -1)
8120 return posix_error();
8121 return build_times_result(
8122 (double)t.tms_utime / ticks_per_second,
8123 (double)t.tms_stime / ticks_per_second,
8124 (double)t.tms_cutime / ticks_per_second,
8125 (double)t.tms_cstime / ticks_per_second,
8126 (double)c / ticks_per_second);
8127}
Larry Hastings2f936352014-08-05 14:04:04 +10008128#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008129#endif /* HAVE_TIMES */
8130
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008131
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008132#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008133/*[clinic input]
8134os.getsid
8135
8136 pid: pid_t
8137 /
8138
8139Call the system call getsid(pid) and return the result.
8140[clinic start generated code]*/
8141
Larry Hastings2f936352014-08-05 14:04:04 +10008142static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008143os_getsid_impl(PyObject *module, pid_t pid)
8144/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008145{
Victor Stinner8c62be82010-05-06 00:08:46 +00008146 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008147 sid = getsid(pid);
8148 if (sid < 0)
8149 return posix_error();
8150 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008151}
8152#endif /* HAVE_GETSID */
8153
8154
Guido van Rossumb6775db1994-08-01 11:34:53 +00008155#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008156/*[clinic input]
8157os.setsid
8158
8159Call the system call setsid().
8160[clinic start generated code]*/
8161
Larry Hastings2f936352014-08-05 14:04:04 +10008162static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008163os_setsid_impl(PyObject *module)
8164/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008165{
Victor Stinner8c62be82010-05-06 00:08:46 +00008166 if (setsid() < 0)
8167 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008168 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008169}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008170#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008171
Larry Hastings2f936352014-08-05 14:04:04 +10008172
Guido van Rossumb6775db1994-08-01 11:34:53 +00008173#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008174/*[clinic input]
8175os.setpgid
8176
8177 pid: pid_t
8178 pgrp: pid_t
8179 /
8180
8181Call the system call setpgid(pid, pgrp).
8182[clinic start generated code]*/
8183
Larry Hastings2f936352014-08-05 14:04:04 +10008184static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008185os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8186/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008187{
Victor Stinner8c62be82010-05-06 00:08:46 +00008188 if (setpgid(pid, pgrp) < 0)
8189 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008190 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008191}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008192#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008194
Guido van Rossumb6775db1994-08-01 11:34:53 +00008195#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008196/*[clinic input]
8197os.tcgetpgrp
8198
8199 fd: int
8200 /
8201
8202Return the process group associated with the terminal specified by fd.
8203[clinic start generated code]*/
8204
Larry Hastings2f936352014-08-05 14:04:04 +10008205static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008206os_tcgetpgrp_impl(PyObject *module, int fd)
8207/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008208{
8209 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008210 if (pgid < 0)
8211 return posix_error();
8212 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008213}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008214#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008216
Guido van Rossumb6775db1994-08-01 11:34:53 +00008217#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008218/*[clinic input]
8219os.tcsetpgrp
8220
8221 fd: int
8222 pgid: pid_t
8223 /
8224
8225Set the process group associated with the terminal specified by fd.
8226[clinic start generated code]*/
8227
Larry Hastings2f936352014-08-05 14:04:04 +10008228static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008229os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8230/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008231{
Victor Stinner8c62be82010-05-06 00:08:46 +00008232 if (tcsetpgrp(fd, pgid) < 0)
8233 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008234 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008235}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008236#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008237
Guido van Rossum687dd131993-05-17 08:34:16 +00008238/* Functions acting on file descriptors */
8239
Victor Stinnerdaf45552013-08-28 00:53:59 +02008240#ifdef O_CLOEXEC
8241extern int _Py_open_cloexec_works;
8242#endif
8243
Larry Hastings2f936352014-08-05 14:04:04 +10008244
8245/*[clinic input]
8246os.open -> int
8247 path: path_t
8248 flags: int
8249 mode: int = 0o777
8250 *
8251 dir_fd: dir_fd(requires='openat') = None
8252
8253# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8254
8255Open a file for low level IO. Returns a file descriptor (integer).
8256
8257If dir_fd is not None, it should be a file descriptor open to a directory,
8258 and path should be relative; path will then be relative to that directory.
8259dir_fd may not be implemented on your platform.
8260 If it is unavailable, using it will raise a NotImplementedError.
8261[clinic start generated code]*/
8262
Larry Hastings2f936352014-08-05 14:04:04 +10008263static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008264os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8265/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008266{
8267 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008268 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008269
Victor Stinnerdaf45552013-08-28 00:53:59 +02008270#ifdef O_CLOEXEC
8271 int *atomic_flag_works = &_Py_open_cloexec_works;
8272#elif !defined(MS_WINDOWS)
8273 int *atomic_flag_works = NULL;
8274#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008275
Victor Stinnerdaf45552013-08-28 00:53:59 +02008276#ifdef MS_WINDOWS
8277 flags |= O_NOINHERIT;
8278#elif defined(O_CLOEXEC)
8279 flags |= O_CLOEXEC;
8280#endif
8281
Steve Dower8fc89802015-04-12 00:26:27 -04008282 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008283 do {
8284 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008285#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008286 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008287#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008288#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008289 if (dir_fd != DEFAULT_DIR_FD)
8290 fd = openat(dir_fd, path->narrow, flags, mode);
8291 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008292#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008293 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008294#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008295 Py_END_ALLOW_THREADS
8296 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008297 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008298
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008299 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008300 if (!async_err)
8301 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008302 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008303 }
8304
Victor Stinnerdaf45552013-08-28 00:53:59 +02008305#ifndef MS_WINDOWS
8306 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8307 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008308 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008309 }
8310#endif
8311
Larry Hastings2f936352014-08-05 14:04:04 +10008312 return fd;
8313}
8314
8315
8316/*[clinic input]
8317os.close
8318
8319 fd: int
8320
8321Close a file descriptor.
8322[clinic start generated code]*/
8323
Barry Warsaw53699e91996-12-10 23:23:01 +00008324static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008325os_close_impl(PyObject *module, int fd)
8326/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008327{
Larry Hastings2f936352014-08-05 14:04:04 +10008328 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008329 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8330 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8331 * for more details.
8332 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008333 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008334 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008335 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008336 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008337 Py_END_ALLOW_THREADS
8338 if (res < 0)
8339 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008340 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008341}
8342
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008343
Larry Hastings2f936352014-08-05 14:04:04 +10008344/*[clinic input]
8345os.closerange
8346
8347 fd_low: int
8348 fd_high: int
8349 /
8350
8351Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8352[clinic start generated code]*/
8353
Larry Hastings2f936352014-08-05 14:04:04 +10008354static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008355os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8356/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008357{
8358 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008359 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008360 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008361 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008362 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008363 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008364 Py_END_ALLOW_THREADS
8365 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008366}
8367
8368
Larry Hastings2f936352014-08-05 14:04:04 +10008369/*[clinic input]
8370os.dup -> int
8371
8372 fd: int
8373 /
8374
8375Return a duplicate of a file descriptor.
8376[clinic start generated code]*/
8377
Larry Hastings2f936352014-08-05 14:04:04 +10008378static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008379os_dup_impl(PyObject *module, int fd)
8380/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008381{
8382 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008383}
8384
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008385
Larry Hastings2f936352014-08-05 14:04:04 +10008386/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008387os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008388 fd: int
8389 fd2: int
8390 inheritable: bool=True
8391
8392Duplicate file descriptor.
8393[clinic start generated code]*/
8394
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008395static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008396os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008397/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008398{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008399 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008400#if defined(HAVE_DUP3) && \
8401 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8402 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008403 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008404#endif
8405
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008406 if (fd < 0 || fd2 < 0) {
8407 posix_error();
8408 return -1;
8409 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008410
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008411 /* dup2() can fail with EINTR if the target FD is already open, because it
8412 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8413 * upon close(), and therefore below.
8414 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008415#ifdef MS_WINDOWS
8416 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008417 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008419 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008420 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008421 if (res < 0) {
8422 posix_error();
8423 return -1;
8424 }
8425 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008426
8427 /* Character files like console cannot be make non-inheritable */
8428 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8429 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008430 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008431 }
8432
8433#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8434 Py_BEGIN_ALLOW_THREADS
8435 if (!inheritable)
8436 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8437 else
8438 res = dup2(fd, fd2);
8439 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008440 if (res < 0) {
8441 posix_error();
8442 return -1;
8443 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008444
8445#else
8446
8447#ifdef HAVE_DUP3
8448 if (!inheritable && dup3_works != 0) {
8449 Py_BEGIN_ALLOW_THREADS
8450 res = dup3(fd, fd2, O_CLOEXEC);
8451 Py_END_ALLOW_THREADS
8452 if (res < 0) {
8453 if (dup3_works == -1)
8454 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008455 if (dup3_works) {
8456 posix_error();
8457 return -1;
8458 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008459 }
8460 }
8461
8462 if (inheritable || dup3_works == 0)
8463 {
8464#endif
8465 Py_BEGIN_ALLOW_THREADS
8466 res = dup2(fd, fd2);
8467 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008468 if (res < 0) {
8469 posix_error();
8470 return -1;
8471 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008472
8473 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8474 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008475 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008476 }
8477#ifdef HAVE_DUP3
8478 }
8479#endif
8480
8481#endif
8482
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008483 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008484}
8485
Larry Hastings2f936352014-08-05 14:04:04 +10008486
Ross Lagerwall7807c352011-03-17 20:20:30 +02008487#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008488/*[clinic input]
8489os.lockf
8490
8491 fd: int
8492 An open file descriptor.
8493 command: int
8494 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8495 length: Py_off_t
8496 The number of bytes to lock, starting at the current position.
8497 /
8498
8499Apply, test or remove a POSIX lock on an open file descriptor.
8500
8501[clinic start generated code]*/
8502
Larry Hastings2f936352014-08-05 14:04:04 +10008503static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008504os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8505/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008506{
8507 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008508
8509 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008510 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008511 Py_END_ALLOW_THREADS
8512
8513 if (res < 0)
8514 return posix_error();
8515
8516 Py_RETURN_NONE;
8517}
Larry Hastings2f936352014-08-05 14:04:04 +10008518#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008519
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008520
Larry Hastings2f936352014-08-05 14:04:04 +10008521/*[clinic input]
8522os.lseek -> Py_off_t
8523
8524 fd: int
8525 position: Py_off_t
8526 how: int
8527 /
8528
8529Set the position of a file descriptor. Return the new position.
8530
8531Return the new cursor position in number of bytes
8532relative to the beginning of the file.
8533[clinic start generated code]*/
8534
Larry Hastings2f936352014-08-05 14:04:04 +10008535static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008536os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8537/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008538{
8539 Py_off_t result;
8540
Guido van Rossum687dd131993-05-17 08:34:16 +00008541#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008542 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8543 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008544 case 0: how = SEEK_SET; break;
8545 case 1: how = SEEK_CUR; break;
8546 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008547 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008548#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008549
Victor Stinner8c62be82010-05-06 00:08:46 +00008550 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008551 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008552#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008553 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008554#else
Larry Hastings2f936352014-08-05 14:04:04 +10008555 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008556#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008557 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008558 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008559 if (result < 0)
8560 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008561
Larry Hastings2f936352014-08-05 14:04:04 +10008562 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008563}
8564
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008565
Larry Hastings2f936352014-08-05 14:04:04 +10008566/*[clinic input]
8567os.read
8568 fd: int
8569 length: Py_ssize_t
8570 /
8571
8572Read from a file descriptor. Returns a bytes object.
8573[clinic start generated code]*/
8574
Larry Hastings2f936352014-08-05 14:04:04 +10008575static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008576os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8577/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008578{
Victor Stinner8c62be82010-05-06 00:08:46 +00008579 Py_ssize_t n;
8580 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008581
8582 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008583 errno = EINVAL;
8584 return posix_error();
8585 }
Larry Hastings2f936352014-08-05 14:04:04 +10008586
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008587 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008588
8589 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008590 if (buffer == NULL)
8591 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008592
Victor Stinner66aab0c2015-03-19 22:53:20 +01008593 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8594 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008595 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008596 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008597 }
Larry Hastings2f936352014-08-05 14:04:04 +10008598
8599 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008600 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008601
Victor Stinner8c62be82010-05-06 00:08:46 +00008602 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008603}
8604
Ross Lagerwall7807c352011-03-17 20:20:30 +02008605#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008606 || defined(__APPLE__))) \
8607 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8608 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8609static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008610iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008611{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008612 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008613
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008614 *iov = PyMem_New(struct iovec, cnt);
8615 if (*iov == NULL) {
8616 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008617 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008618 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008619
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008620 *buf = PyMem_New(Py_buffer, cnt);
8621 if (*buf == NULL) {
8622 PyMem_Del(*iov);
8623 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008624 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008625 }
8626
8627 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008628 PyObject *item = PySequence_GetItem(seq, i);
8629 if (item == NULL)
8630 goto fail;
8631 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8632 Py_DECREF(item);
8633 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008634 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008635 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008636 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008637 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008638 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008639 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008640
8641fail:
8642 PyMem_Del(*iov);
8643 for (j = 0; j < i; j++) {
8644 PyBuffer_Release(&(*buf)[j]);
8645 }
8646 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008647 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008648}
8649
8650static void
8651iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8652{
8653 int i;
8654 PyMem_Del(iov);
8655 for (i = 0; i < cnt; i++) {
8656 PyBuffer_Release(&buf[i]);
8657 }
8658 PyMem_Del(buf);
8659}
8660#endif
8661
Larry Hastings2f936352014-08-05 14:04:04 +10008662
Ross Lagerwall7807c352011-03-17 20:20:30 +02008663#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008664/*[clinic input]
8665os.readv -> Py_ssize_t
8666
8667 fd: int
8668 buffers: object
8669 /
8670
8671Read from a file descriptor fd into an iterable of buffers.
8672
8673The buffers should be mutable buffers accepting bytes.
8674readv will transfer data into each buffer until it is full
8675and then move on to the next buffer in the sequence to hold
8676the rest of the data.
8677
8678readv returns the total number of bytes read,
8679which may be less than the total capacity of all the buffers.
8680[clinic start generated code]*/
8681
Larry Hastings2f936352014-08-05 14:04:04 +10008682static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008683os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8684/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008685{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008686 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008687 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008688 struct iovec *iov;
8689 Py_buffer *buf;
8690
Larry Hastings2f936352014-08-05 14:04:04 +10008691 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008692 PyErr_SetString(PyExc_TypeError,
8693 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008694 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008695 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008696
Larry Hastings2f936352014-08-05 14:04:04 +10008697 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008698 if (cnt < 0)
8699 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008700
8701 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8702 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008703
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008704 do {
8705 Py_BEGIN_ALLOW_THREADS
8706 n = readv(fd, iov, cnt);
8707 Py_END_ALLOW_THREADS
8708 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008709
8710 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008711 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008712 if (!async_err)
8713 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008714 return -1;
8715 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008716
Larry Hastings2f936352014-08-05 14:04:04 +10008717 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008718}
Larry Hastings2f936352014-08-05 14:04:04 +10008719#endif /* HAVE_READV */
8720
Ross Lagerwall7807c352011-03-17 20:20:30 +02008721
8722#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008723/*[clinic input]
8724# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8725os.pread
8726
8727 fd: int
8728 length: int
8729 offset: Py_off_t
8730 /
8731
8732Read a number of bytes from a file descriptor starting at a particular offset.
8733
8734Read length bytes from file descriptor fd, starting at offset bytes from
8735the beginning of the file. The file offset remains unchanged.
8736[clinic start generated code]*/
8737
Larry Hastings2f936352014-08-05 14:04:04 +10008738static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008739os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8740/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008741{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008742 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008743 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008744 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008745
Larry Hastings2f936352014-08-05 14:04:04 +10008746 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008747 errno = EINVAL;
8748 return posix_error();
8749 }
Larry Hastings2f936352014-08-05 14:04:04 +10008750 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008751 if (buffer == NULL)
8752 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008753
8754 do {
8755 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008756 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008757 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008758 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008759 Py_END_ALLOW_THREADS
8760 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8761
Ross Lagerwall7807c352011-03-17 20:20:30 +02008762 if (n < 0) {
8763 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008764 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008765 }
Larry Hastings2f936352014-08-05 14:04:04 +10008766 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008767 _PyBytes_Resize(&buffer, n);
8768 return buffer;
8769}
Larry Hastings2f936352014-08-05 14:04:04 +10008770#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008771
Pablo Galindo4defba32018-01-27 16:16:37 +00008772#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8773/*[clinic input]
8774os.preadv -> Py_ssize_t
8775
8776 fd: int
8777 buffers: object
8778 offset: Py_off_t
8779 flags: int = 0
8780 /
8781
8782Reads from a file descriptor into a number of mutable bytes-like objects.
8783
8784Combines the functionality of readv() and pread(). As readv(), it will
8785transfer data into each buffer until it is full and then move on to the next
8786buffer in the sequence to hold the rest of the data. Its fourth argument,
8787specifies the file offset at which the input operation is to be performed. It
8788will return the total number of bytes read (which can be less than the total
8789capacity of all the objects).
8790
8791The flags argument contains a bitwise OR of zero or more of the following flags:
8792
8793- RWF_HIPRI
8794- RWF_NOWAIT
8795
8796Using non-zero flags requires Linux 4.6 or newer.
8797[clinic start generated code]*/
8798
8799static Py_ssize_t
8800os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8801 int flags)
8802/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8803{
8804 Py_ssize_t cnt, n;
8805 int async_err = 0;
8806 struct iovec *iov;
8807 Py_buffer *buf;
8808
8809 if (!PySequence_Check(buffers)) {
8810 PyErr_SetString(PyExc_TypeError,
8811 "preadv2() arg 2 must be a sequence");
8812 return -1;
8813 }
8814
8815 cnt = PySequence_Size(buffers);
8816 if (cnt < 0) {
8817 return -1;
8818 }
8819
8820#ifndef HAVE_PREADV2
8821 if(flags != 0) {
8822 argument_unavailable_error("preadv2", "flags");
8823 return -1;
8824 }
8825#endif
8826
8827 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8828 return -1;
8829 }
8830#ifdef HAVE_PREADV2
8831 do {
8832 Py_BEGIN_ALLOW_THREADS
8833 _Py_BEGIN_SUPPRESS_IPH
8834 n = preadv2(fd, iov, cnt, offset, flags);
8835 _Py_END_SUPPRESS_IPH
8836 Py_END_ALLOW_THREADS
8837 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8838#else
8839 do {
8840 Py_BEGIN_ALLOW_THREADS
8841 _Py_BEGIN_SUPPRESS_IPH
8842 n = preadv(fd, iov, cnt, offset);
8843 _Py_END_SUPPRESS_IPH
8844 Py_END_ALLOW_THREADS
8845 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8846#endif
8847
8848 iov_cleanup(iov, buf, cnt);
8849 if (n < 0) {
8850 if (!async_err) {
8851 posix_error();
8852 }
8853 return -1;
8854 }
8855
8856 return n;
8857}
8858#endif /* HAVE_PREADV */
8859
Larry Hastings2f936352014-08-05 14:04:04 +10008860
8861/*[clinic input]
8862os.write -> Py_ssize_t
8863
8864 fd: int
8865 data: Py_buffer
8866 /
8867
8868Write a bytes object to a file descriptor.
8869[clinic start generated code]*/
8870
Larry Hastings2f936352014-08-05 14:04:04 +10008871static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008872os_write_impl(PyObject *module, int fd, Py_buffer *data)
8873/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008874{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008875 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008876}
8877
8878#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008879PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008880"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008881sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008882 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008883Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008884
Larry Hastings2f936352014-08-05 14:04:04 +10008885/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008886static PyObject *
8887posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8888{
8889 int in, out;
8890 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008891 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008892 off_t offset;
8893
8894#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8895#ifndef __APPLE__
8896 Py_ssize_t len;
8897#endif
8898 PyObject *headers = NULL, *trailers = NULL;
8899 Py_buffer *hbuf, *tbuf;
8900 off_t sbytes;
8901 struct sf_hdtr sf;
8902 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008903 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008904 static char *keywords[] = {"out", "in",
8905 "offset", "count",
8906 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008907
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008908 sf.headers = NULL;
8909 sf.trailers = NULL;
8910
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008911#ifdef __APPLE__
8912 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008913 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008914#else
8915 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008916 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008917#endif
8918 &headers, &trailers, &flags))
8919 return NULL;
8920 if (headers != NULL) {
8921 if (!PySequence_Check(headers)) {
8922 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008923 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008924 return NULL;
8925 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008926 Py_ssize_t i = PySequence_Size(headers);
8927 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008928 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008929 if (i > INT_MAX) {
8930 PyErr_SetString(PyExc_OverflowError,
8931 "sendfile() header is too large");
8932 return NULL;
8933 }
8934 if (i > 0) {
8935 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008936 if (iov_setup(&(sf.headers), &hbuf,
8937 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008938 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008939#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008940 for (i = 0; i < sf.hdr_cnt; i++) {
8941 Py_ssize_t blen = sf.headers[i].iov_len;
8942# define OFF_T_MAX 0x7fffffffffffffff
8943 if (sbytes >= OFF_T_MAX - blen) {
8944 PyErr_SetString(PyExc_OverflowError,
8945 "sendfile() header is too large");
8946 return NULL;
8947 }
8948 sbytes += blen;
8949 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008950#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008951 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008952 }
8953 }
8954 if (trailers != NULL) {
8955 if (!PySequence_Check(trailers)) {
8956 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008957 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008958 return NULL;
8959 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008960 Py_ssize_t i = PySequence_Size(trailers);
8961 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008962 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008963 if (i > INT_MAX) {
8964 PyErr_SetString(PyExc_OverflowError,
8965 "sendfile() trailer is too large");
8966 return NULL;
8967 }
8968 if (i > 0) {
8969 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008970 if (iov_setup(&(sf.trailers), &tbuf,
8971 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008972 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008973 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008974 }
8975 }
8976
Steve Dower8fc89802015-04-12 00:26:27 -04008977 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008978 do {
8979 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008980#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008981 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008982#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008983 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008984#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008985 Py_END_ALLOW_THREADS
8986 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008987 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008988
8989 if (sf.headers != NULL)
8990 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8991 if (sf.trailers != NULL)
8992 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8993
8994 if (ret < 0) {
8995 if ((errno == EAGAIN) || (errno == EBUSY)) {
8996 if (sbytes != 0) {
8997 // some data has been sent
8998 goto done;
8999 }
9000 else {
9001 // no data has been sent; upper application is supposed
9002 // to retry on EAGAIN or EBUSY
9003 return posix_error();
9004 }
9005 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009006 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009007 }
9008 goto done;
9009
9010done:
9011 #if !defined(HAVE_LARGEFILE_SUPPORT)
9012 return Py_BuildValue("l", sbytes);
9013 #else
9014 return Py_BuildValue("L", sbytes);
9015 #endif
9016
9017#else
9018 Py_ssize_t count;
9019 PyObject *offobj;
9020 static char *keywords[] = {"out", "in",
9021 "offset", "count", NULL};
9022 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
9023 keywords, &out, &in, &offobj, &count))
9024 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009025#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009026 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009027 do {
9028 Py_BEGIN_ALLOW_THREADS
9029 ret = sendfile(out, in, NULL, count);
9030 Py_END_ALLOW_THREADS
9031 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009032 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009033 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009034 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009035 }
9036#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009037 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009038 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009039
9040 do {
9041 Py_BEGIN_ALLOW_THREADS
9042 ret = sendfile(out, in, &offset, count);
9043 Py_END_ALLOW_THREADS
9044 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009045 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009046 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009047 return Py_BuildValue("n", ret);
9048#endif
9049}
Larry Hastings2f936352014-08-05 14:04:04 +10009050#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009051
Larry Hastings2f936352014-08-05 14:04:04 +10009052
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009053#if defined(__APPLE__)
9054/*[clinic input]
9055os._fcopyfile
9056
9057 infd: int
9058 outfd: int
9059 flags: int
9060 /
9061
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009062Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009063[clinic start generated code]*/
9064
9065static PyObject *
9066os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009067/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009068{
9069 int ret;
9070
9071 Py_BEGIN_ALLOW_THREADS
9072 ret = fcopyfile(infd, outfd, NULL, flags);
9073 Py_END_ALLOW_THREADS
9074 if (ret < 0)
9075 return posix_error();
9076 Py_RETURN_NONE;
9077}
9078#endif
9079
9080
Larry Hastings2f936352014-08-05 14:04:04 +10009081/*[clinic input]
9082os.fstat
9083
9084 fd : int
9085
9086Perform a stat system call on the given file descriptor.
9087
9088Like stat(), but for an open file descriptor.
9089Equivalent to os.stat(fd).
9090[clinic start generated code]*/
9091
Larry Hastings2f936352014-08-05 14:04:04 +10009092static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009093os_fstat_impl(PyObject *module, int fd)
9094/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009095{
Victor Stinner8c62be82010-05-06 00:08:46 +00009096 STRUCT_STAT st;
9097 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009098 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009099
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009100 do {
9101 Py_BEGIN_ALLOW_THREADS
9102 res = FSTAT(fd, &st);
9103 Py_END_ALLOW_THREADS
9104 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009106#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009107 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009108#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009109 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009110#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009111 }
Tim Peters5aa91602002-01-30 05:46:57 +00009112
Victor Stinner4195b5c2012-02-08 23:03:19 +01009113 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009114}
9115
Larry Hastings2f936352014-08-05 14:04:04 +10009116
9117/*[clinic input]
9118os.isatty -> bool
9119 fd: int
9120 /
9121
9122Return True if the fd is connected to a terminal.
9123
9124Return True if the file descriptor is an open file descriptor
9125connected to the slave end of a terminal.
9126[clinic start generated code]*/
9127
Larry Hastings2f936352014-08-05 14:04:04 +10009128static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009129os_isatty_impl(PyObject *module, int fd)
9130/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009131{
Steve Dower8fc89802015-04-12 00:26:27 -04009132 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009133 _Py_BEGIN_SUPPRESS_IPH
9134 return_value = isatty(fd);
9135 _Py_END_SUPPRESS_IPH
9136 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009137}
9138
9139
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009140#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009141/*[clinic input]
9142os.pipe
9143
9144Create a pipe.
9145
9146Returns a tuple of two file descriptors:
9147 (read_fd, write_fd)
9148[clinic start generated code]*/
9149
Larry Hastings2f936352014-08-05 14:04:04 +10009150static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009151os_pipe_impl(PyObject *module)
9152/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009153{
Victor Stinner8c62be82010-05-06 00:08:46 +00009154 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009155#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009156 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009157 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009158 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009159#else
9160 int res;
9161#endif
9162
9163#ifdef MS_WINDOWS
9164 attr.nLength = sizeof(attr);
9165 attr.lpSecurityDescriptor = NULL;
9166 attr.bInheritHandle = FALSE;
9167
9168 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009169 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009170 ok = CreatePipe(&read, &write, &attr, 0);
9171 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009172 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9173 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009174 if (fds[0] == -1 || fds[1] == -1) {
9175 CloseHandle(read);
9176 CloseHandle(write);
9177 ok = 0;
9178 }
9179 }
Steve Dowerc3630612016-11-19 18:41:16 -08009180 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009181 Py_END_ALLOW_THREADS
9182
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009184 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009185#else
9186
9187#ifdef HAVE_PIPE2
9188 Py_BEGIN_ALLOW_THREADS
9189 res = pipe2(fds, O_CLOEXEC);
9190 Py_END_ALLOW_THREADS
9191
9192 if (res != 0 && errno == ENOSYS)
9193 {
9194#endif
9195 Py_BEGIN_ALLOW_THREADS
9196 res = pipe(fds);
9197 Py_END_ALLOW_THREADS
9198
9199 if (res == 0) {
9200 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9201 close(fds[0]);
9202 close(fds[1]);
9203 return NULL;
9204 }
9205 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9206 close(fds[0]);
9207 close(fds[1]);
9208 return NULL;
9209 }
9210 }
9211#ifdef HAVE_PIPE2
9212 }
9213#endif
9214
9215 if (res != 0)
9216 return PyErr_SetFromErrno(PyExc_OSError);
9217#endif /* !MS_WINDOWS */
9218 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009219}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009220#endif /* HAVE_PIPE */
9221
Larry Hastings2f936352014-08-05 14:04:04 +10009222
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009223#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009224/*[clinic input]
9225os.pipe2
9226
9227 flags: int
9228 /
9229
9230Create a pipe with flags set atomically.
9231
9232Returns a tuple of two file descriptors:
9233 (read_fd, write_fd)
9234
9235flags can be constructed by ORing together one or more of these values:
9236O_NONBLOCK, O_CLOEXEC.
9237[clinic start generated code]*/
9238
Larry Hastings2f936352014-08-05 14:04:04 +10009239static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009240os_pipe2_impl(PyObject *module, int flags)
9241/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009242{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009243 int fds[2];
9244 int res;
9245
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009246 res = pipe2(fds, flags);
9247 if (res != 0)
9248 return posix_error();
9249 return Py_BuildValue("(ii)", fds[0], fds[1]);
9250}
9251#endif /* HAVE_PIPE2 */
9252
Larry Hastings2f936352014-08-05 14:04:04 +10009253
Ross Lagerwall7807c352011-03-17 20:20:30 +02009254#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009255/*[clinic input]
9256os.writev -> Py_ssize_t
9257 fd: int
9258 buffers: object
9259 /
9260
9261Iterate over buffers, and write the contents of each to a file descriptor.
9262
9263Returns the total number of bytes written.
9264buffers must be a sequence of bytes-like objects.
9265[clinic start generated code]*/
9266
Larry Hastings2f936352014-08-05 14:04:04 +10009267static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009268os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9269/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009270{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009271 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009272 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009273 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009274 struct iovec *iov;
9275 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009276
9277 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009278 PyErr_SetString(PyExc_TypeError,
9279 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009280 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009281 }
Larry Hastings2f936352014-08-05 14:04:04 +10009282 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009283 if (cnt < 0)
9284 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009285
Larry Hastings2f936352014-08-05 14:04:04 +10009286 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9287 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009288 }
9289
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009290 do {
9291 Py_BEGIN_ALLOW_THREADS
9292 result = writev(fd, iov, cnt);
9293 Py_END_ALLOW_THREADS
9294 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009295
9296 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009297 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009298 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009299
Georg Brandl306336b2012-06-24 12:55:33 +02009300 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009301}
Larry Hastings2f936352014-08-05 14:04:04 +10009302#endif /* HAVE_WRITEV */
9303
9304
9305#ifdef HAVE_PWRITE
9306/*[clinic input]
9307os.pwrite -> Py_ssize_t
9308
9309 fd: int
9310 buffer: Py_buffer
9311 offset: Py_off_t
9312 /
9313
9314Write bytes to a file descriptor starting at a particular offset.
9315
9316Write buffer to fd, starting at offset bytes from the beginning of
9317the file. Returns the number of bytes writte. Does not change the
9318current file offset.
9319[clinic start generated code]*/
9320
Larry Hastings2f936352014-08-05 14:04:04 +10009321static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009322os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9323/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009324{
9325 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009326 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009327
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009328 do {
9329 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009330 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009331 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009332 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009333 Py_END_ALLOW_THREADS
9334 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009335
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009336 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009337 posix_error();
9338 return size;
9339}
9340#endif /* HAVE_PWRITE */
9341
Pablo Galindo4defba32018-01-27 16:16:37 +00009342#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9343/*[clinic input]
9344os.pwritev -> Py_ssize_t
9345
9346 fd: int
9347 buffers: object
9348 offset: Py_off_t
9349 flags: int = 0
9350 /
9351
9352Writes the contents of bytes-like objects to a file descriptor at a given offset.
9353
9354Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9355of bytes-like objects. Buffers are processed in array order. Entire contents of first
9356buffer is written before proceeding to second, and so on. The operating system may
9357set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9358This function writes the contents of each object to the file descriptor and returns
9359the total number of bytes written.
9360
9361The flags argument contains a bitwise OR of zero or more of the following flags:
9362
9363- RWF_DSYNC
9364- RWF_SYNC
9365
9366Using non-zero flags requires Linux 4.7 or newer.
9367[clinic start generated code]*/
9368
9369static Py_ssize_t
9370os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9371 int flags)
9372/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9373{
9374 Py_ssize_t cnt;
9375 Py_ssize_t result;
9376 int async_err = 0;
9377 struct iovec *iov;
9378 Py_buffer *buf;
9379
9380 if (!PySequence_Check(buffers)) {
9381 PyErr_SetString(PyExc_TypeError,
9382 "pwritev() arg 2 must be a sequence");
9383 return -1;
9384 }
9385
9386 cnt = PySequence_Size(buffers);
9387 if (cnt < 0) {
9388 return -1;
9389 }
9390
9391#ifndef HAVE_PWRITEV2
9392 if(flags != 0) {
9393 argument_unavailable_error("pwritev2", "flags");
9394 return -1;
9395 }
9396#endif
9397
9398 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9399 return -1;
9400 }
9401#ifdef HAVE_PWRITEV2
9402 do {
9403 Py_BEGIN_ALLOW_THREADS
9404 _Py_BEGIN_SUPPRESS_IPH
9405 result = pwritev2(fd, iov, cnt, offset, flags);
9406 _Py_END_SUPPRESS_IPH
9407 Py_END_ALLOW_THREADS
9408 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9409#else
9410 do {
9411 Py_BEGIN_ALLOW_THREADS
9412 _Py_BEGIN_SUPPRESS_IPH
9413 result = pwritev(fd, iov, cnt, offset);
9414 _Py_END_SUPPRESS_IPH
9415 Py_END_ALLOW_THREADS
9416 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9417#endif
9418
9419 iov_cleanup(iov, buf, cnt);
9420 if (result < 0) {
9421 if (!async_err) {
9422 posix_error();
9423 }
9424 return -1;
9425 }
9426
9427 return result;
9428}
9429#endif /* HAVE_PWRITEV */
9430
9431
9432
Larry Hastings2f936352014-08-05 14:04:04 +10009433
9434#ifdef HAVE_MKFIFO
9435/*[clinic input]
9436os.mkfifo
9437
9438 path: path_t
9439 mode: int=0o666
9440 *
9441 dir_fd: dir_fd(requires='mkfifoat')=None
9442
9443Create a "fifo" (a POSIX named pipe).
9444
9445If dir_fd is not None, it should be a file descriptor open to a directory,
9446 and path should be relative; path will then be relative to that directory.
9447dir_fd may not be implemented on your platform.
9448 If it is unavailable, using it will raise a NotImplementedError.
9449[clinic start generated code]*/
9450
Larry Hastings2f936352014-08-05 14:04:04 +10009451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009452os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9453/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009454{
9455 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009456 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009457
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009458 do {
9459 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009460#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009461 if (dir_fd != DEFAULT_DIR_FD)
9462 result = mkfifoat(dir_fd, path->narrow, mode);
9463 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009464#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009465 result = mkfifo(path->narrow, mode);
9466 Py_END_ALLOW_THREADS
9467 } while (result != 0 && errno == EINTR &&
9468 !(async_err = PyErr_CheckSignals()));
9469 if (result != 0)
9470 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009471
9472 Py_RETURN_NONE;
9473}
9474#endif /* HAVE_MKFIFO */
9475
9476
9477#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9478/*[clinic input]
9479os.mknod
9480
9481 path: path_t
9482 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009483 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009484 *
9485 dir_fd: dir_fd(requires='mknodat')=None
9486
9487Create a node in the file system.
9488
9489Create a node in the file system (file, device special file or named pipe)
9490at path. mode specifies both the permissions to use and the
9491type of node to be created, being combined (bitwise OR) with one of
9492S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9493device defines the newly created device special file (probably using
9494os.makedev()). Otherwise device is ignored.
9495
9496If dir_fd is not None, it should be a file descriptor open to a directory,
9497 and path should be relative; path will then be relative to that directory.
9498dir_fd may not be implemented on your platform.
9499 If it is unavailable, using it will raise a NotImplementedError.
9500[clinic start generated code]*/
9501
Larry Hastings2f936352014-08-05 14:04:04 +10009502static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009503os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009504 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009505/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009506{
9507 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009508 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009509
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009510 do {
9511 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009512#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009513 if (dir_fd != DEFAULT_DIR_FD)
9514 result = mknodat(dir_fd, path->narrow, mode, device);
9515 else
Larry Hastings2f936352014-08-05 14:04:04 +10009516#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009517 result = mknod(path->narrow, mode, device);
9518 Py_END_ALLOW_THREADS
9519 } while (result != 0 && errno == EINTR &&
9520 !(async_err = PyErr_CheckSignals()));
9521 if (result != 0)
9522 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009523
9524 Py_RETURN_NONE;
9525}
9526#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9527
9528
9529#ifdef HAVE_DEVICE_MACROS
9530/*[clinic input]
9531os.major -> unsigned_int
9532
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009533 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009534 /
9535
9536Extracts a device major number from a raw device number.
9537[clinic start generated code]*/
9538
Larry Hastings2f936352014-08-05 14:04:04 +10009539static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009540os_major_impl(PyObject *module, dev_t device)
9541/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009542{
9543 return major(device);
9544}
9545
9546
9547/*[clinic input]
9548os.minor -> unsigned_int
9549
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009550 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009551 /
9552
9553Extracts a device minor number from a raw device number.
9554[clinic start generated code]*/
9555
Larry Hastings2f936352014-08-05 14:04:04 +10009556static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009557os_minor_impl(PyObject *module, dev_t device)
9558/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009559{
9560 return minor(device);
9561}
9562
9563
9564/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009565os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009566
9567 major: int
9568 minor: int
9569 /
9570
9571Composes a raw device number from the major and minor device numbers.
9572[clinic start generated code]*/
9573
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009574static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009575os_makedev_impl(PyObject *module, int major, int minor)
9576/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009577{
9578 return makedev(major, minor);
9579}
9580#endif /* HAVE_DEVICE_MACROS */
9581
9582
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009583#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009584/*[clinic input]
9585os.ftruncate
9586
9587 fd: int
9588 length: Py_off_t
9589 /
9590
9591Truncate a file, specified by file descriptor, to a specific length.
9592[clinic start generated code]*/
9593
Larry Hastings2f936352014-08-05 14:04:04 +10009594static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009595os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9596/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009597{
9598 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009599 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009600
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009601 do {
9602 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009603 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009604#ifdef MS_WINDOWS
9605 result = _chsize_s(fd, length);
9606#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009607 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009608#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009609 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009610 Py_END_ALLOW_THREADS
9611 } while (result != 0 && errno == EINTR &&
9612 !(async_err = PyErr_CheckSignals()));
9613 if (result != 0)
9614 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009615 Py_RETURN_NONE;
9616}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009617#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009618
9619
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009620#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009621/*[clinic input]
9622os.truncate
9623 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9624 length: Py_off_t
9625
9626Truncate a file, specified by path, to a specific length.
9627
9628On some platforms, path may also be specified as an open file descriptor.
9629 If this functionality is unavailable, using it raises an exception.
9630[clinic start generated code]*/
9631
Larry Hastings2f936352014-08-05 14:04:04 +10009632static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009633os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9634/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009635{
9636 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009637#ifdef MS_WINDOWS
9638 int fd;
9639#endif
9640
9641 if (path->fd != -1)
9642 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009643
9644 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009645 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009646#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009647 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009648 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009649 result = -1;
9650 else {
9651 result = _chsize_s(fd, length);
9652 close(fd);
9653 if (result < 0)
9654 errno = result;
9655 }
9656#else
9657 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009658#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009659 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009660 Py_END_ALLOW_THREADS
9661 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009662 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009663
9664 Py_RETURN_NONE;
9665}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009666#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009667
Ross Lagerwall7807c352011-03-17 20:20:30 +02009668
Victor Stinnerd6b17692014-09-30 12:20:05 +02009669/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9670 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9671 defined, which is the case in Python on AIX. AIX bug report:
9672 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9673#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9674# define POSIX_FADVISE_AIX_BUG
9675#endif
9676
Victor Stinnerec39e262014-09-30 12:35:58 +02009677
Victor Stinnerd6b17692014-09-30 12:20:05 +02009678#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009679/*[clinic input]
9680os.posix_fallocate
9681
9682 fd: int
9683 offset: Py_off_t
9684 length: Py_off_t
9685 /
9686
9687Ensure a file has allocated at least a particular number of bytes on disk.
9688
9689Ensure that the file specified by fd encompasses a range of bytes
9690starting at offset bytes from the beginning and continuing for length bytes.
9691[clinic start generated code]*/
9692
Larry Hastings2f936352014-08-05 14:04:04 +10009693static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009694os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009695 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009696/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009697{
9698 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009699 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009700
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009701 do {
9702 Py_BEGIN_ALLOW_THREADS
9703 result = posix_fallocate(fd, offset, length);
9704 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009705 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9706
9707 if (result == 0)
9708 Py_RETURN_NONE;
9709
9710 if (async_err)
9711 return NULL;
9712
9713 errno = result;
9714 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009715}
Victor Stinnerec39e262014-09-30 12:35:58 +02009716#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009717
Ross Lagerwall7807c352011-03-17 20:20:30 +02009718
Victor Stinnerd6b17692014-09-30 12:20:05 +02009719#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009720/*[clinic input]
9721os.posix_fadvise
9722
9723 fd: int
9724 offset: Py_off_t
9725 length: Py_off_t
9726 advice: int
9727 /
9728
9729Announce an intention to access data in a specific pattern.
9730
9731Announce an intention to access data in a specific pattern, thus allowing
9732the kernel to make optimizations.
9733The advice applies to the region of the file specified by fd starting at
9734offset and continuing for length bytes.
9735advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9736POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9737POSIX_FADV_DONTNEED.
9738[clinic start generated code]*/
9739
Larry Hastings2f936352014-08-05 14:04:04 +10009740static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009741os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009742 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009743/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009744{
9745 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009746 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009747
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009748 do {
9749 Py_BEGIN_ALLOW_THREADS
9750 result = posix_fadvise(fd, offset, length, advice);
9751 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009752 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9753
9754 if (result == 0)
9755 Py_RETURN_NONE;
9756
9757 if (async_err)
9758 return NULL;
9759
9760 errno = result;
9761 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009762}
Victor Stinnerec39e262014-09-30 12:35:58 +02009763#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009764
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009765#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009766
Fred Drake762e2061999-08-26 17:23:54 +00009767/* Save putenv() parameters as values here, so we can collect them when they
9768 * get re-set with another call for the same key. */
9769static PyObject *posix_putenv_garbage;
9770
Larry Hastings2f936352014-08-05 14:04:04 +10009771static void
9772posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009773{
Larry Hastings2f936352014-08-05 14:04:04 +10009774 /* Install the first arg and newstr in posix_putenv_garbage;
9775 * this will cause previous value to be collected. This has to
9776 * happen after the real putenv() call because the old value
9777 * was still accessible until then. */
9778 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9779 /* really not much we can do; just leak */
9780 PyErr_Clear();
9781 else
9782 Py_DECREF(value);
9783}
9784
9785
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009786#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009787/*[clinic input]
9788os.putenv
9789
9790 name: unicode
9791 value: unicode
9792 /
9793
9794Change or add an environment variable.
9795[clinic start generated code]*/
9796
Larry Hastings2f936352014-08-05 14:04:04 +10009797static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009798os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9799/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009800{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009801 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009802 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009803
Serhiy Storchaka77703942017-06-25 07:33:01 +03009804 /* Search from index 1 because on Windows starting '=' is allowed for
9805 defining hidden environment variables. */
9806 if (PyUnicode_GET_LENGTH(name) == 0 ||
9807 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9808 {
9809 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9810 return NULL;
9811 }
Larry Hastings2f936352014-08-05 14:04:04 +10009812 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9813 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009814 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009815 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009816
9817 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9818 if (env == NULL)
9819 goto error;
9820 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009821 PyErr_Format(PyExc_ValueError,
9822 "the environment variable is longer than %u characters",
9823 _MAX_ENV);
9824 goto error;
9825 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009826 if (wcslen(env) != (size_t)size) {
9827 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009828 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009829 }
9830
Larry Hastings2f936352014-08-05 14:04:04 +10009831 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009833 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009835
Larry Hastings2f936352014-08-05 14:04:04 +10009836 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009837 Py_RETURN_NONE;
9838
9839error:
Larry Hastings2f936352014-08-05 14:04:04 +10009840 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009841 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009842}
Larry Hastings2f936352014-08-05 14:04:04 +10009843#else /* MS_WINDOWS */
9844/*[clinic input]
9845os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009846
Larry Hastings2f936352014-08-05 14:04:04 +10009847 name: FSConverter
9848 value: FSConverter
9849 /
9850
9851Change or add an environment variable.
9852[clinic start generated code]*/
9853
Larry Hastings2f936352014-08-05 14:04:04 +10009854static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009855os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9856/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009857{
9858 PyObject *bytes = NULL;
9859 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009860 const char *name_string = PyBytes_AS_STRING(name);
9861 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009862
Serhiy Storchaka77703942017-06-25 07:33:01 +03009863 if (strchr(name_string, '=') != NULL) {
9864 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9865 return NULL;
9866 }
Larry Hastings2f936352014-08-05 14:04:04 +10009867 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9868 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009869 return NULL;
9870 }
9871
9872 env = PyBytes_AS_STRING(bytes);
9873 if (putenv(env)) {
9874 Py_DECREF(bytes);
9875 return posix_error();
9876 }
9877
9878 posix_putenv_garbage_setitem(name, bytes);
9879 Py_RETURN_NONE;
9880}
9881#endif /* MS_WINDOWS */
9882#endif /* HAVE_PUTENV */
9883
9884
9885#ifdef HAVE_UNSETENV
9886/*[clinic input]
9887os.unsetenv
9888 name: FSConverter
9889 /
9890
9891Delete an environment variable.
9892[clinic start generated code]*/
9893
Larry Hastings2f936352014-08-05 14:04:04 +10009894static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009895os_unsetenv_impl(PyObject *module, PyObject *name)
9896/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009897{
Victor Stinner984890f2011-11-24 13:53:38 +01009898#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009899 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009900#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009901
Victor Stinner984890f2011-11-24 13:53:38 +01009902#ifdef HAVE_BROKEN_UNSETENV
9903 unsetenv(PyBytes_AS_STRING(name));
9904#else
Victor Stinner65170952011-11-22 22:16:17 +01009905 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009906 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009907 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009908#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009909
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 /* Remove the key from posix_putenv_garbage;
9911 * this will cause it to be collected. This has to
9912 * happen after the real unsetenv() call because the
9913 * old value was still accessible until then.
9914 */
Victor Stinner65170952011-11-22 22:16:17 +01009915 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 /* really not much we can do; just leak */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02009917 if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
9918 return NULL;
9919 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 PyErr_Clear();
9921 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009922 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009923}
Larry Hastings2f936352014-08-05 14:04:04 +10009924#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009925
Larry Hastings2f936352014-08-05 14:04:04 +10009926
9927/*[clinic input]
9928os.strerror
9929
9930 code: int
9931 /
9932
9933Translate an error code to a message string.
9934[clinic start generated code]*/
9935
Larry Hastings2f936352014-08-05 14:04:04 +10009936static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009937os_strerror_impl(PyObject *module, int code)
9938/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009939{
9940 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 if (message == NULL) {
9942 PyErr_SetString(PyExc_ValueError,
9943 "strerror() argument out of range");
9944 return NULL;
9945 }
Victor Stinner1b579672011-12-17 05:47:23 +01009946 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009947}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009948
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009949
Guido van Rossumc9641791998-08-04 15:26:23 +00009950#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009951#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009952/*[clinic input]
9953os.WCOREDUMP -> bool
9954
9955 status: int
9956 /
9957
9958Return True if the process returning status was dumped to a core file.
9959[clinic start generated code]*/
9960
Larry Hastings2f936352014-08-05 14:04:04 +10009961static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009962os_WCOREDUMP_impl(PyObject *module, int status)
9963/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009964{
9965 WAIT_TYPE wait_status;
9966 WAIT_STATUS_INT(wait_status) = status;
9967 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009968}
9969#endif /* WCOREDUMP */
9970
Larry Hastings2f936352014-08-05 14:04:04 +10009971
Fred Drake106c1a02002-04-23 15:58:02 +00009972#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009973/*[clinic input]
9974os.WIFCONTINUED -> bool
9975
9976 status: int
9977
9978Return True if a particular process was continued from a job control stop.
9979
9980Return True if the process returning status was continued from a
9981job control stop.
9982[clinic start generated code]*/
9983
Larry Hastings2f936352014-08-05 14:04:04 +10009984static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009985os_WIFCONTINUED_impl(PyObject *module, int status)
9986/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009987{
9988 WAIT_TYPE wait_status;
9989 WAIT_STATUS_INT(wait_status) = status;
9990 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009991}
9992#endif /* WIFCONTINUED */
9993
Larry Hastings2f936352014-08-05 14:04:04 +10009994
Guido van Rossumc9641791998-08-04 15:26:23 +00009995#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009996/*[clinic input]
9997os.WIFSTOPPED -> bool
9998
9999 status: int
10000
10001Return True if the process returning status was stopped.
10002[clinic start generated code]*/
10003
Larry Hastings2f936352014-08-05 14:04:04 +100010004static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010005os_WIFSTOPPED_impl(PyObject *module, int status)
10006/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010007{
10008 WAIT_TYPE wait_status;
10009 WAIT_STATUS_INT(wait_status) = status;
10010 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010011}
10012#endif /* WIFSTOPPED */
10013
Larry Hastings2f936352014-08-05 14:04:04 +100010014
Guido van Rossumc9641791998-08-04 15:26:23 +000010015#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010016/*[clinic input]
10017os.WIFSIGNALED -> bool
10018
10019 status: int
10020
10021Return True if the process returning status was terminated by a signal.
10022[clinic start generated code]*/
10023
Larry Hastings2f936352014-08-05 14:04:04 +100010024static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010025os_WIFSIGNALED_impl(PyObject *module, int status)
10026/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010027{
10028 WAIT_TYPE wait_status;
10029 WAIT_STATUS_INT(wait_status) = status;
10030 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010031}
10032#endif /* WIFSIGNALED */
10033
Larry Hastings2f936352014-08-05 14:04:04 +100010034
Guido van Rossumc9641791998-08-04 15:26:23 +000010035#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010036/*[clinic input]
10037os.WIFEXITED -> bool
10038
10039 status: int
10040
10041Return True if the process returning status exited via the exit() system call.
10042[clinic start generated code]*/
10043
Larry Hastings2f936352014-08-05 14:04:04 +100010044static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010045os_WIFEXITED_impl(PyObject *module, int status)
10046/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010047{
10048 WAIT_TYPE wait_status;
10049 WAIT_STATUS_INT(wait_status) = status;
10050 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010051}
10052#endif /* WIFEXITED */
10053
Larry Hastings2f936352014-08-05 14:04:04 +100010054
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010055#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010056/*[clinic input]
10057os.WEXITSTATUS -> int
10058
10059 status: int
10060
10061Return the process return code from status.
10062[clinic start generated code]*/
10063
Larry Hastings2f936352014-08-05 14:04:04 +100010064static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010065os_WEXITSTATUS_impl(PyObject *module, int status)
10066/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010067{
10068 WAIT_TYPE wait_status;
10069 WAIT_STATUS_INT(wait_status) = status;
10070 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010071}
10072#endif /* WEXITSTATUS */
10073
Larry Hastings2f936352014-08-05 14:04:04 +100010074
Guido van Rossumc9641791998-08-04 15:26:23 +000010075#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010076/*[clinic input]
10077os.WTERMSIG -> int
10078
10079 status: int
10080
10081Return the signal that terminated the process that provided the status value.
10082[clinic start generated code]*/
10083
Larry Hastings2f936352014-08-05 14:04:04 +100010084static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010085os_WTERMSIG_impl(PyObject *module, int status)
10086/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010087{
10088 WAIT_TYPE wait_status;
10089 WAIT_STATUS_INT(wait_status) = status;
10090 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010091}
10092#endif /* WTERMSIG */
10093
Larry Hastings2f936352014-08-05 14:04:04 +100010094
Guido van Rossumc9641791998-08-04 15:26:23 +000010095#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010096/*[clinic input]
10097os.WSTOPSIG -> int
10098
10099 status: int
10100
10101Return the signal that stopped the process that provided the status value.
10102[clinic start generated code]*/
10103
Larry Hastings2f936352014-08-05 14:04:04 +100010104static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010105os_WSTOPSIG_impl(PyObject *module, int status)
10106/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010107{
10108 WAIT_TYPE wait_status;
10109 WAIT_STATUS_INT(wait_status) = status;
10110 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010111}
10112#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010113#endif /* HAVE_SYS_WAIT_H */
10114
10115
Thomas Wouters477c8d52006-05-27 19:21:47 +000010116#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010117#ifdef _SCO_DS
10118/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10119 needed definitions in sys/statvfs.h */
10120#define _SVID3
10121#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010122#include <sys/statvfs.h>
10123
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010124static PyObject*
10125_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -080010126 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 if (v == NULL)
10128 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010129
10130#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10132 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10133 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10134 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10135 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10136 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10137 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10138 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10139 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10140 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010141#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10143 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10144 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010145 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010147 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010149 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010151 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010153 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010155 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10157 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010158#endif
Michael Felt502d5512018-01-05 13:01:58 +010010159/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10160 * (issue #32390). */
10161#if defined(_AIX) && defined(_ALL_SOURCE)
10162 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10163#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010164 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010165#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010166 if (PyErr_Occurred()) {
10167 Py_DECREF(v);
10168 return NULL;
10169 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010170
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010172}
10173
Larry Hastings2f936352014-08-05 14:04:04 +100010174
10175/*[clinic input]
10176os.fstatvfs
10177 fd: int
10178 /
10179
10180Perform an fstatvfs system call on the given fd.
10181
10182Equivalent to statvfs(fd).
10183[clinic start generated code]*/
10184
Larry Hastings2f936352014-08-05 14:04:04 +100010185static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010186os_fstatvfs_impl(PyObject *module, int fd)
10187/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010188{
10189 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010190 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010192
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010193 do {
10194 Py_BEGIN_ALLOW_THREADS
10195 result = fstatvfs(fd, &st);
10196 Py_END_ALLOW_THREADS
10197 } while (result != 0 && errno == EINTR &&
10198 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010199 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010200 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010201
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010203}
Larry Hastings2f936352014-08-05 14:04:04 +100010204#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010205
10206
Thomas Wouters477c8d52006-05-27 19:21:47 +000010207#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010208#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010209/*[clinic input]
10210os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010211
Larry Hastings2f936352014-08-05 14:04:04 +100010212 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10213
10214Perform a statvfs system call on the given path.
10215
10216path may always be specified as a string.
10217On some platforms, path may also be specified as an open file descriptor.
10218 If this functionality is unavailable, using it raises an exception.
10219[clinic start generated code]*/
10220
Larry Hastings2f936352014-08-05 14:04:04 +100010221static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010222os_statvfs_impl(PyObject *module, path_t *path)
10223/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010224{
10225 int result;
10226 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010227
10228 Py_BEGIN_ALLOW_THREADS
10229#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010230 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010231#ifdef __APPLE__
10232 /* handle weak-linking on Mac OS X 10.3 */
10233 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010234 fd_specified("statvfs", path->fd);
10235 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010236 }
10237#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010238 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010239 }
10240 else
10241#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010242 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010243 Py_END_ALLOW_THREADS
10244
10245 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010246 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010247 }
10248
Larry Hastings2f936352014-08-05 14:04:04 +100010249 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010250}
Larry Hastings2f936352014-08-05 14:04:04 +100010251#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10252
Guido van Rossum94f6f721999-01-06 18:42:14 +000010253
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010254#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010255/*[clinic input]
10256os._getdiskusage
10257
Steve Dower23ad6d02018-02-22 10:39:10 -080010258 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010259
10260Return disk usage statistics about the given path as a (total, free) tuple.
10261[clinic start generated code]*/
10262
Larry Hastings2f936352014-08-05 14:04:04 +100010263static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010264os__getdiskusage_impl(PyObject *module, path_t *path)
10265/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010266{
10267 BOOL retval;
10268 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010269 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010270
10271 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010272 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010273 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010274 if (retval == 0) {
10275 if (GetLastError() == ERROR_DIRECTORY) {
10276 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010277
Joe Pamerc8c02492018-09-25 10:57:36 -040010278 dir_path = PyMem_New(wchar_t, path->length + 1);
10279 if (dir_path == NULL) {
10280 return PyErr_NoMemory();
10281 }
10282
10283 wcscpy_s(dir_path, path->length + 1, path->wide);
10284
10285 if (_dirnameW(dir_path) != -1) {
10286 Py_BEGIN_ALLOW_THREADS
10287 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10288 Py_END_ALLOW_THREADS
10289 }
10290 /* Record the last error in case it's modified by PyMem_Free. */
10291 err = GetLastError();
10292 PyMem_Free(dir_path);
10293 if (retval) {
10294 goto success;
10295 }
10296 }
10297 return PyErr_SetFromWindowsErr(err);
10298 }
10299
10300success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010301 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10302}
Larry Hastings2f936352014-08-05 14:04:04 +100010303#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010304
10305
Fred Drakec9680921999-12-13 16:37:25 +000010306/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10307 * It maps strings representing configuration variable names to
10308 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010309 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010310 * rarely-used constants. There are three separate tables that use
10311 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010312 *
10313 * This code is always included, even if none of the interfaces that
10314 * need it are included. The #if hackery needed to avoid it would be
10315 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010316 */
10317struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010318 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010319 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010320};
10321
Fred Drake12c6e2d1999-12-14 21:25:03 +000010322static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010323conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010324 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010325{
Christian Heimes217cfd12007-12-02 14:31:20 +000010326 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010327 int value = _PyLong_AsInt(arg);
10328 if (value == -1 && PyErr_Occurred())
10329 return 0;
10330 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010331 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010332 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010333 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010334 /* look up the value in the table using a binary search */
10335 size_t lo = 0;
10336 size_t mid;
10337 size_t hi = tablesize;
10338 int cmp;
10339 const char *confname;
10340 if (!PyUnicode_Check(arg)) {
10341 PyErr_SetString(PyExc_TypeError,
10342 "configuration names must be strings or integers");
10343 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010345 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010346 if (confname == NULL)
10347 return 0;
10348 while (lo < hi) {
10349 mid = (lo + hi) / 2;
10350 cmp = strcmp(confname, table[mid].name);
10351 if (cmp < 0)
10352 hi = mid;
10353 else if (cmp > 0)
10354 lo = mid + 1;
10355 else {
10356 *valuep = table[mid].value;
10357 return 1;
10358 }
10359 }
10360 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10361 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010363}
10364
10365
10366#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10367static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010368#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010369 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010370#endif
10371#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010372 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010373#endif
Fred Drakec9680921999-12-13 16:37:25 +000010374#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010375 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010376#endif
10377#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010378 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010379#endif
10380#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010381 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010382#endif
10383#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010384 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010385#endif
10386#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010387 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010388#endif
10389#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010390 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010391#endif
10392#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010393 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010394#endif
10395#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010396 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010397#endif
10398#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010399 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010400#endif
10401#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010402 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010403#endif
10404#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010405 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010406#endif
10407#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010408 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010409#endif
10410#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010412#endif
10413#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010415#endif
10416#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010418#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010419#ifdef _PC_ACL_ENABLED
10420 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10421#endif
10422#ifdef _PC_MIN_HOLE_SIZE
10423 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10424#endif
10425#ifdef _PC_ALLOC_SIZE_MIN
10426 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10427#endif
10428#ifdef _PC_REC_INCR_XFER_SIZE
10429 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10430#endif
10431#ifdef _PC_REC_MAX_XFER_SIZE
10432 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10433#endif
10434#ifdef _PC_REC_MIN_XFER_SIZE
10435 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10436#endif
10437#ifdef _PC_REC_XFER_ALIGN
10438 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10439#endif
10440#ifdef _PC_SYMLINK_MAX
10441 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10442#endif
10443#ifdef _PC_XATTR_ENABLED
10444 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10445#endif
10446#ifdef _PC_XATTR_EXISTS
10447 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10448#endif
10449#ifdef _PC_TIMESTAMP_RESOLUTION
10450 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10451#endif
Fred Drakec9680921999-12-13 16:37:25 +000010452};
10453
Fred Drakec9680921999-12-13 16:37:25 +000010454static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010455conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010456{
10457 return conv_confname(arg, valuep, posix_constants_pathconf,
10458 sizeof(posix_constants_pathconf)
10459 / sizeof(struct constdef));
10460}
10461#endif
10462
Larry Hastings2f936352014-08-05 14:04:04 +100010463
Fred Drakec9680921999-12-13 16:37:25 +000010464#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010465/*[clinic input]
10466os.fpathconf -> long
10467
10468 fd: int
10469 name: path_confname
10470 /
10471
10472Return the configuration limit name for the file descriptor fd.
10473
10474If there is no limit, return -1.
10475[clinic start generated code]*/
10476
Larry Hastings2f936352014-08-05 14:04:04 +100010477static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010478os_fpathconf_impl(PyObject *module, int fd, int name)
10479/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010480{
10481 long limit;
10482
10483 errno = 0;
10484 limit = fpathconf(fd, name);
10485 if (limit == -1 && errno != 0)
10486 posix_error();
10487
10488 return limit;
10489}
10490#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010491
10492
10493#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010494/*[clinic input]
10495os.pathconf -> long
10496 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10497 name: path_confname
10498
10499Return the configuration limit name for the file or directory path.
10500
10501If there is no limit, return -1.
10502On some platforms, path may also be specified as an open file descriptor.
10503 If this functionality is unavailable, using it raises an exception.
10504[clinic start generated code]*/
10505
Larry Hastings2f936352014-08-05 14:04:04 +100010506static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010507os_pathconf_impl(PyObject *module, path_t *path, int name)
10508/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010509{
Victor Stinner8c62be82010-05-06 00:08:46 +000010510 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010511
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010513#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010514 if (path->fd != -1)
10515 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010516 else
10517#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010518 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010519 if (limit == -1 && errno != 0) {
10520 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010521 /* could be a path or name problem */
10522 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010523 else
Larry Hastings2f936352014-08-05 14:04:04 +100010524 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 }
Larry Hastings2f936352014-08-05 14:04:04 +100010526
10527 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010528}
Larry Hastings2f936352014-08-05 14:04:04 +100010529#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010530
10531#ifdef HAVE_CONFSTR
10532static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010533#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010534 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010535#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010536#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010538#endif
10539#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010540 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010541#endif
Fred Draked86ed291999-12-15 15:34:33 +000010542#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010544#endif
10545#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010546 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010547#endif
10548#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010550#endif
10551#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010552 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010553#endif
Fred Drakec9680921999-12-13 16:37:25 +000010554#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010555 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010556#endif
10557#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010558 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010559#endif
10560#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010561 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010562#endif
10563#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010564 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010565#endif
10566#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010567 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010568#endif
10569#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010570 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010571#endif
10572#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010573 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010574#endif
10575#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010576 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010577#endif
Fred Draked86ed291999-12-15 15:34:33 +000010578#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010579 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010580#endif
Fred Drakec9680921999-12-13 16:37:25 +000010581#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010582 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010583#endif
Fred Draked86ed291999-12-15 15:34:33 +000010584#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010585 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010586#endif
10587#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010589#endif
10590#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010591 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010592#endif
10593#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010594 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010595#endif
Fred Drakec9680921999-12-13 16:37:25 +000010596#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010597 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010598#endif
10599#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010600 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010601#endif
10602#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010604#endif
10605#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010606 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010607#endif
10608#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010609 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010610#endif
10611#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010612 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010613#endif
10614#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010615 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010616#endif
10617#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010618 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010619#endif
10620#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010621 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010622#endif
10623#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010624 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010625#endif
10626#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010627 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010628#endif
10629#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010630 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010631#endif
10632#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010633 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010634#endif
10635#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010636 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010637#endif
10638#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010639 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010640#endif
10641#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010642 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010643#endif
Fred Draked86ed291999-12-15 15:34:33 +000010644#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010645 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010646#endif
10647#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010649#endif
10650#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010651 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010652#endif
10653#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010655#endif
10656#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010657 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010658#endif
10659#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010660 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010661#endif
10662#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010664#endif
10665#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010667#endif
10668#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010670#endif
10671#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010673#endif
10674#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010676#endif
10677#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010679#endif
10680#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010682#endif
Fred Drakec9680921999-12-13 16:37:25 +000010683};
10684
10685static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010686conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010687{
10688 return conv_confname(arg, valuep, posix_constants_confstr,
10689 sizeof(posix_constants_confstr)
10690 / sizeof(struct constdef));
10691}
10692
Larry Hastings2f936352014-08-05 14:04:04 +100010693
10694/*[clinic input]
10695os.confstr
10696
10697 name: confstr_confname
10698 /
10699
10700Return a string-valued system configuration variable.
10701[clinic start generated code]*/
10702
Larry Hastings2f936352014-08-05 14:04:04 +100010703static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010704os_confstr_impl(PyObject *module, int name)
10705/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010706{
10707 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010708 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010709 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010710
Victor Stinnercb043522010-09-10 23:49:04 +000010711 errno = 0;
10712 len = confstr(name, buffer, sizeof(buffer));
10713 if (len == 0) {
10714 if (errno) {
10715 posix_error();
10716 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010717 }
10718 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010719 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010720 }
10721 }
Victor Stinnercb043522010-09-10 23:49:04 +000010722
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010723 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010724 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010725 char *buf = PyMem_Malloc(len);
10726 if (buf == NULL)
10727 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010728 len2 = confstr(name, buf, len);
10729 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010730 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010731 PyMem_Free(buf);
10732 }
10733 else
10734 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010735 return result;
10736}
Larry Hastings2f936352014-08-05 14:04:04 +100010737#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010738
10739
10740#ifdef HAVE_SYSCONF
10741static struct constdef posix_constants_sysconf[] = {
10742#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010743 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010744#endif
10745#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010746 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010747#endif
10748#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010749 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010750#endif
10751#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010752 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010753#endif
10754#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010755 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010756#endif
10757#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010758 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010759#endif
10760#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010761 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010762#endif
10763#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010764 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010765#endif
10766#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010767 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010768#endif
10769#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010770 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010771#endif
Fred Draked86ed291999-12-15 15:34:33 +000010772#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010773 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010774#endif
10775#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010776 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010777#endif
Fred Drakec9680921999-12-13 16:37:25 +000010778#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010779 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010780#endif
Fred Drakec9680921999-12-13 16:37:25 +000010781#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010782 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010783#endif
10784#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010785 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010786#endif
10787#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010788 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010789#endif
10790#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010791 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010792#endif
10793#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010794 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010795#endif
Fred Draked86ed291999-12-15 15:34:33 +000010796#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010797 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010798#endif
Fred Drakec9680921999-12-13 16:37:25 +000010799#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010800 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010801#endif
10802#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010803 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010804#endif
10805#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010806 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010807#endif
10808#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010809 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010810#endif
10811#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010812 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010813#endif
Fred Draked86ed291999-12-15 15:34:33 +000010814#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010815 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010816#endif
Fred Drakec9680921999-12-13 16:37:25 +000010817#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010818 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010819#endif
10820#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010821 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010822#endif
10823#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010824 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010825#endif
10826#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010827 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010828#endif
10829#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010830 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010831#endif
10832#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010833 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010834#endif
10835#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010836 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010837#endif
10838#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010839 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010840#endif
10841#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010842 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010843#endif
10844#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010845 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010846#endif
10847#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010848 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010849#endif
10850#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010851 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010852#endif
10853#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010855#endif
10856#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010857 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010858#endif
10859#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010860 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010861#endif
10862#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010863 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010864#endif
10865#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010866 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010867#endif
10868#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010869 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010870#endif
10871#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010873#endif
10874#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010875 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010876#endif
10877#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010878 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010879#endif
10880#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010881 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010882#endif
10883#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010884 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010885#endif
Fred Draked86ed291999-12-15 15:34:33 +000010886#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010887 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010888#endif
Fred Drakec9680921999-12-13 16:37:25 +000010889#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010890 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010891#endif
10892#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010893 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010894#endif
10895#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010896 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010897#endif
Fred Draked86ed291999-12-15 15:34:33 +000010898#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010899 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010900#endif
Fred Drakec9680921999-12-13 16:37:25 +000010901#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010902 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010903#endif
Fred Draked86ed291999-12-15 15:34:33 +000010904#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010906#endif
10907#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010908 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010909#endif
Fred Drakec9680921999-12-13 16:37:25 +000010910#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010911 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010912#endif
10913#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010914 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010915#endif
10916#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010917 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010918#endif
10919#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010920 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010921#endif
Fred Draked86ed291999-12-15 15:34:33 +000010922#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010923 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010924#endif
Fred Drakec9680921999-12-13 16:37:25 +000010925#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010926 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010927#endif
10928#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010929 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010930#endif
10931#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010932 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010933#endif
10934#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010936#endif
10937#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010939#endif
10940#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010942#endif
10943#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010945#endif
Fred Draked86ed291999-12-15 15:34:33 +000010946#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010947 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010948#endif
Fred Drakec9680921999-12-13 16:37:25 +000010949#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010950 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010951#endif
10952#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010953 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010954#endif
Fred Draked86ed291999-12-15 15:34:33 +000010955#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010957#endif
Fred Drakec9680921999-12-13 16:37:25 +000010958#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010960#endif
10961#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010962 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010963#endif
10964#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010965 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010966#endif
10967#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010968 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010969#endif
10970#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010972#endif
10973#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010975#endif
10976#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010977 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010978#endif
10979#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010981#endif
10982#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010984#endif
Fred Draked86ed291999-12-15 15:34:33 +000010985#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010986 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010987#endif
10988#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010989 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010990#endif
Fred Drakec9680921999-12-13 16:37:25 +000010991#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010992 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010993#endif
10994#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010996#endif
10997#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010998 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010999#endif
11000#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011001 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011002#endif
11003#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011005#endif
11006#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011007 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011008#endif
11009#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011011#endif
11012#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011013 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011014#endif
11015#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011016 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011017#endif
11018#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011019 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011020#endif
11021#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011023#endif
11024#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011025 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011026#endif
11027#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011028 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011029#endif
11030#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011031 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011032#endif
11033#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011034 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011035#endif
11036#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011037 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011038#endif
11039#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011040 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011041#endif
11042#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011043 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011044#endif
11045#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011046 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011047#endif
11048#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011049 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011050#endif
11051#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011052 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011053#endif
11054#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011055 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011056#endif
11057#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011058 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011059#endif
11060#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011061 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011062#endif
11063#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011065#endif
11066#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011068#endif
11069#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011070 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011071#endif
11072#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011073 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011074#endif
11075#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011076 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011077#endif
11078#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011079 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011080#endif
11081#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011082 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011083#endif
11084#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011086#endif
11087#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011088 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011089#endif
11090#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011091 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011092#endif
11093#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011094 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011095#endif
Fred Draked86ed291999-12-15 15:34:33 +000011096#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011097 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011098#endif
Fred Drakec9680921999-12-13 16:37:25 +000011099#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011100 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011101#endif
11102#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011103 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011104#endif
11105#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011106 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011107#endif
11108#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011110#endif
11111#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011112 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011113#endif
11114#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011115 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011116#endif
11117#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011118 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011119#endif
11120#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011121 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011122#endif
11123#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011124 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011125#endif
11126#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011127 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011128#endif
11129#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011130 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011131#endif
11132#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011133 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011134#endif
11135#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011136 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011137#endif
11138#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011139 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011140#endif
11141#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011142 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011143#endif
11144#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011145 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011146#endif
11147#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011149#endif
11150#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011151 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011152#endif
11153#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011155#endif
11156#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011158#endif
11159#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011161#endif
11162#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011164#endif
11165#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011167#endif
11168#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011170#endif
11171#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011173#endif
11174#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011175 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011176#endif
11177#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011178 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011179#endif
11180#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011181 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011182#endif
11183#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011184 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011185#endif
11186#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011187 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011188#endif
11189#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011190 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011191#endif
11192#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011193 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011194#endif
11195#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011196 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011197#endif
11198#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011199 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011200#endif
11201#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011202 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011203#endif
11204#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011205 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011206#endif
11207#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011208 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011209#endif
11210#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011211 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011212#endif
11213#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011215#endif
11216#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011218#endif
11219#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011221#endif
11222#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011223 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011224#endif
11225#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011227#endif
11228#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011230#endif
11231#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011233#endif
11234};
11235
11236static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011237conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011238{
11239 return conv_confname(arg, valuep, posix_constants_sysconf,
11240 sizeof(posix_constants_sysconf)
11241 / sizeof(struct constdef));
11242}
11243
Larry Hastings2f936352014-08-05 14:04:04 +100011244
11245/*[clinic input]
11246os.sysconf -> long
11247 name: sysconf_confname
11248 /
11249
11250Return an integer-valued system configuration variable.
11251[clinic start generated code]*/
11252
Larry Hastings2f936352014-08-05 14:04:04 +100011253static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011254os_sysconf_impl(PyObject *module, int name)
11255/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011256{
11257 long value;
11258
11259 errno = 0;
11260 value = sysconf(name);
11261 if (value == -1 && errno != 0)
11262 posix_error();
11263 return value;
11264}
11265#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011266
11267
Fred Drakebec628d1999-12-15 18:31:10 +000011268/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011269 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011270 * the exported dictionaries that are used to publish information about the
11271 * names available on the host platform.
11272 *
11273 * Sorting the table at runtime ensures that the table is properly ordered
11274 * when used, even for platforms we're not able to test on. It also makes
11275 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011276 */
Fred Drakebec628d1999-12-15 18:31:10 +000011277
11278static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011279cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011280{
11281 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011282 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011283 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011284 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011285
11286 return strcmp(c1->name, c2->name);
11287}
11288
11289static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011290setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011291 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011292{
Fred Drakebec628d1999-12-15 18:31:10 +000011293 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011294 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011295
11296 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11297 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011298 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011299 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011300
Barry Warsaw3155db32000-04-13 15:20:40 +000011301 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011302 PyObject *o = PyLong_FromLong(table[i].value);
11303 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11304 Py_XDECREF(o);
11305 Py_DECREF(d);
11306 return -1;
11307 }
11308 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011309 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011310 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011311}
11312
Fred Drakebec628d1999-12-15 18:31:10 +000011313/* Return -1 on failure, 0 on success. */
11314static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011315setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011316{
11317#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011318 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011319 sizeof(posix_constants_pathconf)
11320 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011321 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011322 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011323#endif
11324#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011325 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011326 sizeof(posix_constants_confstr)
11327 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011328 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011329 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011330#endif
11331#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011332 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011333 sizeof(posix_constants_sysconf)
11334 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011335 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011336 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011337#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011338 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011339}
Fred Draked86ed291999-12-15 15:34:33 +000011340
11341
Larry Hastings2f936352014-08-05 14:04:04 +100011342/*[clinic input]
11343os.abort
11344
11345Abort the interpreter immediately.
11346
11347This function 'dumps core' or otherwise fails in the hardest way possible
11348on the hosting operating system. This function never returns.
11349[clinic start generated code]*/
11350
Larry Hastings2f936352014-08-05 14:04:04 +100011351static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011352os_abort_impl(PyObject *module)
11353/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011354{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011355 abort();
11356 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011357#ifndef __clang__
11358 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11359 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11360 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011361 Py_FatalError("abort() called from Python code didn't abort!");
11362 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011363#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011364}
Fred Drakebec628d1999-12-15 18:31:10 +000011365
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011366#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011367/* Grab ShellExecute dynamically from shell32 */
11368static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011369static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11370 LPCWSTR, INT);
11371static int
11372check_ShellExecute()
11373{
11374 HINSTANCE hShell32;
11375
11376 /* only recheck */
11377 if (-1 == has_ShellExecute) {
11378 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011379 /* Security note: this call is not vulnerable to "DLL hijacking".
11380 SHELL32 is part of "KnownDLLs" and so Windows always load
11381 the system SHELL32.DLL, even if there is another SHELL32.DLL
11382 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011383 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011384 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011385 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11386 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011387 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011388 } else {
11389 has_ShellExecute = 0;
11390 }
Tony Roberts4860f012019-02-02 18:16:42 +010011391 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011392 }
11393 return has_ShellExecute;
11394}
11395
11396
Steve Dowercc16be82016-09-08 10:35:16 -070011397/*[clinic input]
11398os.startfile
11399 filepath: path_t
11400 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011401
Steve Dowercc16be82016-09-08 10:35:16 -070011402startfile(filepath [, operation])
11403
11404Start a file with its associated application.
11405
11406When "operation" is not specified or "open", this acts like
11407double-clicking the file in Explorer, or giving the file name as an
11408argument to the DOS "start" command: the file is opened with whatever
11409application (if any) its extension is associated.
11410When another "operation" is given, it specifies what should be done with
11411the file. A typical operation is "print".
11412
11413startfile returns as soon as the associated application is launched.
11414There is no option to wait for the application to close, and no way
11415to retrieve the application's exit status.
11416
11417The filepath is relative to the current directory. If you want to use
11418an absolute path, make sure the first character is not a slash ("/");
11419the underlying Win32 ShellExecute function doesn't work if it is.
11420[clinic start generated code]*/
11421
11422static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011423os_startfile_impl(PyObject *module, path_t *filepath,
11424 const Py_UNICODE *operation)
11425/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011426{
11427 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011428
11429 if(!check_ShellExecute()) {
11430 /* If the OS doesn't have ShellExecute, return a
11431 NotImplementedError. */
11432 return PyErr_Format(PyExc_NotImplementedError,
11433 "startfile not available on this platform");
11434 }
11435
Victor Stinner8c62be82010-05-06 00:08:46 +000011436 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011437 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011438 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011439 Py_END_ALLOW_THREADS
11440
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011442 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011443 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 }
Steve Dowercc16be82016-09-08 10:35:16 -070011445 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011446}
Larry Hastings2f936352014-08-05 14:04:04 +100011447#endif /* MS_WINDOWS */
11448
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011449
Martin v. Löwis438b5342002-12-27 10:16:42 +000011450#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011451/*[clinic input]
11452os.getloadavg
11453
11454Return average recent system load information.
11455
11456Return the number of processes in the system run queue averaged over
11457the last 1, 5, and 15 minutes as a tuple of three floats.
11458Raises OSError if the load average was unobtainable.
11459[clinic start generated code]*/
11460
Larry Hastings2f936352014-08-05 14:04:04 +100011461static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011462os_getloadavg_impl(PyObject *module)
11463/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011464{
11465 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011466 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011467 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11468 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011469 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011470 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011471}
Larry Hastings2f936352014-08-05 14:04:04 +100011472#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011473
Larry Hastings2f936352014-08-05 14:04:04 +100011474
11475/*[clinic input]
11476os.device_encoding
11477 fd: int
11478
11479Return a string describing the encoding of a terminal's file descriptor.
11480
11481The file descriptor must be attached to a terminal.
11482If the device is not a terminal, return None.
11483[clinic start generated code]*/
11484
Larry Hastings2f936352014-08-05 14:04:04 +100011485static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011486os_device_encoding_impl(PyObject *module, int fd)
11487/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011488{
Brett Cannonefb00c02012-02-29 18:31:31 -050011489 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011490}
11491
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011492
Larry Hastings2f936352014-08-05 14:04:04 +100011493#ifdef HAVE_SETRESUID
11494/*[clinic input]
11495os.setresuid
11496
11497 ruid: uid_t
11498 euid: uid_t
11499 suid: uid_t
11500 /
11501
11502Set the current process's real, effective, and saved user ids.
11503[clinic start generated code]*/
11504
Larry Hastings2f936352014-08-05 14:04:04 +100011505static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011506os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11507/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011508{
Victor Stinner8c62be82010-05-06 00:08:46 +000011509 if (setresuid(ruid, euid, suid) < 0)
11510 return posix_error();
11511 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011512}
Larry Hastings2f936352014-08-05 14:04:04 +100011513#endif /* HAVE_SETRESUID */
11514
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011515
11516#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011517/*[clinic input]
11518os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011519
Larry Hastings2f936352014-08-05 14:04:04 +100011520 rgid: gid_t
11521 egid: gid_t
11522 sgid: gid_t
11523 /
11524
11525Set the current process's real, effective, and saved group ids.
11526[clinic start generated code]*/
11527
Larry Hastings2f936352014-08-05 14:04:04 +100011528static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011529os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11530/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011531{
Victor Stinner8c62be82010-05-06 00:08:46 +000011532 if (setresgid(rgid, egid, sgid) < 0)
11533 return posix_error();
11534 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011535}
Larry Hastings2f936352014-08-05 14:04:04 +100011536#endif /* HAVE_SETRESGID */
11537
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011538
11539#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011540/*[clinic input]
11541os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011542
Larry Hastings2f936352014-08-05 14:04:04 +100011543Return a tuple of the current process's real, effective, and saved user ids.
11544[clinic start generated code]*/
11545
Larry Hastings2f936352014-08-05 14:04:04 +100011546static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011547os_getresuid_impl(PyObject *module)
11548/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011549{
Victor Stinner8c62be82010-05-06 00:08:46 +000011550 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011551 if (getresuid(&ruid, &euid, &suid) < 0)
11552 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011553 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11554 _PyLong_FromUid(euid),
11555 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011556}
Larry Hastings2f936352014-08-05 14:04:04 +100011557#endif /* HAVE_GETRESUID */
11558
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011559
11560#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011561/*[clinic input]
11562os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011563
Larry Hastings2f936352014-08-05 14:04:04 +100011564Return a tuple of the current process's real, effective, and saved group ids.
11565[clinic start generated code]*/
11566
Larry Hastings2f936352014-08-05 14:04:04 +100011567static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011568os_getresgid_impl(PyObject *module)
11569/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011570{
11571 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011572 if (getresgid(&rgid, &egid, &sgid) < 0)
11573 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011574 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11575 _PyLong_FromGid(egid),
11576 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011577}
Larry Hastings2f936352014-08-05 14:04:04 +100011578#endif /* HAVE_GETRESGID */
11579
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011580
Benjamin Peterson9428d532011-09-14 11:45:52 -040011581#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011582/*[clinic input]
11583os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011584
Larry Hastings2f936352014-08-05 14:04:04 +100011585 path: path_t(allow_fd=True)
11586 attribute: path_t
11587 *
11588 follow_symlinks: bool = True
11589
11590Return the value of extended attribute attribute on path.
11591
BNMetricsb9427072018-11-02 15:20:19 +000011592path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011593If follow_symlinks is False, and the last element of the path is a symbolic
11594 link, getxattr will examine the symbolic link itself instead of the file
11595 the link points to.
11596
11597[clinic start generated code]*/
11598
Larry Hastings2f936352014-08-05 14:04:04 +100011599static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011600os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011601 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011602/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011603{
11604 Py_ssize_t i;
11605 PyObject *buffer = NULL;
11606
11607 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11608 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011609
Larry Hastings9cf065c2012-06-22 16:30:09 -070011610 for (i = 0; ; i++) {
11611 void *ptr;
11612 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011613 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011614 Py_ssize_t buffer_size = buffer_sizes[i];
11615 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011616 path_error(path);
11617 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011618 }
11619 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11620 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011621 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011622 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011623
Larry Hastings9cf065c2012-06-22 16:30:09 -070011624 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011625 if (path->fd >= 0)
11626 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011627 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011628 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011629 else
Larry Hastings2f936352014-08-05 14:04:04 +100011630 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011631 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011632
Larry Hastings9cf065c2012-06-22 16:30:09 -070011633 if (result < 0) {
11634 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011635 if (errno == ERANGE)
11636 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011637 path_error(path);
11638 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011639 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011640
Larry Hastings9cf065c2012-06-22 16:30:09 -070011641 if (result != buffer_size) {
11642 /* Can only shrink. */
11643 _PyBytes_Resize(&buffer, result);
11644 }
11645 break;
11646 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011647
Larry Hastings9cf065c2012-06-22 16:30:09 -070011648 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011649}
11650
Larry Hastings2f936352014-08-05 14:04:04 +100011651
11652/*[clinic input]
11653os.setxattr
11654
11655 path: path_t(allow_fd=True)
11656 attribute: path_t
11657 value: Py_buffer
11658 flags: int = 0
11659 *
11660 follow_symlinks: bool = True
11661
11662Set extended attribute attribute on path to value.
11663
BNMetricsb9427072018-11-02 15:20:19 +000011664path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011665If follow_symlinks is False, and the last element of the path is a symbolic
11666 link, setxattr will modify the symbolic link itself instead of the file
11667 the link points to.
11668
11669[clinic start generated code]*/
11670
Benjamin Peterson799bd802011-08-31 22:15:17 -040011671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011672os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011673 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011674/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011675{
Larry Hastings2f936352014-08-05 14:04:04 +100011676 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011677
Larry Hastings2f936352014-08-05 14:04:04 +100011678 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011679 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011680
Benjamin Peterson799bd802011-08-31 22:15:17 -040011681 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011682 if (path->fd > -1)
11683 result = fsetxattr(path->fd, attribute->narrow,
11684 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011685 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011686 result = setxattr(path->narrow, attribute->narrow,
11687 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011688 else
Larry Hastings2f936352014-08-05 14:04:04 +100011689 result = lsetxattr(path->narrow, attribute->narrow,
11690 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011691 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011692
Larry Hastings9cf065c2012-06-22 16:30:09 -070011693 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011694 path_error(path);
11695 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011696 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011697
Larry Hastings2f936352014-08-05 14:04:04 +100011698 Py_RETURN_NONE;
11699}
11700
11701
11702/*[clinic input]
11703os.removexattr
11704
11705 path: path_t(allow_fd=True)
11706 attribute: path_t
11707 *
11708 follow_symlinks: bool = True
11709
11710Remove extended attribute attribute on path.
11711
BNMetricsb9427072018-11-02 15:20:19 +000011712path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011713If follow_symlinks is False, and the last element of the path is a symbolic
11714 link, removexattr will modify the symbolic link itself instead of the file
11715 the link points to.
11716
11717[clinic start generated code]*/
11718
Larry Hastings2f936352014-08-05 14:04:04 +100011719static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011720os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011721 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011722/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011723{
11724 ssize_t result;
11725
11726 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11727 return NULL;
11728
11729 Py_BEGIN_ALLOW_THREADS;
11730 if (path->fd > -1)
11731 result = fremovexattr(path->fd, attribute->narrow);
11732 else if (follow_symlinks)
11733 result = removexattr(path->narrow, attribute->narrow);
11734 else
11735 result = lremovexattr(path->narrow, attribute->narrow);
11736 Py_END_ALLOW_THREADS;
11737
11738 if (result) {
11739 return path_error(path);
11740 }
11741
11742 Py_RETURN_NONE;
11743}
11744
11745
11746/*[clinic input]
11747os.listxattr
11748
11749 path: path_t(allow_fd=True, nullable=True) = None
11750 *
11751 follow_symlinks: bool = True
11752
11753Return a list of extended attributes on path.
11754
BNMetricsb9427072018-11-02 15:20:19 +000011755path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011756if path is None, listxattr will examine the current directory.
11757If follow_symlinks is False, and the last element of the path is a symbolic
11758 link, listxattr will examine the symbolic link itself instead of the file
11759 the link points to.
11760[clinic start generated code]*/
11761
Larry Hastings2f936352014-08-05 14:04:04 +100011762static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011763os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011764/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011765{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011766 Py_ssize_t i;
11767 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011768 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011769 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011770
Larry Hastings2f936352014-08-05 14:04:04 +100011771 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011772 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011773
Larry Hastings2f936352014-08-05 14:04:04 +100011774 name = path->narrow ? path->narrow : ".";
11775
Larry Hastings9cf065c2012-06-22 16:30:09 -070011776 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011777 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011778 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011779 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011780 Py_ssize_t buffer_size = buffer_sizes[i];
11781 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011782 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011783 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011784 break;
11785 }
11786 buffer = PyMem_MALLOC(buffer_size);
11787 if (!buffer) {
11788 PyErr_NoMemory();
11789 break;
11790 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011791
Larry Hastings9cf065c2012-06-22 16:30:09 -070011792 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011793 if (path->fd > -1)
11794 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011795 else if (follow_symlinks)
11796 length = listxattr(name, buffer, buffer_size);
11797 else
11798 length = llistxattr(name, buffer, buffer_size);
11799 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011800
Larry Hastings9cf065c2012-06-22 16:30:09 -070011801 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011802 if (errno == ERANGE) {
11803 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011804 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011805 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011806 }
Larry Hastings2f936352014-08-05 14:04:04 +100011807 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011808 break;
11809 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011810
Larry Hastings9cf065c2012-06-22 16:30:09 -070011811 result = PyList_New(0);
11812 if (!result) {
11813 goto exit;
11814 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011815
Larry Hastings9cf065c2012-06-22 16:30:09 -070011816 end = buffer + length;
11817 for (trace = start = buffer; trace != end; trace++) {
11818 if (!*trace) {
11819 int error;
11820 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11821 trace - start);
11822 if (!attribute) {
11823 Py_DECREF(result);
11824 result = NULL;
11825 goto exit;
11826 }
11827 error = PyList_Append(result, attribute);
11828 Py_DECREF(attribute);
11829 if (error) {
11830 Py_DECREF(result);
11831 result = NULL;
11832 goto exit;
11833 }
11834 start = trace + 1;
11835 }
11836 }
11837 break;
11838 }
11839exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011840 if (buffer)
11841 PyMem_FREE(buffer);
11842 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011843}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011844#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011845
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011846
Larry Hastings2f936352014-08-05 14:04:04 +100011847/*[clinic input]
11848os.urandom
11849
11850 size: Py_ssize_t
11851 /
11852
11853Return a bytes object containing random bytes suitable for cryptographic use.
11854[clinic start generated code]*/
11855
Larry Hastings2f936352014-08-05 14:04:04 +100011856static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011857os_urandom_impl(PyObject *module, Py_ssize_t size)
11858/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011859{
11860 PyObject *bytes;
11861 int result;
11862
Georg Brandl2fb477c2012-02-21 00:33:36 +010011863 if (size < 0)
11864 return PyErr_Format(PyExc_ValueError,
11865 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011866 bytes = PyBytes_FromStringAndSize(NULL, size);
11867 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011868 return NULL;
11869
Victor Stinnere66987e2016-09-06 16:33:52 -070011870 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011871 if (result == -1) {
11872 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011873 return NULL;
11874 }
Larry Hastings2f936352014-08-05 14:04:04 +100011875 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011876}
11877
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011878/* Terminal size querying */
11879
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011880static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011881
11882PyDoc_STRVAR(TerminalSize_docstring,
11883 "A tuple of (columns, lines) for holding terminal window size");
11884
11885static PyStructSequence_Field TerminalSize_fields[] = {
11886 {"columns", "width of the terminal window in characters"},
11887 {"lines", "height of the terminal window in characters"},
11888 {NULL, NULL}
11889};
11890
11891static PyStructSequence_Desc TerminalSize_desc = {
11892 "os.terminal_size",
11893 TerminalSize_docstring,
11894 TerminalSize_fields,
11895 2,
11896};
11897
11898#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011899/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011900PyDoc_STRVAR(termsize__doc__,
11901 "Return the size of the terminal window as (columns, lines).\n" \
11902 "\n" \
11903 "The optional argument fd (default standard output) specifies\n" \
11904 "which file descriptor should be queried.\n" \
11905 "\n" \
11906 "If the file descriptor is not connected to a terminal, an OSError\n" \
11907 "is thrown.\n" \
11908 "\n" \
11909 "This function will only be defined if an implementation is\n" \
11910 "available for this system.\n" \
11911 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080011912 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011913 "normally be used, os.get_terminal_size is the low-level implementation.");
11914
11915static PyObject*
11916get_terminal_size(PyObject *self, PyObject *args)
11917{
11918 int columns, lines;
11919 PyObject *termsize;
11920
11921 int fd = fileno(stdout);
11922 /* Under some conditions stdout may not be connected and
11923 * fileno(stdout) may point to an invalid file descriptor. For example
11924 * GUI apps don't have valid standard streams by default.
11925 *
11926 * If this happens, and the optional fd argument is not present,
11927 * the ioctl below will fail returning EBADF. This is what we want.
11928 */
11929
11930 if (!PyArg_ParseTuple(args, "|i", &fd))
11931 return NULL;
11932
11933#ifdef TERMSIZE_USE_IOCTL
11934 {
11935 struct winsize w;
11936 if (ioctl(fd, TIOCGWINSZ, &w))
11937 return PyErr_SetFromErrno(PyExc_OSError);
11938 columns = w.ws_col;
11939 lines = w.ws_row;
11940 }
11941#endif /* TERMSIZE_USE_IOCTL */
11942
11943#ifdef TERMSIZE_USE_CONIO
11944 {
11945 DWORD nhandle;
11946 HANDLE handle;
11947 CONSOLE_SCREEN_BUFFER_INFO csbi;
11948 switch (fd) {
11949 case 0: nhandle = STD_INPUT_HANDLE;
11950 break;
11951 case 1: nhandle = STD_OUTPUT_HANDLE;
11952 break;
11953 case 2: nhandle = STD_ERROR_HANDLE;
11954 break;
11955 default:
11956 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11957 }
11958 handle = GetStdHandle(nhandle);
11959 if (handle == NULL)
11960 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11961 if (handle == INVALID_HANDLE_VALUE)
11962 return PyErr_SetFromWindowsErr(0);
11963
11964 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11965 return PyErr_SetFromWindowsErr(0);
11966
11967 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11968 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11969 }
11970#endif /* TERMSIZE_USE_CONIO */
11971
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011972 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011973 if (termsize == NULL)
11974 return NULL;
11975 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11976 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11977 if (PyErr_Occurred()) {
11978 Py_DECREF(termsize);
11979 return NULL;
11980 }
11981 return termsize;
11982}
11983#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11984
Larry Hastings2f936352014-08-05 14:04:04 +100011985
11986/*[clinic input]
11987os.cpu_count
11988
Charles-François Natali80d62e62015-08-13 20:37:08 +010011989Return the number of CPUs in the system; return None if indeterminable.
11990
11991This number is not equivalent to the number of CPUs the current process can
11992use. The number of usable CPUs can be obtained with
11993``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011994[clinic start generated code]*/
11995
Larry Hastings2f936352014-08-05 14:04:04 +100011996static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011997os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011998/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011999{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012000 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012001#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012002 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
12003 Need to fallback to Vista behavior if this call isn't present */
12004 HINSTANCE hKernel32;
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012005 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
Tony Roberts4860f012019-02-02 18:16:42 +010012006 Py_BEGIN_ALLOW_THREADS
12007 hKernel32 = GetModuleHandleW(L"KERNEL32");
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012008 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
12009 "GetMaximumProcessorCount");
Tony Roberts4860f012019-02-02 18:16:42 +010012010 Py_END_ALLOW_THREADS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012011 if (_GetMaximumProcessorCount != NULL) {
12012 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
12013 }
12014 else {
12015 SYSTEM_INFO sysinfo;
12016 GetSystemInfo(&sysinfo);
12017 ncpu = sysinfo.dwNumberOfProcessors;
12018 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012019#elif defined(__hpux)
12020 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12021#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12022 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012023#elif defined(__DragonFly__) || \
12024 defined(__OpenBSD__) || \
12025 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012026 defined(__NetBSD__) || \
12027 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012028 int mib[2];
12029 size_t len = sizeof(ncpu);
12030 mib[0] = CTL_HW;
12031 mib[1] = HW_NCPU;
12032 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12033 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012034#endif
12035 if (ncpu >= 1)
12036 return PyLong_FromLong(ncpu);
12037 else
12038 Py_RETURN_NONE;
12039}
12040
Victor Stinnerdaf45552013-08-28 00:53:59 +020012041
Larry Hastings2f936352014-08-05 14:04:04 +100012042/*[clinic input]
12043os.get_inheritable -> bool
12044
12045 fd: int
12046 /
12047
12048Get the close-on-exe flag of the specified file descriptor.
12049[clinic start generated code]*/
12050
Larry Hastings2f936352014-08-05 14:04:04 +100012051static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012052os_get_inheritable_impl(PyObject *module, int fd)
12053/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012054{
Steve Dower8fc89802015-04-12 00:26:27 -040012055 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012056 _Py_BEGIN_SUPPRESS_IPH
12057 return_value = _Py_get_inheritable(fd);
12058 _Py_END_SUPPRESS_IPH
12059 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012060}
12061
12062
12063/*[clinic input]
12064os.set_inheritable
12065 fd: int
12066 inheritable: int
12067 /
12068
12069Set the inheritable flag of the specified file descriptor.
12070[clinic start generated code]*/
12071
Larry Hastings2f936352014-08-05 14:04:04 +100012072static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012073os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12074/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012075{
Steve Dower8fc89802015-04-12 00:26:27 -040012076 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012077
Steve Dower8fc89802015-04-12 00:26:27 -040012078 _Py_BEGIN_SUPPRESS_IPH
12079 result = _Py_set_inheritable(fd, inheritable, NULL);
12080 _Py_END_SUPPRESS_IPH
12081 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012082 return NULL;
12083 Py_RETURN_NONE;
12084}
12085
12086
12087#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012088/*[clinic input]
12089os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012090 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012091 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012092
Larry Hastings2f936352014-08-05 14:04:04 +100012093Get the close-on-exe flag of the specified file descriptor.
12094[clinic start generated code]*/
12095
Larry Hastings2f936352014-08-05 14:04:04 +100012096static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012097os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012098/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012099{
12100 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012101
12102 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12103 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012104 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012105 }
12106
Larry Hastings2f936352014-08-05 14:04:04 +100012107 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012108}
12109
Victor Stinnerdaf45552013-08-28 00:53:59 +020012110
Larry Hastings2f936352014-08-05 14:04:04 +100012111/*[clinic input]
12112os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012113 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012114 inheritable: bool
12115 /
12116
12117Set the inheritable flag of the specified handle.
12118[clinic start generated code]*/
12119
Larry Hastings2f936352014-08-05 14:04:04 +100012120static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012121os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012122 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012123/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012124{
12125 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012126 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12127 PyErr_SetFromWindowsErr(0);
12128 return NULL;
12129 }
12130 Py_RETURN_NONE;
12131}
Larry Hastings2f936352014-08-05 14:04:04 +100012132#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012133
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012134#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012135/*[clinic input]
12136os.get_blocking -> bool
12137 fd: int
12138 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012139
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012140Get the blocking mode of the file descriptor.
12141
12142Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12143[clinic start generated code]*/
12144
12145static int
12146os_get_blocking_impl(PyObject *module, int fd)
12147/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012148{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012149 int blocking;
12150
Steve Dower8fc89802015-04-12 00:26:27 -040012151 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012152 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012153 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012154 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012155}
12156
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012157/*[clinic input]
12158os.set_blocking
12159 fd: int
12160 blocking: bool(accept={int})
12161 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012162
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012163Set the blocking mode of the specified file descriptor.
12164
12165Set the O_NONBLOCK flag if blocking is False,
12166clear the O_NONBLOCK flag otherwise.
12167[clinic start generated code]*/
12168
12169static PyObject *
12170os_set_blocking_impl(PyObject *module, int fd, int blocking)
12171/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012172{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012173 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012174
Steve Dower8fc89802015-04-12 00:26:27 -040012175 _Py_BEGIN_SUPPRESS_IPH
12176 result = _Py_set_blocking(fd, blocking);
12177 _Py_END_SUPPRESS_IPH
12178 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012179 return NULL;
12180 Py_RETURN_NONE;
12181}
12182#endif /* !MS_WINDOWS */
12183
12184
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012185/*[clinic input]
12186class os.DirEntry "DirEntry *" "&DirEntryType"
12187[clinic start generated code]*/
12188/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012189
12190typedef struct {
12191 PyObject_HEAD
12192 PyObject *name;
12193 PyObject *path;
12194 PyObject *stat;
12195 PyObject *lstat;
12196#ifdef MS_WINDOWS
12197 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012198 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012199 int got_file_index;
12200#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012201#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012202 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012203#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012204 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012205 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012206#endif
12207} DirEntry;
12208
12209static void
12210DirEntry_dealloc(DirEntry *entry)
12211{
12212 Py_XDECREF(entry->name);
12213 Py_XDECREF(entry->path);
12214 Py_XDECREF(entry->stat);
12215 Py_XDECREF(entry->lstat);
12216 Py_TYPE(entry)->tp_free((PyObject *)entry);
12217}
12218
12219/* Forward reference */
12220static int
12221DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12222
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012223/*[clinic input]
12224os.DirEntry.is_symlink -> bool
12225
12226Return True if the entry is a symbolic link; cached per entry.
12227[clinic start generated code]*/
12228
Victor Stinner6036e442015-03-08 01:58:04 +010012229static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012230os_DirEntry_is_symlink_impl(DirEntry *self)
12231/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012232{
12233#ifdef MS_WINDOWS
12234 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012235#elif defined(HAVE_DIRENT_D_TYPE)
12236 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012237 if (self->d_type != DT_UNKNOWN)
12238 return self->d_type == DT_LNK;
12239 else
12240 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012241#else
12242 /* POSIX without d_type */
12243 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012244#endif
12245}
12246
12247static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012248DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12249{
12250 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012251 STRUCT_STAT st;
12252 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012253
12254#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012255 if (!PyUnicode_FSDecoder(self->path, &ub))
12256 return NULL;
12257 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012258#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012259 if (!PyUnicode_FSConverter(self->path, &ub))
12260 return NULL;
12261 const char *path = PyBytes_AS_STRING(ub);
12262 if (self->dir_fd != DEFAULT_DIR_FD) {
12263#ifdef HAVE_FSTATAT
12264 result = fstatat(self->dir_fd, path, &st,
12265 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12266#else
12267 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12268 return NULL;
12269#endif /* HAVE_FSTATAT */
12270 }
12271 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012272#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012273 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012274 if (follow_symlinks)
12275 result = STAT(path, &st);
12276 else
12277 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012278 }
12279 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012280
12281 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012282 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012283
12284 return _pystat_fromstructstat(&st);
12285}
12286
12287static PyObject *
12288DirEntry_get_lstat(DirEntry *self)
12289{
12290 if (!self->lstat) {
12291#ifdef MS_WINDOWS
12292 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12293#else /* POSIX */
12294 self->lstat = DirEntry_fetch_stat(self, 0);
12295#endif
12296 }
12297 Py_XINCREF(self->lstat);
12298 return self->lstat;
12299}
12300
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012301/*[clinic input]
12302os.DirEntry.stat
12303 *
12304 follow_symlinks: bool = True
12305
12306Return stat_result object for the entry; cached per entry.
12307[clinic start generated code]*/
12308
Victor Stinner6036e442015-03-08 01:58:04 +010012309static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012310os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12311/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012312{
12313 if (!follow_symlinks)
12314 return DirEntry_get_lstat(self);
12315
12316 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012317 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012318 if (result == -1)
12319 return NULL;
12320 else if (result)
12321 self->stat = DirEntry_fetch_stat(self, 1);
12322 else
12323 self->stat = DirEntry_get_lstat(self);
12324 }
12325
12326 Py_XINCREF(self->stat);
12327 return self->stat;
12328}
12329
Victor Stinner6036e442015-03-08 01:58:04 +010012330/* Set exception and return -1 on error, 0 for False, 1 for True */
12331static int
12332DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12333{
12334 PyObject *stat = NULL;
12335 PyObject *st_mode = NULL;
12336 long mode;
12337 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012338#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012339 int is_symlink;
12340 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012341#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012342#ifdef MS_WINDOWS
12343 unsigned long dir_bits;
12344#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012345 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012346
12347#ifdef MS_WINDOWS
12348 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12349 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012350#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012351 is_symlink = self->d_type == DT_LNK;
12352 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12353#endif
12354
Victor Stinner35a97c02015-03-08 02:59:09 +010012355#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012356 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012357#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012358 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012359 if (!stat) {
12360 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12361 /* If file doesn't exist (anymore), then return False
12362 (i.e., say it's not a file/directory) */
12363 PyErr_Clear();
12364 return 0;
12365 }
12366 goto error;
12367 }
12368 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12369 if (!st_mode)
12370 goto error;
12371
12372 mode = PyLong_AsLong(st_mode);
12373 if (mode == -1 && PyErr_Occurred())
12374 goto error;
12375 Py_CLEAR(st_mode);
12376 Py_CLEAR(stat);
12377 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012378#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012379 }
12380 else if (is_symlink) {
12381 assert(mode_bits != S_IFLNK);
12382 result = 0;
12383 }
12384 else {
12385 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12386#ifdef MS_WINDOWS
12387 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12388 if (mode_bits == S_IFDIR)
12389 result = dir_bits != 0;
12390 else
12391 result = dir_bits == 0;
12392#else /* POSIX */
12393 if (mode_bits == S_IFDIR)
12394 result = self->d_type == DT_DIR;
12395 else
12396 result = self->d_type == DT_REG;
12397#endif
12398 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012399#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012400
12401 return result;
12402
12403error:
12404 Py_XDECREF(st_mode);
12405 Py_XDECREF(stat);
12406 return -1;
12407}
12408
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012409/*[clinic input]
12410os.DirEntry.is_dir -> bool
12411 *
12412 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012413
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012414Return True if the entry is a directory; cached per entry.
12415[clinic start generated code]*/
12416
12417static int
12418os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12419/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12420{
12421 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012422}
12423
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012424/*[clinic input]
12425os.DirEntry.is_file -> bool
12426 *
12427 follow_symlinks: bool = True
12428
12429Return True if the entry is a file; cached per entry.
12430[clinic start generated code]*/
12431
12432static int
12433os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12434/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012435{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012436 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012437}
12438
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012439/*[clinic input]
12440os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012441
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012442Return inode of the entry; cached per entry.
12443[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012444
12445static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012446os_DirEntry_inode_impl(DirEntry *self)
12447/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012448{
12449#ifdef MS_WINDOWS
12450 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012451 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012452 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012453 STRUCT_STAT stat;
12454 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012455
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012456 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012457 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012458 path = PyUnicode_AsUnicode(unicode);
12459 result = LSTAT(path, &stat);
12460 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012461
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012462 if (result != 0)
12463 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012464
12465 self->win32_file_index = stat.st_ino;
12466 self->got_file_index = 1;
12467 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012468 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12469 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012470#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012471 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12472 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012473#endif
12474}
12475
12476static PyObject *
12477DirEntry_repr(DirEntry *self)
12478{
12479 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12480}
12481
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012482/*[clinic input]
12483os.DirEntry.__fspath__
12484
12485Returns the path for the entry.
12486[clinic start generated code]*/
12487
Brett Cannon96881cd2016-06-10 14:37:21 -070012488static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012489os_DirEntry___fspath___impl(DirEntry *self)
12490/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012491{
12492 Py_INCREF(self->path);
12493 return self->path;
12494}
12495
Victor Stinner6036e442015-03-08 01:58:04 +010012496static PyMemberDef DirEntry_members[] = {
12497 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12498 "the entry's base filename, relative to scandir() \"path\" argument"},
12499 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12500 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12501 {NULL}
12502};
12503
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012504#include "clinic/posixmodule.c.h"
12505
Victor Stinner6036e442015-03-08 01:58:04 +010012506static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012507 OS_DIRENTRY_IS_DIR_METHODDEF
12508 OS_DIRENTRY_IS_FILE_METHODDEF
12509 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12510 OS_DIRENTRY_STAT_METHODDEF
12511 OS_DIRENTRY_INODE_METHODDEF
12512 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012513 {NULL}
12514};
12515
Benjamin Peterson5646de42015-04-12 17:56:34 -040012516static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012517 PyVarObject_HEAD_INIT(NULL, 0)
12518 MODNAME ".DirEntry", /* tp_name */
12519 sizeof(DirEntry), /* tp_basicsize */
12520 0, /* tp_itemsize */
12521 /* methods */
12522 (destructor)DirEntry_dealloc, /* tp_dealloc */
12523 0, /* tp_print */
12524 0, /* tp_getattr */
12525 0, /* tp_setattr */
12526 0, /* tp_compare */
12527 (reprfunc)DirEntry_repr, /* tp_repr */
12528 0, /* tp_as_number */
12529 0, /* tp_as_sequence */
12530 0, /* tp_as_mapping */
12531 0, /* tp_hash */
12532 0, /* tp_call */
12533 0, /* tp_str */
12534 0, /* tp_getattro */
12535 0, /* tp_setattro */
12536 0, /* tp_as_buffer */
12537 Py_TPFLAGS_DEFAULT, /* tp_flags */
12538 0, /* tp_doc */
12539 0, /* tp_traverse */
12540 0, /* tp_clear */
12541 0, /* tp_richcompare */
12542 0, /* tp_weaklistoffset */
12543 0, /* tp_iter */
12544 0, /* tp_iternext */
12545 DirEntry_methods, /* tp_methods */
12546 DirEntry_members, /* tp_members */
12547};
12548
12549#ifdef MS_WINDOWS
12550
12551static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012552join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012553{
12554 Py_ssize_t path_len;
12555 Py_ssize_t size;
12556 wchar_t *result;
12557 wchar_t ch;
12558
12559 if (!path_wide) { /* Default arg: "." */
12560 path_wide = L".";
12561 path_len = 1;
12562 }
12563 else {
12564 path_len = wcslen(path_wide);
12565 }
12566
12567 /* The +1's are for the path separator and the NUL */
12568 size = path_len + 1 + wcslen(filename) + 1;
12569 result = PyMem_New(wchar_t, size);
12570 if (!result) {
12571 PyErr_NoMemory();
12572 return NULL;
12573 }
12574 wcscpy(result, path_wide);
12575 if (path_len > 0) {
12576 ch = result[path_len - 1];
12577 if (ch != SEP && ch != ALTSEP && ch != L':')
12578 result[path_len++] = SEP;
12579 wcscpy(result + path_len, filename);
12580 }
12581 return result;
12582}
12583
12584static PyObject *
12585DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12586{
12587 DirEntry *entry;
12588 BY_HANDLE_FILE_INFORMATION file_info;
12589 ULONG reparse_tag;
12590 wchar_t *joined_path;
12591
12592 entry = PyObject_New(DirEntry, &DirEntryType);
12593 if (!entry)
12594 return NULL;
12595 entry->name = NULL;
12596 entry->path = NULL;
12597 entry->stat = NULL;
12598 entry->lstat = NULL;
12599 entry->got_file_index = 0;
12600
12601 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12602 if (!entry->name)
12603 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012604 if (path->narrow) {
12605 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12606 if (!entry->name)
12607 goto error;
12608 }
Victor Stinner6036e442015-03-08 01:58:04 +010012609
12610 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12611 if (!joined_path)
12612 goto error;
12613
12614 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12615 PyMem_Free(joined_path);
12616 if (!entry->path)
12617 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012618 if (path->narrow) {
12619 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12620 if (!entry->path)
12621 goto error;
12622 }
Victor Stinner6036e442015-03-08 01:58:04 +010012623
Steve Dowercc16be82016-09-08 10:35:16 -070012624 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012625 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12626
12627 return (PyObject *)entry;
12628
12629error:
12630 Py_DECREF(entry);
12631 return NULL;
12632}
12633
12634#else /* POSIX */
12635
12636static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012637join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012638{
12639 Py_ssize_t path_len;
12640 Py_ssize_t size;
12641 char *result;
12642
12643 if (!path_narrow) { /* Default arg: "." */
12644 path_narrow = ".";
12645 path_len = 1;
12646 }
12647 else {
12648 path_len = strlen(path_narrow);
12649 }
12650
12651 if (filename_len == -1)
12652 filename_len = strlen(filename);
12653
12654 /* The +1's are for the path separator and the NUL */
12655 size = path_len + 1 + filename_len + 1;
12656 result = PyMem_New(char, size);
12657 if (!result) {
12658 PyErr_NoMemory();
12659 return NULL;
12660 }
12661 strcpy(result, path_narrow);
12662 if (path_len > 0 && result[path_len - 1] != '/')
12663 result[path_len++] = '/';
12664 strcpy(result + path_len, filename);
12665 return result;
12666}
12667
12668static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012669DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012670 ino_t d_ino
12671#ifdef HAVE_DIRENT_D_TYPE
12672 , unsigned char d_type
12673#endif
12674 )
Victor Stinner6036e442015-03-08 01:58:04 +010012675{
12676 DirEntry *entry;
12677 char *joined_path;
12678
12679 entry = PyObject_New(DirEntry, &DirEntryType);
12680 if (!entry)
12681 return NULL;
12682 entry->name = NULL;
12683 entry->path = NULL;
12684 entry->stat = NULL;
12685 entry->lstat = NULL;
12686
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012687 if (path->fd != -1) {
12688 entry->dir_fd = path->fd;
12689 joined_path = NULL;
12690 }
12691 else {
12692 entry->dir_fd = DEFAULT_DIR_FD;
12693 joined_path = join_path_filename(path->narrow, name, name_len);
12694 if (!joined_path)
12695 goto error;
12696 }
Victor Stinner6036e442015-03-08 01:58:04 +010012697
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012698 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012699 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012700 if (joined_path)
12701 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012702 }
12703 else {
12704 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012705 if (joined_path)
12706 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012707 }
12708 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012709 if (!entry->name)
12710 goto error;
12711
12712 if (path->fd != -1) {
12713 entry->path = entry->name;
12714 Py_INCREF(entry->path);
12715 }
12716 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012717 goto error;
12718
Victor Stinner35a97c02015-03-08 02:59:09 +010012719#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012720 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012721#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012722 entry->d_ino = d_ino;
12723
12724 return (PyObject *)entry;
12725
12726error:
12727 Py_XDECREF(entry);
12728 return NULL;
12729}
12730
12731#endif
12732
12733
12734typedef struct {
12735 PyObject_HEAD
12736 path_t path;
12737#ifdef MS_WINDOWS
12738 HANDLE handle;
12739 WIN32_FIND_DATAW file_data;
12740 int first_time;
12741#else /* POSIX */
12742 DIR *dirp;
12743#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012744#ifdef HAVE_FDOPENDIR
12745 int fd;
12746#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012747} ScandirIterator;
12748
12749#ifdef MS_WINDOWS
12750
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012751static int
12752ScandirIterator_is_closed(ScandirIterator *iterator)
12753{
12754 return iterator->handle == INVALID_HANDLE_VALUE;
12755}
12756
Victor Stinner6036e442015-03-08 01:58:04 +010012757static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012758ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012759{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012760 HANDLE handle = iterator->handle;
12761
12762 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012763 return;
12764
Victor Stinner6036e442015-03-08 01:58:04 +010012765 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012766 Py_BEGIN_ALLOW_THREADS
12767 FindClose(handle);
12768 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012769}
12770
12771static PyObject *
12772ScandirIterator_iternext(ScandirIterator *iterator)
12773{
12774 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12775 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012776 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012777
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012778 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012779 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012780 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012781
12782 while (1) {
12783 if (!iterator->first_time) {
12784 Py_BEGIN_ALLOW_THREADS
12785 success = FindNextFileW(iterator->handle, file_data);
12786 Py_END_ALLOW_THREADS
12787 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012788 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012789 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012790 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012791 break;
12792 }
12793 }
12794 iterator->first_time = 0;
12795
12796 /* Skip over . and .. */
12797 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012798 wcscmp(file_data->cFileName, L"..") != 0) {
12799 entry = DirEntry_from_find_data(&iterator->path, file_data);
12800 if (!entry)
12801 break;
12802 return entry;
12803 }
Victor Stinner6036e442015-03-08 01:58:04 +010012804
12805 /* Loop till we get a non-dot directory or finish iterating */
12806 }
12807
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012808 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012809 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012810 return NULL;
12811}
12812
12813#else /* POSIX */
12814
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012815static int
12816ScandirIterator_is_closed(ScandirIterator *iterator)
12817{
12818 return !iterator->dirp;
12819}
12820
Victor Stinner6036e442015-03-08 01:58:04 +010012821static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012822ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012823{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012824 DIR *dirp = iterator->dirp;
12825
12826 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012827 return;
12828
Victor Stinner6036e442015-03-08 01:58:04 +010012829 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012830 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012831#ifdef HAVE_FDOPENDIR
12832 if (iterator->path.fd != -1)
12833 rewinddir(dirp);
12834#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012835 closedir(dirp);
12836 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012837 return;
12838}
12839
12840static PyObject *
12841ScandirIterator_iternext(ScandirIterator *iterator)
12842{
12843 struct dirent *direntp;
12844 Py_ssize_t name_len;
12845 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012846 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012847
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012848 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012849 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012850 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012851
12852 while (1) {
12853 errno = 0;
12854 Py_BEGIN_ALLOW_THREADS
12855 direntp = readdir(iterator->dirp);
12856 Py_END_ALLOW_THREADS
12857
12858 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012859 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012860 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012861 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012862 break;
12863 }
12864
12865 /* Skip over . and .. */
12866 name_len = NAMLEN(direntp);
12867 is_dot = direntp->d_name[0] == '.' &&
12868 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12869 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012870 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012871 name_len, direntp->d_ino
12872#ifdef HAVE_DIRENT_D_TYPE
12873 , direntp->d_type
12874#endif
12875 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012876 if (!entry)
12877 break;
12878 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012879 }
12880
12881 /* Loop till we get a non-dot directory or finish iterating */
12882 }
12883
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012884 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012885 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012886 return NULL;
12887}
12888
12889#endif
12890
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012891static PyObject *
12892ScandirIterator_close(ScandirIterator *self, PyObject *args)
12893{
12894 ScandirIterator_closedir(self);
12895 Py_RETURN_NONE;
12896}
12897
12898static PyObject *
12899ScandirIterator_enter(PyObject *self, PyObject *args)
12900{
12901 Py_INCREF(self);
12902 return self;
12903}
12904
12905static PyObject *
12906ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12907{
12908 ScandirIterator_closedir(self);
12909 Py_RETURN_NONE;
12910}
12911
Victor Stinner6036e442015-03-08 01:58:04 +010012912static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012913ScandirIterator_finalize(ScandirIterator *iterator)
12914{
12915 PyObject *error_type, *error_value, *error_traceback;
12916
12917 /* Save the current exception, if any. */
12918 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12919
12920 if (!ScandirIterator_is_closed(iterator)) {
12921 ScandirIterator_closedir(iterator);
12922
12923 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12924 "unclosed scandir iterator %R", iterator)) {
12925 /* Spurious errors can appear at shutdown */
12926 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12927 PyErr_WriteUnraisable((PyObject *) iterator);
12928 }
12929 }
12930 }
12931
Victor Stinner7bfa4092016-03-23 00:43:54 +010012932 path_cleanup(&iterator->path);
12933
12934 /* Restore the saved exception. */
12935 PyErr_Restore(error_type, error_value, error_traceback);
12936}
12937
12938static void
Victor Stinner6036e442015-03-08 01:58:04 +010012939ScandirIterator_dealloc(ScandirIterator *iterator)
12940{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012941 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12942 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012943
Victor Stinner6036e442015-03-08 01:58:04 +010012944 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12945}
12946
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012947static PyMethodDef ScandirIterator_methods[] = {
12948 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12949 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12950 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12951 {NULL}
12952};
12953
Benjamin Peterson5646de42015-04-12 17:56:34 -040012954static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012955 PyVarObject_HEAD_INIT(NULL, 0)
12956 MODNAME ".ScandirIterator", /* tp_name */
12957 sizeof(ScandirIterator), /* tp_basicsize */
12958 0, /* tp_itemsize */
12959 /* methods */
12960 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12961 0, /* tp_print */
12962 0, /* tp_getattr */
12963 0, /* tp_setattr */
12964 0, /* tp_compare */
12965 0, /* tp_repr */
12966 0, /* tp_as_number */
12967 0, /* tp_as_sequence */
12968 0, /* tp_as_mapping */
12969 0, /* tp_hash */
12970 0, /* tp_call */
12971 0, /* tp_str */
12972 0, /* tp_getattro */
12973 0, /* tp_setattro */
12974 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012975 Py_TPFLAGS_DEFAULT
12976 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012977 0, /* tp_doc */
12978 0, /* tp_traverse */
12979 0, /* tp_clear */
12980 0, /* tp_richcompare */
12981 0, /* tp_weaklistoffset */
12982 PyObject_SelfIter, /* tp_iter */
12983 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012984 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012985 0, /* tp_members */
12986 0, /* tp_getset */
12987 0, /* tp_base */
12988 0, /* tp_dict */
12989 0, /* tp_descr_get */
12990 0, /* tp_descr_set */
12991 0, /* tp_dictoffset */
12992 0, /* tp_init */
12993 0, /* tp_alloc */
12994 0, /* tp_new */
12995 0, /* tp_free */
12996 0, /* tp_is_gc */
12997 0, /* tp_bases */
12998 0, /* tp_mro */
12999 0, /* tp_cache */
13000 0, /* tp_subclasses */
13001 0, /* tp_weaklist */
13002 0, /* tp_del */
13003 0, /* tp_version_tag */
13004 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010013005};
13006
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013007/*[clinic input]
13008os.scandir
13009
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013010 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013011
13012Return an iterator of DirEntry objects for given path.
13013
BNMetricsb9427072018-11-02 15:20:19 +000013014path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013015is bytes, the names of yielded DirEntry objects will also be bytes; in
13016all other circumstances they will be str.
13017
13018If path is None, uses the path='.'.
13019[clinic start generated code]*/
13020
Victor Stinner6036e442015-03-08 01:58:04 +010013021static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013022os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013023/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013024{
13025 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013026#ifdef MS_WINDOWS
13027 wchar_t *path_strW;
13028#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013029 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013030#ifdef HAVE_FDOPENDIR
13031 int fd = -1;
13032#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013033#endif
13034
13035 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
13036 if (!iterator)
13037 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013038
13039#ifdef MS_WINDOWS
13040 iterator->handle = INVALID_HANDLE_VALUE;
13041#else
13042 iterator->dirp = NULL;
13043#endif
13044
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013045 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013046 /* Move the ownership to iterator->path */
13047 path->object = NULL;
13048 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013049
13050#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013051 iterator->first_time = 1;
13052
13053 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13054 if (!path_strW)
13055 goto error;
13056
13057 Py_BEGIN_ALLOW_THREADS
13058 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13059 Py_END_ALLOW_THREADS
13060
13061 PyMem_Free(path_strW);
13062
13063 if (iterator->handle == INVALID_HANDLE_VALUE) {
13064 path_error(&iterator->path);
13065 goto error;
13066 }
13067#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013068 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013069#ifdef HAVE_FDOPENDIR
13070 if (path->fd != -1) {
13071 /* closedir() closes the FD, so we duplicate it */
13072 fd = _Py_dup(path->fd);
13073 if (fd == -1)
13074 goto error;
13075
13076 Py_BEGIN_ALLOW_THREADS
13077 iterator->dirp = fdopendir(fd);
13078 Py_END_ALLOW_THREADS
13079 }
13080 else
13081#endif
13082 {
13083 if (iterator->path.narrow)
13084 path_str = iterator->path.narrow;
13085 else
13086 path_str = ".";
13087
13088 Py_BEGIN_ALLOW_THREADS
13089 iterator->dirp = opendir(path_str);
13090 Py_END_ALLOW_THREADS
13091 }
Victor Stinner6036e442015-03-08 01:58:04 +010013092
13093 if (!iterator->dirp) {
13094 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013095#ifdef HAVE_FDOPENDIR
13096 if (fd != -1) {
13097 Py_BEGIN_ALLOW_THREADS
13098 close(fd);
13099 Py_END_ALLOW_THREADS
13100 }
13101#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013102 goto error;
13103 }
13104#endif
13105
13106 return (PyObject *)iterator;
13107
13108error:
13109 Py_DECREF(iterator);
13110 return NULL;
13111}
13112
Ethan Furman410ef8e2016-06-04 12:06:26 -070013113/*
13114 Return the file system path representation of the object.
13115
13116 If the object is str or bytes, then allow it to pass through with
13117 an incremented refcount. If the object defines __fspath__(), then
13118 return the result of that method. All other types raise a TypeError.
13119*/
13120PyObject *
13121PyOS_FSPath(PyObject *path)
13122{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013123 /* For error message reasons, this function is manually inlined in
13124 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013125 _Py_IDENTIFIER(__fspath__);
13126 PyObject *func = NULL;
13127 PyObject *path_repr = NULL;
13128
13129 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13130 Py_INCREF(path);
13131 return path;
13132 }
13133
13134 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13135 if (NULL == func) {
13136 return PyErr_Format(PyExc_TypeError,
13137 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013138 "not %.200s",
13139 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013140 }
13141
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013142 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013143 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013144 if (NULL == path_repr) {
13145 return NULL;
13146 }
13147
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013148 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13149 PyErr_Format(PyExc_TypeError,
13150 "expected %.200s.__fspath__() to return str or bytes, "
13151 "not %.200s", Py_TYPE(path)->tp_name,
13152 Py_TYPE(path_repr)->tp_name);
13153 Py_DECREF(path_repr);
13154 return NULL;
13155 }
13156
Ethan Furman410ef8e2016-06-04 12:06:26 -070013157 return path_repr;
13158}
13159
13160/*[clinic input]
13161os.fspath
13162
13163 path: object
13164
13165Return the file system path representation of the object.
13166
Brett Cannonb4f43e92016-06-09 14:32:08 -070013167If the object is str or bytes, then allow it to pass through as-is. If the
13168object defines __fspath__(), then return the result of that method. All other
13169types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013170[clinic start generated code]*/
13171
13172static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013173os_fspath_impl(PyObject *module, PyObject *path)
13174/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013175{
13176 return PyOS_FSPath(path);
13177}
Victor Stinner6036e442015-03-08 01:58:04 +010013178
Victor Stinner9b1f4742016-09-06 16:18:52 -070013179#ifdef HAVE_GETRANDOM_SYSCALL
13180/*[clinic input]
13181os.getrandom
13182
13183 size: Py_ssize_t
13184 flags: int=0
13185
13186Obtain a series of random bytes.
13187[clinic start generated code]*/
13188
13189static PyObject *
13190os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13191/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13192{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013193 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013194 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013195
13196 if (size < 0) {
13197 errno = EINVAL;
13198 return posix_error();
13199 }
13200
Victor Stinnerec2319c2016-09-20 23:00:59 +020013201 bytes = PyBytes_FromStringAndSize(NULL, size);
13202 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013203 PyErr_NoMemory();
13204 return NULL;
13205 }
13206
13207 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013208 n = syscall(SYS_getrandom,
13209 PyBytes_AS_STRING(bytes),
13210 PyBytes_GET_SIZE(bytes),
13211 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013212 if (n < 0 && errno == EINTR) {
13213 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013214 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013215 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013216
13217 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013218 continue;
13219 }
13220 break;
13221 }
13222
13223 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013224 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013225 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013226 }
13227
Victor Stinnerec2319c2016-09-20 23:00:59 +020013228 if (n != size) {
13229 _PyBytes_Resize(&bytes, n);
13230 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013231
13232 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013233
13234error:
13235 Py_DECREF(bytes);
13236 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013237}
13238#endif /* HAVE_GETRANDOM_SYSCALL */
13239
Steve Dower2438cdf2019-03-29 16:37:16 -070013240#ifdef MS_WINDOWS
13241/* bpo-36085: Helper functions for managing DLL search directories
13242 * on win32
13243 */
13244
13245typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13246typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13247
13248/*[clinic input]
13249os._add_dll_directory
13250
13251 path: path_t
13252
13253Add a path to the DLL search path.
13254
13255This search path is used when resolving dependencies for imported
13256extension modules (the module itself is resolved through sys.path),
13257and also by ctypes.
13258
13259Returns an opaque value that may be passed to os.remove_dll_directory
13260to remove this directory from the search path.
13261[clinic start generated code]*/
13262
13263static PyObject *
13264os__add_dll_directory_impl(PyObject *module, path_t *path)
13265/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13266{
13267 HMODULE hKernel32;
13268 PAddDllDirectory AddDllDirectory;
13269 DLL_DIRECTORY_COOKIE cookie = 0;
13270 DWORD err = 0;
13271
13272 /* For Windows 7, we have to load this. As this will be a fairly
13273 infrequent operation, just do it each time. Kernel32 is always
13274 loaded. */
13275 Py_BEGIN_ALLOW_THREADS
13276 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13277 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13278 hKernel32, "AddDllDirectory")) ||
13279 !(cookie = (*AddDllDirectory)(path->wide))) {
13280 err = GetLastError();
13281 }
13282 Py_END_ALLOW_THREADS
13283
13284 if (err) {
13285 return win32_error_object_err("add_dll_directory",
13286 path->object, err);
13287 }
13288
13289 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13290}
13291
13292/*[clinic input]
13293os._remove_dll_directory
13294
13295 cookie: object
13296
13297Removes a path from the DLL search path.
13298
13299The parameter is an opaque value that was returned from
13300os.add_dll_directory. You can only remove directories that you added
13301yourself.
13302[clinic start generated code]*/
13303
13304static PyObject *
13305os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13306/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13307{
13308 HMODULE hKernel32;
13309 PRemoveDllDirectory RemoveDllDirectory;
13310 DLL_DIRECTORY_COOKIE cookieValue;
13311 DWORD err = 0;
13312
13313 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13314 PyErr_SetString(PyExc_TypeError,
13315 "Provided cookie was not returned from os.add_dll_directory");
13316 return NULL;
13317 }
13318
13319 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13320 cookie, "DLL directory cookie");
13321
13322 /* For Windows 7, we have to load this. As this will be a fairly
13323 infrequent operation, just do it each time. Kernel32 is always
13324 loaded. */
13325 Py_BEGIN_ALLOW_THREADS
13326 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13327 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13328 hKernel32, "RemoveDllDirectory")) ||
13329 !(*RemoveDllDirectory)(cookieValue)) {
13330 err = GetLastError();
13331 }
13332 Py_END_ALLOW_THREADS
13333
13334 if (err) {
13335 return win32_error_object_err("remove_dll_directory",
13336 NULL, err);
13337 }
13338
13339 if (PyCapsule_SetName(cookie, NULL)) {
13340 return NULL;
13341 }
13342
13343 Py_RETURN_NONE;
13344}
13345
13346#endif
Larry Hastings31826802013-10-19 00:09:25 -070013347
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013348static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013349
13350 OS_STAT_METHODDEF
13351 OS_ACCESS_METHODDEF
13352 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013353 OS_CHDIR_METHODDEF
13354 OS_CHFLAGS_METHODDEF
13355 OS_CHMOD_METHODDEF
13356 OS_FCHMOD_METHODDEF
13357 OS_LCHMOD_METHODDEF
13358 OS_CHOWN_METHODDEF
13359 OS_FCHOWN_METHODDEF
13360 OS_LCHOWN_METHODDEF
13361 OS_LCHFLAGS_METHODDEF
13362 OS_CHROOT_METHODDEF
13363 OS_CTERMID_METHODDEF
13364 OS_GETCWD_METHODDEF
13365 OS_GETCWDB_METHODDEF
13366 OS_LINK_METHODDEF
13367 OS_LISTDIR_METHODDEF
13368 OS_LSTAT_METHODDEF
13369 OS_MKDIR_METHODDEF
13370 OS_NICE_METHODDEF
13371 OS_GETPRIORITY_METHODDEF
13372 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013373 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013374 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013375 OS_READLINK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013376 OS_RENAME_METHODDEF
13377 OS_REPLACE_METHODDEF
13378 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013379 OS_SYMLINK_METHODDEF
13380 OS_SYSTEM_METHODDEF
13381 OS_UMASK_METHODDEF
13382 OS_UNAME_METHODDEF
13383 OS_UNLINK_METHODDEF
13384 OS_REMOVE_METHODDEF
13385 OS_UTIME_METHODDEF
13386 OS_TIMES_METHODDEF
13387 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013388 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013389 OS_EXECV_METHODDEF
13390 OS_EXECVE_METHODDEF
13391 OS_SPAWNV_METHODDEF
13392 OS_SPAWNVE_METHODDEF
13393 OS_FORK1_METHODDEF
13394 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013395 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013396 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13397 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13398 OS_SCHED_GETPARAM_METHODDEF
13399 OS_SCHED_GETSCHEDULER_METHODDEF
13400 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13401 OS_SCHED_SETPARAM_METHODDEF
13402 OS_SCHED_SETSCHEDULER_METHODDEF
13403 OS_SCHED_YIELD_METHODDEF
13404 OS_SCHED_SETAFFINITY_METHODDEF
13405 OS_SCHED_GETAFFINITY_METHODDEF
13406 OS_OPENPTY_METHODDEF
13407 OS_FORKPTY_METHODDEF
13408 OS_GETEGID_METHODDEF
13409 OS_GETEUID_METHODDEF
13410 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013411#ifdef HAVE_GETGROUPLIST
13412 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13413#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013414 OS_GETGROUPS_METHODDEF
13415 OS_GETPID_METHODDEF
13416 OS_GETPGRP_METHODDEF
13417 OS_GETPPID_METHODDEF
13418 OS_GETUID_METHODDEF
13419 OS_GETLOGIN_METHODDEF
13420 OS_KILL_METHODDEF
13421 OS_KILLPG_METHODDEF
13422 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013423#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013424 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013425#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013426 OS_SETUID_METHODDEF
13427 OS_SETEUID_METHODDEF
13428 OS_SETREUID_METHODDEF
13429 OS_SETGID_METHODDEF
13430 OS_SETEGID_METHODDEF
13431 OS_SETREGID_METHODDEF
13432 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013433#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013434 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013435#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013436 OS_GETPGID_METHODDEF
13437 OS_SETPGRP_METHODDEF
13438 OS_WAIT_METHODDEF
13439 OS_WAIT3_METHODDEF
13440 OS_WAIT4_METHODDEF
13441 OS_WAITID_METHODDEF
13442 OS_WAITPID_METHODDEF
13443 OS_GETSID_METHODDEF
13444 OS_SETSID_METHODDEF
13445 OS_SETPGID_METHODDEF
13446 OS_TCGETPGRP_METHODDEF
13447 OS_TCSETPGRP_METHODDEF
13448 OS_OPEN_METHODDEF
13449 OS_CLOSE_METHODDEF
13450 OS_CLOSERANGE_METHODDEF
13451 OS_DEVICE_ENCODING_METHODDEF
13452 OS_DUP_METHODDEF
13453 OS_DUP2_METHODDEF
13454 OS_LOCKF_METHODDEF
13455 OS_LSEEK_METHODDEF
13456 OS_READ_METHODDEF
13457 OS_READV_METHODDEF
13458 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013459 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013460 OS_WRITE_METHODDEF
13461 OS_WRITEV_METHODDEF
13462 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013463 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013464#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013465 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013466 posix_sendfile__doc__},
13467#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013468 OS_FSTAT_METHODDEF
13469 OS_ISATTY_METHODDEF
13470 OS_PIPE_METHODDEF
13471 OS_PIPE2_METHODDEF
13472 OS_MKFIFO_METHODDEF
13473 OS_MKNOD_METHODDEF
13474 OS_MAJOR_METHODDEF
13475 OS_MINOR_METHODDEF
13476 OS_MAKEDEV_METHODDEF
13477 OS_FTRUNCATE_METHODDEF
13478 OS_TRUNCATE_METHODDEF
13479 OS_POSIX_FALLOCATE_METHODDEF
13480 OS_POSIX_FADVISE_METHODDEF
13481 OS_PUTENV_METHODDEF
13482 OS_UNSETENV_METHODDEF
13483 OS_STRERROR_METHODDEF
13484 OS_FCHDIR_METHODDEF
13485 OS_FSYNC_METHODDEF
13486 OS_SYNC_METHODDEF
13487 OS_FDATASYNC_METHODDEF
13488 OS_WCOREDUMP_METHODDEF
13489 OS_WIFCONTINUED_METHODDEF
13490 OS_WIFSTOPPED_METHODDEF
13491 OS_WIFSIGNALED_METHODDEF
13492 OS_WIFEXITED_METHODDEF
13493 OS_WEXITSTATUS_METHODDEF
13494 OS_WTERMSIG_METHODDEF
13495 OS_WSTOPSIG_METHODDEF
13496 OS_FSTATVFS_METHODDEF
13497 OS_STATVFS_METHODDEF
13498 OS_CONFSTR_METHODDEF
13499 OS_SYSCONF_METHODDEF
13500 OS_FPATHCONF_METHODDEF
13501 OS_PATHCONF_METHODDEF
13502 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013503 OS__GETFULLPATHNAME_METHODDEF
13504 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013505 OS__GETDISKUSAGE_METHODDEF
13506 OS__GETFINALPATHNAME_METHODDEF
13507 OS__GETVOLUMEPATHNAME_METHODDEF
13508 OS_GETLOADAVG_METHODDEF
13509 OS_URANDOM_METHODDEF
13510 OS_SETRESUID_METHODDEF
13511 OS_SETRESGID_METHODDEF
13512 OS_GETRESUID_METHODDEF
13513 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013514
Larry Hastings2f936352014-08-05 14:04:04 +100013515 OS_GETXATTR_METHODDEF
13516 OS_SETXATTR_METHODDEF
13517 OS_REMOVEXATTR_METHODDEF
13518 OS_LISTXATTR_METHODDEF
13519
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013520#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13521 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13522#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013523 OS_CPU_COUNT_METHODDEF
13524 OS_GET_INHERITABLE_METHODDEF
13525 OS_SET_INHERITABLE_METHODDEF
13526 OS_GET_HANDLE_INHERITABLE_METHODDEF
13527 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013528#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013529 OS_GET_BLOCKING_METHODDEF
13530 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013531#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013532 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013533 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013534 OS_GETRANDOM_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070013535#ifdef MS_WINDOWS
13536 OS__ADD_DLL_DIRECTORY_METHODDEF
13537 OS__REMOVE_DLL_DIRECTORY_METHODDEF
13538#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013539 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013540};
13541
Barry Warsaw4a342091996-12-19 23:50:02 +000013542static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013543all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013544{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013545#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013546 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013547#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013548#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013549 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013550#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013551#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013552 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013553#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013554#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013555 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013556#endif
Fred Drakec9680921999-12-13 16:37:25 +000013557#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013558 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013559#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013560#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013561 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013562#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013563#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013564 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013565#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013566#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013567 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013568#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013569#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013570 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013571#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013572#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013573 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013574#endif
13575#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013576 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013577#endif
13578#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013579 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013580#endif
13581#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013582 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013583#endif
13584#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013585 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013586#endif
13587#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013588 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013589#endif
13590#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013591 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013592#endif
13593#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013594 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013595#endif
13596#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013597 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013598#endif
13599#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013600 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013601#endif
13602#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013603 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013604#endif
13605#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013606 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013607#endif
13608#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013609 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013610#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013611#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013612 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013613#endif
13614#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013615 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013616#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013617#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013618 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013619#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013620#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013621 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013622#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013623#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013624#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013625 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013626#endif
13627#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013628 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013629#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013630#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013631#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013632 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013633#endif
13634#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013635 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013636#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013637#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013638 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013639#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013640#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013641 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013642#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013643#ifdef O_TMPFILE
13644 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13645#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013646#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013647 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013648#endif
13649#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013650 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013651#endif
13652#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013653 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013654#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013655#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013656 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013657#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013658#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013659 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013660#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013661
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013662
Jesus Cea94363612012-06-22 18:32:07 +020013663#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013664 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013665#endif
13666#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013667 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013668#endif
13669
Tim Peters5aa91602002-01-30 05:46:57 +000013670/* MS Windows */
13671#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013672 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013673 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013674#endif
13675#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013676 /* Optimize for short life (keep in memory). */
13677 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013678 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013679#endif
13680#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013681 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013682 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013683#endif
13684#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013685 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013686 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013687#endif
13688#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013689 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013690 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013691#endif
13692
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013693/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013694#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013695 /* Send a SIGIO signal whenever input or output
13696 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013697 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013698#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013699#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013700 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013701 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013702#endif
13703#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013704 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013705 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013706#endif
13707#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013708 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013709 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013710#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013711#ifdef O_NOLINKS
13712 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013713 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013714#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013715#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013716 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013717 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013718#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013719
Victor Stinner8c62be82010-05-06 00:08:46 +000013720 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013721#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013722 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013723#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013724#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013725 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013726#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013727#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013728 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013729#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013730#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013731 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013732#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013733#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013734 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013735#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013736#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013737 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013738#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013739#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013740 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013741#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013742#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013743 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013744#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013745#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013746 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013747#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013748#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013749 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013750#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013751#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013752 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013753#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013754#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013755 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013756#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013757#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013758 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013759#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013760#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013761 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013762#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013763#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013764 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013765#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013766#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013767 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013768#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013769#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013770 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013771#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013772
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013773 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013774#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013775 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013776#endif /* ST_RDONLY */
13777#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013778 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013779#endif /* ST_NOSUID */
13780
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013781 /* GNU extensions */
13782#ifdef ST_NODEV
13783 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13784#endif /* ST_NODEV */
13785#ifdef ST_NOEXEC
13786 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13787#endif /* ST_NOEXEC */
13788#ifdef ST_SYNCHRONOUS
13789 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13790#endif /* ST_SYNCHRONOUS */
13791#ifdef ST_MANDLOCK
13792 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13793#endif /* ST_MANDLOCK */
13794#ifdef ST_WRITE
13795 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13796#endif /* ST_WRITE */
13797#ifdef ST_APPEND
13798 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13799#endif /* ST_APPEND */
13800#ifdef ST_NOATIME
13801 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13802#endif /* ST_NOATIME */
13803#ifdef ST_NODIRATIME
13804 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13805#endif /* ST_NODIRATIME */
13806#ifdef ST_RELATIME
13807 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13808#endif /* ST_RELATIME */
13809
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013810 /* FreeBSD sendfile() constants */
13811#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013812 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013813#endif
13814#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013815 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013816#endif
13817#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013818 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013819#endif
13820
Ross Lagerwall7807c352011-03-17 20:20:30 +020013821 /* constants for posix_fadvise */
13822#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013823 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013824#endif
13825#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013826 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013827#endif
13828#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013829 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013830#endif
13831#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013832 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013833#endif
13834#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013835 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013836#endif
13837#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013838 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013839#endif
13840
13841 /* constants for waitid */
13842#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013843 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13844 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13845 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013846#endif
13847#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013848 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013849#endif
13850#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013851 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013852#endif
13853#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013854 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013855#endif
13856#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013857 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013858#endif
13859#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013860 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013861#endif
13862#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013863 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013864#endif
13865#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013866 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013867#endif
13868
13869 /* constants for lockf */
13870#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013871 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013872#endif
13873#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013874 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013875#endif
13876#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013877 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013878#endif
13879#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013880 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013881#endif
13882
Pablo Galindo4defba32018-01-27 16:16:37 +000013883#ifdef RWF_DSYNC
13884 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13885#endif
13886#ifdef RWF_HIPRI
13887 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13888#endif
13889#ifdef RWF_SYNC
13890 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13891#endif
13892#ifdef RWF_NOWAIT
13893 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13894#endif
13895
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013896/* constants for posix_spawn */
13897#ifdef HAVE_POSIX_SPAWN
13898 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
13899 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
13900 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
13901#endif
13902
pxinwrf2d7ac72019-05-21 18:46:37 +080013903#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013904 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13905 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013906 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080013907#endif
13908#ifdef HAVE_SPAWNV
13909 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013910 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013911#endif
13912
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013913#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013914#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013915 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013916#endif
13917#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013918 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013919#endif
13920#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013921 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013922#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013923#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013924 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013925#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013926#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013927 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013928#endif
13929#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013930 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013931#endif
13932#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013933 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013934#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013935#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013936 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013937#endif
13938#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013939 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013940#endif
13941#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013942 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013943#endif
13944#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013945 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013946#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013947#endif
13948
Benjamin Peterson9428d532011-09-14 11:45:52 -040013949#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013950 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13951 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13952 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013953#endif
13954
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013955#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013956 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013957#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013958#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013959 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013960#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013961#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013962 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013963#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013964#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013965 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013966#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013967#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013968 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013969#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013970#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013971 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013972#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013973#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013974 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013975#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013976#if HAVE_DECL_RTLD_MEMBER
13977 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13978#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013979
Victor Stinner9b1f4742016-09-06 16:18:52 -070013980#ifdef HAVE_GETRANDOM_SYSCALL
13981 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13982 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13983#endif
13984
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013985#if defined(__APPLE__)
13986 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
13987#endif
13988
Steve Dower2438cdf2019-03-29 16:37:16 -070013989#ifdef MS_WINDOWS
13990 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
13991 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
13992 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
13993 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
13994 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
13995#endif
13996
Victor Stinner8c62be82010-05-06 00:08:46 +000013997 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013998}
13999
14000
Martin v. Löwis1a214512008-06-11 05:26:20 +000014001static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000014002 PyModuleDef_HEAD_INIT,
14003 MODNAME,
14004 posix__doc__,
14005 -1,
14006 posix_methods,
14007 NULL,
14008 NULL,
14009 NULL,
14010 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000014011};
14012
14013
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014014static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014015
14016#ifdef HAVE_FACCESSAT
14017 "HAVE_FACCESSAT",
14018#endif
14019
14020#ifdef HAVE_FCHDIR
14021 "HAVE_FCHDIR",
14022#endif
14023
14024#ifdef HAVE_FCHMOD
14025 "HAVE_FCHMOD",
14026#endif
14027
14028#ifdef HAVE_FCHMODAT
14029 "HAVE_FCHMODAT",
14030#endif
14031
14032#ifdef HAVE_FCHOWN
14033 "HAVE_FCHOWN",
14034#endif
14035
Larry Hastings00964ed2013-08-12 13:49:30 -040014036#ifdef HAVE_FCHOWNAT
14037 "HAVE_FCHOWNAT",
14038#endif
14039
Larry Hastings9cf065c2012-06-22 16:30:09 -070014040#ifdef HAVE_FEXECVE
14041 "HAVE_FEXECVE",
14042#endif
14043
14044#ifdef HAVE_FDOPENDIR
14045 "HAVE_FDOPENDIR",
14046#endif
14047
Georg Brandl306336b2012-06-24 12:55:33 +020014048#ifdef HAVE_FPATHCONF
14049 "HAVE_FPATHCONF",
14050#endif
14051
Larry Hastings9cf065c2012-06-22 16:30:09 -070014052#ifdef HAVE_FSTATAT
14053 "HAVE_FSTATAT",
14054#endif
14055
14056#ifdef HAVE_FSTATVFS
14057 "HAVE_FSTATVFS",
14058#endif
14059
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014060#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014061 "HAVE_FTRUNCATE",
14062#endif
14063
Larry Hastings9cf065c2012-06-22 16:30:09 -070014064#ifdef HAVE_FUTIMENS
14065 "HAVE_FUTIMENS",
14066#endif
14067
14068#ifdef HAVE_FUTIMES
14069 "HAVE_FUTIMES",
14070#endif
14071
14072#ifdef HAVE_FUTIMESAT
14073 "HAVE_FUTIMESAT",
14074#endif
14075
14076#ifdef HAVE_LINKAT
14077 "HAVE_LINKAT",
14078#endif
14079
14080#ifdef HAVE_LCHFLAGS
14081 "HAVE_LCHFLAGS",
14082#endif
14083
14084#ifdef HAVE_LCHMOD
14085 "HAVE_LCHMOD",
14086#endif
14087
14088#ifdef HAVE_LCHOWN
14089 "HAVE_LCHOWN",
14090#endif
14091
14092#ifdef HAVE_LSTAT
14093 "HAVE_LSTAT",
14094#endif
14095
14096#ifdef HAVE_LUTIMES
14097 "HAVE_LUTIMES",
14098#endif
14099
14100#ifdef HAVE_MKDIRAT
14101 "HAVE_MKDIRAT",
14102#endif
14103
14104#ifdef HAVE_MKFIFOAT
14105 "HAVE_MKFIFOAT",
14106#endif
14107
14108#ifdef HAVE_MKNODAT
14109 "HAVE_MKNODAT",
14110#endif
14111
14112#ifdef HAVE_OPENAT
14113 "HAVE_OPENAT",
14114#endif
14115
14116#ifdef HAVE_READLINKAT
14117 "HAVE_READLINKAT",
14118#endif
14119
14120#ifdef HAVE_RENAMEAT
14121 "HAVE_RENAMEAT",
14122#endif
14123
14124#ifdef HAVE_SYMLINKAT
14125 "HAVE_SYMLINKAT",
14126#endif
14127
14128#ifdef HAVE_UNLINKAT
14129 "HAVE_UNLINKAT",
14130#endif
14131
14132#ifdef HAVE_UTIMENSAT
14133 "HAVE_UTIMENSAT",
14134#endif
14135
14136#ifdef MS_WINDOWS
14137 "MS_WINDOWS",
14138#endif
14139
14140 NULL
14141};
14142
14143
Mark Hammondfe51c6d2002-08-02 02:27:13 +000014144PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000014145INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014146{
Victor Stinner8c62be82010-05-06 00:08:46 +000014147 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014148 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014149 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000014150
Victor Stinner8c62be82010-05-06 00:08:46 +000014151 m = PyModule_Create(&posixmodule);
14152 if (m == NULL)
14153 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000014154
Victor Stinner8c62be82010-05-06 00:08:46 +000014155 /* Initialize environ dictionary */
14156 v = convertenviron();
14157 Py_XINCREF(v);
14158 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
14159 return NULL;
14160 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014161
Victor Stinner8c62be82010-05-06 00:08:46 +000014162 if (all_ins(m))
14163 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000014164
Victor Stinner8c62be82010-05-06 00:08:46 +000014165 if (setup_confname_tables(m))
14166 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000014167
Victor Stinner8c62be82010-05-06 00:08:46 +000014168 Py_INCREF(PyExc_OSError);
14169 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014170
Guido van Rossumb3d39562000-01-31 18:41:26 +000014171#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000014172 if (posix_putenv_garbage == NULL)
14173 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000014174#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000014175
Victor Stinner8c62be82010-05-06 00:08:46 +000014176 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020014177#if defined(HAVE_WAITID) && !defined(__APPLE__)
14178 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014179 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
14180 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014181 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014182 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014183#endif
14184
Christian Heimes25827622013-10-12 01:27:08 +020014185 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000014186 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14187 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14188 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014189 StatResultType = PyStructSequence_NewType(&stat_result_desc);
14190 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014191 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014192 }
14193 structseq_new = StatResultType->tp_new;
14194 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014195
Christian Heimes25827622013-10-12 01:27:08 +020014196 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014197 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
14198 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014199 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014200 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014201#ifdef NEED_TICKS_PER_SECOND
14202# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000014203 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014204# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000014205 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014206# else
Victor Stinner8c62be82010-05-06 00:08:46 +000014207 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014208# endif
14209#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014210
William Orr81574b82018-10-01 22:19:56 -070014211#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014212 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014213 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
14214 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014215 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014216 }
14217 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014218#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014219
14220 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014221 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
14222 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014223 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014224 }
Victor Stinner6036e442015-03-08 01:58:04 +010014225
14226 /* initialize scandir types */
14227 if (PyType_Ready(&ScandirIteratorType) < 0)
14228 return NULL;
14229 if (PyType_Ready(&DirEntryType) < 0)
14230 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014231 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014232#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014233 Py_INCREF((PyObject*) WaitidResultType);
14234 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020014235#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014236 Py_INCREF((PyObject*) StatResultType);
14237 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
14238 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000014239 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014240 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014241
14242#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014243 Py_INCREF(SchedParamType);
14244 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014245#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014246
Larry Hastings605a62d2012-06-24 04:33:36 -070014247 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014248 TimesResultType = PyStructSequence_NewType(&times_result_desc);
14249 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014250 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014251 }
14252 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014253
14254 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014255 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
14256 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014257 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014258 }
14259 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014260
Thomas Wouters477c8d52006-05-27 19:21:47 +000014261#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014262 /*
14263 * Step 2 of weak-linking support on Mac OS X.
14264 *
14265 * The code below removes functions that are not available on the
14266 * currently active platform.
14267 *
14268 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014269 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014270 * OSX 10.4.
14271 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014272#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014273 if (fstatvfs == NULL) {
14274 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14275 return NULL;
14276 }
14277 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014278#endif /* HAVE_FSTATVFS */
14279
14280#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014281 if (statvfs == NULL) {
14282 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14283 return NULL;
14284 }
14285 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014286#endif /* HAVE_STATVFS */
14287
14288# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014289 if (lchown == NULL) {
14290 if (PyObject_DelAttrString(m, "lchown") == -1) {
14291 return NULL;
14292 }
14293 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014294#endif /* HAVE_LCHOWN */
14295
14296
14297#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014298
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014299 Py_INCREF(TerminalSizeType);
14300 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014301
Larry Hastings6fe20b32012-04-19 15:07:49 -070014302 billion = PyLong_FromLong(1000000000);
14303 if (!billion)
14304 return NULL;
14305
Larry Hastings9cf065c2012-06-22 16:30:09 -070014306 /* suppress "function not used" warnings */
14307 {
14308 int ignored;
14309 fd_specified("", -1);
14310 follow_symlinks_specified("", 1);
14311 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14312 dir_fd_converter(Py_None, &ignored);
14313 dir_fd_unavailable(Py_None, &ignored);
14314 }
14315
14316 /*
14317 * provide list of locally available functions
14318 * so os.py can populate support_* lists
14319 */
14320 list = PyList_New(0);
14321 if (!list)
14322 return NULL;
14323 for (trace = have_functions; *trace; trace++) {
14324 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14325 if (!unicode)
14326 return NULL;
14327 if (PyList_Append(list, unicode))
14328 return NULL;
14329 Py_DECREF(unicode);
14330 }
14331 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014332
14333 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014334 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014335
14336 initialized = 1;
14337
Victor Stinner8c62be82010-05-06 00:08:46 +000014338 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014339}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014340
14341#ifdef __cplusplus
14342}
14343#endif