blob: c68bab81c7821049ffc47a425e8b5a35c568586c [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
Pablo Galindoaac4d032019-05-31 19:39:47 +0100120#ifdef HAVE_COPY_FILE_RANGE
121#include <unistd.h>
122#endif
123
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500124#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500125#undef HAVE_SCHED_SETAFFINITY
126#endif
127
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200128#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400129#define USE_XATTRS
130#endif
131
132#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400133#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400134#endif
135
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000136#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
137#ifdef HAVE_SYS_SOCKET_H
138#include <sys/socket.h>
139#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000140#endif
141
Victor Stinner8b905bd2011-10-25 13:34:04 +0200142#ifdef HAVE_DLFCN_H
143#include <dlfcn.h>
144#endif
145
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200146#ifdef __hpux
147#include <sys/mpctl.h>
148#endif
149
150#if defined(__DragonFly__) || \
151 defined(__OpenBSD__) || \
152 defined(__FreeBSD__) || \
153 defined(__NetBSD__) || \
154 defined(__APPLE__)
155#include <sys/sysctl.h>
156#endif
157
Victor Stinner9b1f4742016-09-06 16:18:52 -0700158#ifdef HAVE_LINUX_RANDOM_H
159# include <linux/random.h>
160#endif
161#ifdef HAVE_GETRANDOM_SYSCALL
162# include <sys/syscall.h>
163#endif
164
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100165#if defined(MS_WINDOWS)
166# define TERMSIZE_USE_CONIO
167#elif defined(HAVE_SYS_IOCTL_H)
168# include <sys/ioctl.h>
169# if defined(HAVE_TERMIOS_H)
170# include <termios.h>
171# endif
172# if defined(TIOCGWINSZ)
173# define TERMSIZE_USE_IOCTL
174# endif
175#endif /* MS_WINDOWS */
176
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000178/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000179#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000180#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000181#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182#include <process.h>
183#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000184#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000185#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000186#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000187#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700189#define HAVE_WSPAWNV 1
190#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000191#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000192#define HAVE_SYSTEM 1
193#define HAVE_CWAIT 1
194#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000195#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000196#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000197/* Unix functions that the configure script doesn't check for */
pxinwrf2d7ac72019-05-21 18:46:37 +0800198#ifndef __VXWORKS__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000199#define HAVE_EXECV 1
200#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000201#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000202#define HAVE_FORK1 1
203#endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800204#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000205#define HAVE_GETEGID 1
206#define HAVE_GETEUID 1
207#define HAVE_GETGID 1
208#define HAVE_GETPPID 1
209#define HAVE_GETUID 1
210#define HAVE_KILL 1
211#define HAVE_OPENDIR 1
212#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000213#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000214#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000215#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000217#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000218
Victor Stinnera2f7c002012-02-08 03:36:25 +0100219
Larry Hastings61272b72014-01-07 12:41:53 -0800220/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000221# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800222module os
Larry Hastings61272b72014-01-07 12:41:53 -0800223[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000224/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100225
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000226#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000227
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000228#if defined(__sgi)&&_COMPILER_VERSION>=700
229/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
230 (default) */
231extern char *ctermid_r(char *);
232#endif
233
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235
pxinwrf2d7ac72019-05-21 18:46:37 +0800236#if defined(__VXWORKS__)
237#include <vxCpuLib.h>
238#include <rtpLib.h>
239#include <wait.h>
240#include <taskLib.h>
241#ifndef _P_WAIT
242#define _P_WAIT 0
243#define _P_NOWAIT 1
244#define _P_NOWAITO 1
245#endif
246#endif /* __VXWORKS__ */
247
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000248#ifdef HAVE_POSIX_SPAWN
249#include <spawn.h>
250#endif
251
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#ifdef HAVE_UTIME_H
253#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000254#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000256#ifdef HAVE_SYS_UTIME_H
257#include <sys/utime.h>
258#define HAVE_UTIME_H /* pretend we do for the rest of this file */
259#endif /* HAVE_SYS_UTIME_H */
260
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261#ifdef HAVE_SYS_TIMES_H
262#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000263#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264
265#ifdef HAVE_SYS_PARAM_H
266#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000267#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268
269#ifdef HAVE_SYS_UTSNAME_H
270#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000271#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000273#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000275#define NAMLEN(dirent) strlen((dirent)->d_name)
276#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000277#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000278#include <direct.h>
279#define NAMLEN(dirent) strlen((dirent)->d_name)
280#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000283#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000284#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000286#endif
287#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000288#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000289#endif
290#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000292#endif
293#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000294
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000295#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000296#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000297#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000298#endif
299#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000300#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000301#endif
302#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000303#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000304#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000305#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000306#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000307#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100308#ifndef IO_REPARSE_TAG_MOUNT_POINT
309#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
310#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000311#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000312#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000313#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000314#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000315#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000316#define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000317#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318
Tim Petersbc2e10e2002-03-03 23:17:02 +0000319#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320#if defined(PATH_MAX) && PATH_MAX > 1024
321#define MAXPATHLEN PATH_MAX
322#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000323#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000325#endif /* MAXPATHLEN */
326
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000327#ifdef UNION_WAIT
328/* Emulate some macros on systems that have a union instead of macros */
329
330#ifndef WIFEXITED
331#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
332#endif
333
334#ifndef WEXITSTATUS
335#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
336#endif
337
338#ifndef WTERMSIG
339#define WTERMSIG(u_wait) ((u_wait).w_termsig)
340#endif
341
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000342#define WAIT_TYPE union wait
343#define WAIT_STATUS_INT(s) (s.w_status)
344
345#else /* !UNION_WAIT */
346#define WAIT_TYPE int
347#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000348#endif /* UNION_WAIT */
349
Greg Wardb48bc172000-03-01 21:51:56 +0000350/* Don't use the "_r" form if we don't need it (also, won't have a
351 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200352#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000353#define USE_CTERMID_R
354#endif
355
Fred Drake699f3522000-06-29 21:12:41 +0000356/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000357#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000358#undef FSTAT
359#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200360#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000361# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700362# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200363# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800364# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000365#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000366# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700367# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000368# define FSTAT fstat
369# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000370#endif
371
Tim Peters11b23062003-04-23 02:39:17 +0000372#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000373#include <sys/mkdev.h>
374#else
375#if defined(MAJOR_IN_SYSMACROS)
376#include <sys/sysmacros.h>
377#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000378#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
379#include <sys/mkdev.h>
380#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000381#endif
Fred Drake699f3522000-06-29 21:12:41 +0000382
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200383#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100384#define INITFUNC PyInit_nt
385#define MODNAME "nt"
386#else
387#define INITFUNC PyInit_posix
388#define MODNAME "posix"
389#endif
390
jcea6c51d512018-01-28 14:00:08 +0100391#if defined(__sun)
392/* Something to implement in autoconf, not present in autoconf 2.69 */
393#define HAVE_STRUCT_STAT_ST_FSTYPE 1
394#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200395
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600396/* memfd_create is either defined in sys/mman.h or sys/memfd.h
397 * linux/memfd.h defines additional flags
398 */
399#ifdef HAVE_SYS_MMAN_H
400#include <sys/mman.h>
401#endif
402#ifdef HAVE_SYS_MEMFD_H
403#include <sys/memfd.h>
404#endif
405#ifdef HAVE_LINUX_MEMFD_H
406#include <linux/memfd.h>
407#endif
408
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800409#ifdef _Py_MEMORY_SANITIZER
410# include <sanitizer/msan_interface.h>
411#endif
412
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200413#ifdef HAVE_FORK
414static void
415run_at_forkers(PyObject *lst, int reverse)
416{
417 Py_ssize_t i;
418 PyObject *cpy;
419
420 if (lst != NULL) {
421 assert(PyList_CheckExact(lst));
422
423 /* Use a list copy in case register_at_fork() is called from
424 * one of the callbacks.
425 */
426 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
427 if (cpy == NULL)
428 PyErr_WriteUnraisable(lst);
429 else {
430 if (reverse)
431 PyList_Reverse(cpy);
432 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
433 PyObject *func, *res;
434 func = PyList_GET_ITEM(cpy, i);
435 res = PyObject_CallObject(func, NULL);
436 if (res == NULL)
437 PyErr_WriteUnraisable(func);
438 else
439 Py_DECREF(res);
440 }
441 Py_DECREF(cpy);
442 }
443 }
444}
445
446void
447PyOS_BeforeFork(void)
448{
Victor Stinnercaba55b2018-08-03 15:33:52 +0200449 run_at_forkers(_PyInterpreterState_Get()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200450
451 _PyImport_AcquireLock();
452}
453
454void
455PyOS_AfterFork_Parent(void)
456{
457 if (_PyImport_ReleaseLock() <= 0)
458 Py_FatalError("failed releasing import lock after fork");
459
Victor Stinnercaba55b2018-08-03 15:33:52 +0200460 run_at_forkers(_PyInterpreterState_Get()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200461}
462
463void
464PyOS_AfterFork_Child(void)
465{
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200466 _PyRuntimeState *runtime = &_PyRuntime;
467 _PyGILState_Reinit(runtime);
Victor Stinnerd5d9e812019-05-13 12:35:37 +0200468 _PyEval_ReInitThreads(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200469 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200470 _PySignal_AfterFork();
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200471 _PyRuntimeState_ReInitThreads(runtime);
Victor Stinnerb49858b2019-05-24 15:20:23 +0200472 _PyInterpreterState_DeleteExceptMain(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200473
Victor Stinnercaba55b2018-08-03 15:33:52 +0200474 run_at_forkers(_PyInterpreterState_Get()->after_forkers_child, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200475}
476
477static int
478register_at_forker(PyObject **lst, PyObject *func)
479{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700480 if (func == NULL) /* nothing to register? do nothing. */
481 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200482 if (*lst == NULL) {
483 *lst = PyList_New(0);
484 if (*lst == NULL)
485 return -1;
486 }
487 return PyList_Append(*lst, func);
488}
489#endif
490
491/* Legacy wrapper */
492void
493PyOS_AfterFork(void)
494{
495#ifdef HAVE_FORK
496 PyOS_AfterFork_Child();
497#endif
498}
499
500
Victor Stinner6036e442015-03-08 01:58:04 +0100501#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200502/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700503void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
504void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200505 ULONG, struct _Py_stat_struct *);
506#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700507
508#ifdef MS_WINDOWS
509static int
510win32_warn_bytes_api()
511{
512 return PyErr_WarnEx(PyExc_DeprecationWarning,
513 "The Windows bytes API has been deprecated, "
514 "use Unicode filenames instead",
515 1);
516}
517#endif
518
519
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200520#ifndef MS_WINDOWS
521PyObject *
522_PyLong_FromUid(uid_t uid)
523{
524 if (uid == (uid_t)-1)
525 return PyLong_FromLong(-1);
526 return PyLong_FromUnsignedLong(uid);
527}
528
529PyObject *
530_PyLong_FromGid(gid_t gid)
531{
532 if (gid == (gid_t)-1)
533 return PyLong_FromLong(-1);
534 return PyLong_FromUnsignedLong(gid);
535}
536
537int
538_Py_Uid_Converter(PyObject *obj, void *p)
539{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700540 uid_t uid;
541 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200542 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200543 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700544 unsigned long uresult;
545
546 index = PyNumber_Index(obj);
547 if (index == NULL) {
548 PyErr_Format(PyExc_TypeError,
549 "uid should be integer, not %.200s",
550 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200551 return 0;
552 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700553
554 /*
555 * Handling uid_t is complicated for two reasons:
556 * * Although uid_t is (always?) unsigned, it still
557 * accepts -1.
558 * * We don't know its size in advance--it may be
559 * bigger than an int, or it may be smaller than
560 * a long.
561 *
562 * So a bit of defensive programming is in order.
563 * Start with interpreting the value passed
564 * in as a signed long and see if it works.
565 */
566
567 result = PyLong_AsLongAndOverflow(index, &overflow);
568
569 if (!overflow) {
570 uid = (uid_t)result;
571
572 if (result == -1) {
573 if (PyErr_Occurred())
574 goto fail;
575 /* It's a legitimate -1, we're done. */
576 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200577 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700578
579 /* Any other negative number is disallowed. */
580 if (result < 0)
581 goto underflow;
582
583 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200584 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700585 (long)uid != result)
586 goto underflow;
587 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200588 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700589
590 if (overflow < 0)
591 goto underflow;
592
593 /*
594 * Okay, the value overflowed a signed long. If it
595 * fits in an *unsigned* long, it may still be okay,
596 * as uid_t may be unsigned long on this platform.
597 */
598 uresult = PyLong_AsUnsignedLong(index);
599 if (PyErr_Occurred()) {
600 if (PyErr_ExceptionMatches(PyExc_OverflowError))
601 goto overflow;
602 goto fail;
603 }
604
605 uid = (uid_t)uresult;
606
607 /*
608 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
609 * but this value would get interpreted as (uid_t)-1 by chown
610 * and its siblings. That's not what the user meant! So we
611 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100612 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700613 */
614 if (uid == (uid_t)-1)
615 goto overflow;
616
617 /* Ensure the value wasn't truncated. */
618 if (sizeof(uid_t) < sizeof(long) &&
619 (unsigned long)uid != uresult)
620 goto overflow;
621 /* fallthrough */
622
623success:
624 Py_DECREF(index);
625 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200626 return 1;
627
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700628underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200629 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700630 "uid is less than minimum");
631 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200632
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700633overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200634 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700635 "uid is greater than maximum");
636 /* fallthrough */
637
638fail:
639 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200640 return 0;
641}
642
643int
644_Py_Gid_Converter(PyObject *obj, void *p)
645{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700646 gid_t gid;
647 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200648 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200649 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700650 unsigned long uresult;
651
652 index = PyNumber_Index(obj);
653 if (index == NULL) {
654 PyErr_Format(PyExc_TypeError,
655 "gid should be integer, not %.200s",
656 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200657 return 0;
658 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700659
660 /*
661 * Handling gid_t is complicated for two reasons:
662 * * Although gid_t is (always?) unsigned, it still
663 * accepts -1.
664 * * We don't know its size in advance--it may be
665 * bigger than an int, or it may be smaller than
666 * a long.
667 *
668 * So a bit of defensive programming is in order.
669 * Start with interpreting the value passed
670 * in as a signed long and see if it works.
671 */
672
673 result = PyLong_AsLongAndOverflow(index, &overflow);
674
675 if (!overflow) {
676 gid = (gid_t)result;
677
678 if (result == -1) {
679 if (PyErr_Occurred())
680 goto fail;
681 /* It's a legitimate -1, we're done. */
682 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200683 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684
685 /* Any other negative number is disallowed. */
686 if (result < 0) {
687 goto underflow;
688 }
689
690 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200691 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700692 (long)gid != result)
693 goto underflow;
694 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200695 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700696
697 if (overflow < 0)
698 goto underflow;
699
700 /*
701 * Okay, the value overflowed a signed long. If it
702 * fits in an *unsigned* long, it may still be okay,
703 * as gid_t may be unsigned long on this platform.
704 */
705 uresult = PyLong_AsUnsignedLong(index);
706 if (PyErr_Occurred()) {
707 if (PyErr_ExceptionMatches(PyExc_OverflowError))
708 goto overflow;
709 goto fail;
710 }
711
712 gid = (gid_t)uresult;
713
714 /*
715 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
716 * but this value would get interpreted as (gid_t)-1 by chown
717 * and its siblings. That's not what the user meant! So we
718 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100719 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700720 */
721 if (gid == (gid_t)-1)
722 goto overflow;
723
724 /* Ensure the value wasn't truncated. */
725 if (sizeof(gid_t) < sizeof(long) &&
726 (unsigned long)gid != uresult)
727 goto overflow;
728 /* fallthrough */
729
730success:
731 Py_DECREF(index);
732 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200733 return 1;
734
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700735underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200736 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700737 "gid is less than minimum");
738 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200739
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700740overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200741 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700742 "gid is greater than maximum");
743 /* fallthrough */
744
745fail:
746 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200747 return 0;
748}
749#endif /* MS_WINDOWS */
750
751
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700752#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800753
754
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200755#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
756static int
757_Py_Dev_Converter(PyObject *obj, void *p)
758{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200759 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200760 if (PyErr_Occurred())
761 return 0;
762 return 1;
763}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800764#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200765
766
Larry Hastings9cf065c2012-06-22 16:30:09 -0700767#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400768/*
769 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
770 * without the int cast, the value gets interpreted as uint (4291925331),
771 * which doesn't play nicely with all the initializer lines in this file that
772 * look like this:
773 * int dir_fd = DEFAULT_DIR_FD;
774 */
775#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700776#else
777#define DEFAULT_DIR_FD (-100)
778#endif
779
780static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300781_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200782{
783 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700784 long long_value;
785
786 PyObject *index = PyNumber_Index(o);
787 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700788 return 0;
789 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700790
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300791 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700792 long_value = PyLong_AsLongAndOverflow(index, &overflow);
793 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300794 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200795 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700796 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700797 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700798 return 0;
799 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200800 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700801 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700802 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700803 return 0;
804 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700805
Larry Hastings9cf065c2012-06-22 16:30:09 -0700806 *p = (int)long_value;
807 return 1;
808}
809
810static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200811dir_fd_converter(PyObject *o, void *p)
812{
813 if (o == Py_None) {
814 *(int *)p = DEFAULT_DIR_FD;
815 return 1;
816 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300817 else if (PyIndex_Check(o)) {
818 return _fd_converter(o, (int *)p);
819 }
820 else {
821 PyErr_Format(PyExc_TypeError,
822 "argument should be integer or None, not %.200s",
823 Py_TYPE(o)->tp_name);
824 return 0;
825 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700826}
827
828
Larry Hastings9cf065c2012-06-22 16:30:09 -0700829/*
830 * A PyArg_ParseTuple "converter" function
831 * that handles filesystem paths in the manner
832 * preferred by the os module.
833 *
834 * path_converter accepts (Unicode) strings and their
835 * subclasses, and bytes and their subclasses. What
836 * it does with the argument depends on the platform:
837 *
838 * * On Windows, if we get a (Unicode) string we
839 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700840 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700841 *
842 * * On all other platforms, strings are encoded
843 * to bytes using PyUnicode_FSConverter, then we
844 * extract the char * from the bytes object and
845 * return that.
846 *
847 * path_converter also optionally accepts signed
848 * integers (representing open file descriptors) instead
849 * of path strings.
850 *
851 * Input fields:
852 * path.nullable
853 * If nonzero, the path is permitted to be None.
854 * path.allow_fd
855 * If nonzero, the path is permitted to be a file handle
856 * (a signed int) instead of a string.
857 * path.function_name
858 * If non-NULL, path_converter will use that as the name
859 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700860 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700861 * path.argument_name
862 * If non-NULL, path_converter will use that as the name
863 * of the parameter in error messages.
864 * (If path.argument_name is NULL it uses "path".)
865 *
866 * Output fields:
867 * path.wide
868 * Points to the path if it was expressed as Unicode
869 * and was not encoded. (Only used on Windows.)
870 * path.narrow
871 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700872 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000873 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700874 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700875 * path.fd
876 * Contains a file descriptor if path.accept_fd was true
877 * and the caller provided a signed integer instead of any
878 * sort of string.
879 *
880 * WARNING: if your "path" parameter is optional, and is
881 * unspecified, path_converter will never get called.
882 * So if you set allow_fd, you *MUST* initialize path.fd = -1
883 * yourself!
884 * path.length
885 * The length of the path in characters, if specified as
886 * a string.
887 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800888 * The original object passed in (if get a PathLike object,
889 * the result of PyOS_FSPath() is treated as the original object).
890 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700891 * path.cleanup
892 * For internal use only. May point to a temporary object.
893 * (Pay no attention to the man behind the curtain.)
894 *
895 * At most one of path.wide or path.narrow will be non-NULL.
896 * If path was None and path.nullable was set,
897 * or if path was an integer and path.allow_fd was set,
898 * both path.wide and path.narrow will be NULL
899 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200900 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700901 * path_converter takes care to not write to the path_t
902 * unless it's successful. However it must reset the
903 * "cleanup" field each time it's called.
904 *
905 * Use as follows:
906 * path_t path;
907 * memset(&path, 0, sizeof(path));
908 * PyArg_ParseTuple(args, "O&", path_converter, &path);
909 * // ... use values from path ...
910 * path_cleanup(&path);
911 *
912 * (Note that if PyArg_Parse fails you don't need to call
913 * path_cleanup(). However it is safe to do so.)
914 */
915typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100916 const char *function_name;
917 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700918 int nullable;
919 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300920 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700921#ifdef MS_WINDOWS
922 BOOL narrow;
923#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300924 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700925#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700926 int fd;
927 Py_ssize_t length;
928 PyObject *object;
929 PyObject *cleanup;
930} path_t;
931
Steve Dowercc16be82016-09-08 10:35:16 -0700932#ifdef MS_WINDOWS
933#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
934 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
935#else
Larry Hastings2f936352014-08-05 14:04:04 +1000936#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
937 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700938#endif
Larry Hastings31826802013-10-19 00:09:25 -0700939
Larry Hastings9cf065c2012-06-22 16:30:09 -0700940static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800941path_cleanup(path_t *path)
942{
943 Py_CLEAR(path->object);
944 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700945}
946
947static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300948path_converter(PyObject *o, void *p)
949{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700950 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800951 PyObject *bytes = NULL;
952 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700953 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300954 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700955#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800956 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700957 const wchar_t *wide;
958#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700959
960#define FORMAT_EXCEPTION(exc, fmt) \
961 PyErr_Format(exc, "%s%s" fmt, \
962 path->function_name ? path->function_name : "", \
963 path->function_name ? ": " : "", \
964 path->argument_name ? path->argument_name : "path")
965
966 /* Py_CLEANUP_SUPPORTED support */
967 if (o == NULL) {
968 path_cleanup(path);
969 return 1;
970 }
971
Brett Cannon3f9183b2016-08-26 14:44:48 -0700972 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800973 path->object = path->cleanup = NULL;
974 /* path->object owns a reference to the original object */
975 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700976
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300977 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700978 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700979#ifdef MS_WINDOWS
980 path->narrow = FALSE;
981#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700982 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700983#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700984 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800985 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700986 }
987
Brett Cannon3f9183b2016-08-26 14:44:48 -0700988 /* Only call this here so that we don't treat the return value of
989 os.fspath() as an fd or buffer. */
990 is_index = path->allow_fd && PyIndex_Check(o);
991 is_buffer = PyObject_CheckBuffer(o);
992 is_bytes = PyBytes_Check(o);
993 is_unicode = PyUnicode_Check(o);
994
995 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
996 /* Inline PyOS_FSPath() for better error messages. */
997 _Py_IDENTIFIER(__fspath__);
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000998 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700999
1000 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1001 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001002 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001003 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001004 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001005 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001006 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001007 goto error_exit;
1008 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001009 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001010 is_unicode = 1;
1011 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001012 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001013 is_bytes = 1;
1014 }
1015 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001016 PyErr_Format(PyExc_TypeError,
1017 "expected %.200s.__fspath__() to return str or bytes, "
1018 "not %.200s", Py_TYPE(o)->tp_name,
1019 Py_TYPE(res)->tp_name);
1020 Py_DECREF(res);
1021 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001022 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001023
1024 /* still owns a reference to the original object */
1025 Py_DECREF(o);
1026 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001027 }
1028
1029 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001030#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001031 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001032 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001033 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001034 }
Victor Stinner59799a82013-11-13 14:17:30 +01001035 if (length > 32767) {
1036 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001037 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001038 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001039 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001040 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001041 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001042 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001043
1044 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001045 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001046 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001047 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001048#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001049 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001050 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001051 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052#endif
1053 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001054 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001055 bytes = o;
1056 Py_INCREF(bytes);
1057 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001058 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001059 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001060 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001061 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1062 "%s%s%s should be %s, not %.200s",
1063 path->function_name ? path->function_name : "",
1064 path->function_name ? ": " : "",
1065 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001066 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1067 "integer or None" :
1068 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1069 path->nullable ? "string, bytes, os.PathLike or None" :
1070 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001071 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001072 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001073 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001074 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001075 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001076 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001077 }
1078 }
Steve Dowercc16be82016-09-08 10:35:16 -07001079 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001080 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001081 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001082 }
1083 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001084#ifdef MS_WINDOWS
1085 path->narrow = FALSE;
1086#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001087 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001088#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001089 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001090 }
1091 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001092 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001093 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1094 path->function_name ? path->function_name : "",
1095 path->function_name ? ": " : "",
1096 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001097 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1098 "integer or None" :
1099 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1100 path->nullable ? "string, bytes, os.PathLike or None" :
1101 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001102 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001103 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001104 }
1105
Larry Hastings9cf065c2012-06-22 16:30:09 -07001106 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001107 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001108 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001109 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001110 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001111 }
1112
Steve Dowercc16be82016-09-08 10:35:16 -07001113#ifdef MS_WINDOWS
1114 wo = PyUnicode_DecodeFSDefaultAndSize(
1115 narrow,
1116 length
1117 );
1118 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001119 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001120 }
1121
Xiang Zhang04316c42017-01-08 23:26:57 +08001122 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001123 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001124 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001125 }
1126 if (length > 32767) {
1127 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001128 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001129 }
1130 if (wcslen(wide) != length) {
1131 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001132 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001133 }
1134 path->wide = wide;
1135 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001136 path->cleanup = wo;
1137 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001138#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001139 path->wide = NULL;
1140 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001141 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001142 /* Still a reference owned by path->object, don't have to
1143 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001144 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001145 }
1146 else {
1147 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001148 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001149#endif
1150 path->fd = -1;
1151
1152 success_exit:
1153 path->length = length;
1154 path->object = o;
1155 return Py_CLEANUP_SUPPORTED;
1156
1157 error_exit:
1158 Py_XDECREF(o);
1159 Py_XDECREF(bytes);
1160#ifdef MS_WINDOWS
1161 Py_XDECREF(wo);
1162#endif
1163 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001164}
1165
1166static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001167argument_unavailable_error(const char *function_name, const char *argument_name)
1168{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001169 PyErr_Format(PyExc_NotImplementedError,
1170 "%s%s%s unavailable on this platform",
1171 (function_name != NULL) ? function_name : "",
1172 (function_name != NULL) ? ": ": "",
1173 argument_name);
1174}
1175
1176static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001177dir_fd_unavailable(PyObject *o, void *p)
1178{
1179 int dir_fd;
1180 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001181 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001182 if (dir_fd != DEFAULT_DIR_FD) {
1183 argument_unavailable_error(NULL, "dir_fd");
1184 return 0;
1185 }
1186 *(int *)p = dir_fd;
1187 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001188}
1189
1190static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001191fd_specified(const char *function_name, int fd)
1192{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001193 if (fd == -1)
1194 return 0;
1195
1196 argument_unavailable_error(function_name, "fd");
1197 return 1;
1198}
1199
1200static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001201follow_symlinks_specified(const char *function_name, int follow_symlinks)
1202{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001203 if (follow_symlinks)
1204 return 0;
1205
1206 argument_unavailable_error(function_name, "follow_symlinks");
1207 return 1;
1208}
1209
1210static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001211path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1212{
Steve Dowercc16be82016-09-08 10:35:16 -07001213 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1214#ifndef MS_WINDOWS
1215 && !path->narrow
1216#endif
1217 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001218 PyErr_Format(PyExc_ValueError,
1219 "%s: can't specify dir_fd without matching path",
1220 function_name);
1221 return 1;
1222 }
1223 return 0;
1224}
1225
1226static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001227dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1228{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001229 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1230 PyErr_Format(PyExc_ValueError,
1231 "%s: can't specify both dir_fd and fd",
1232 function_name);
1233 return 1;
1234 }
1235 return 0;
1236}
1237
1238static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001239fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1240 int follow_symlinks)
1241{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001242 if ((fd > 0) && (!follow_symlinks)) {
1243 PyErr_Format(PyExc_ValueError,
1244 "%s: cannot use fd and follow_symlinks together",
1245 function_name);
1246 return 1;
1247 }
1248 return 0;
1249}
1250
1251static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001252dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1253 int follow_symlinks)
1254{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001255 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1256 PyErr_Format(PyExc_ValueError,
1257 "%s: cannot use dir_fd and follow_symlinks together",
1258 function_name);
1259 return 1;
1260 }
1261 return 0;
1262}
1263
Larry Hastings2f936352014-08-05 14:04:04 +10001264#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001265 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001266#else
Larry Hastings2f936352014-08-05 14:04:04 +10001267 typedef off_t Py_off_t;
1268#endif
1269
1270static int
1271Py_off_t_converter(PyObject *arg, void *addr)
1272{
1273#ifdef HAVE_LARGEFILE_SUPPORT
1274 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1275#else
1276 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001277#endif
1278 if (PyErr_Occurred())
1279 return 0;
1280 return 1;
1281}
Larry Hastings2f936352014-08-05 14:04:04 +10001282
1283static PyObject *
1284PyLong_FromPy_off_t(Py_off_t offset)
1285{
1286#ifdef HAVE_LARGEFILE_SUPPORT
1287 return PyLong_FromLongLong(offset);
1288#else
1289 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001290#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001291}
1292
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001293#ifdef HAVE_SIGSET_T
1294/* Convert an iterable of integers to a sigset.
1295 Return 1 on success, return 0 and raise an exception on error. */
1296int
1297_Py_Sigset_Converter(PyObject *obj, void *addr)
1298{
1299 sigset_t *mask = (sigset_t *)addr;
1300 PyObject *iterator, *item;
1301 long signum;
1302 int overflow;
1303
Rémi Lapeyref0900192019-05-04 01:30:53 +02001304 // The extra parens suppress the unreachable-code warning with clang on MacOS
1305 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001306 /* Probably only if mask == NULL. */
1307 PyErr_SetFromErrno(PyExc_OSError);
1308 return 0;
1309 }
1310
1311 iterator = PyObject_GetIter(obj);
1312 if (iterator == NULL) {
1313 return 0;
1314 }
1315
1316 while ((item = PyIter_Next(iterator)) != NULL) {
1317 signum = PyLong_AsLongAndOverflow(item, &overflow);
1318 Py_DECREF(item);
1319 if (signum <= 0 || signum >= NSIG) {
1320 if (overflow || signum != -1 || !PyErr_Occurred()) {
1321 PyErr_Format(PyExc_ValueError,
1322 "signal number %ld out of range", signum);
1323 }
1324 goto error;
1325 }
1326 if (sigaddset(mask, (int)signum)) {
1327 if (errno != EINVAL) {
1328 /* Probably impossible */
1329 PyErr_SetFromErrno(PyExc_OSError);
1330 goto error;
1331 }
1332 /* For backwards compatibility, allow idioms such as
1333 * `range(1, NSIG)` but warn about invalid signal numbers
1334 */
1335 const char msg[] =
1336 "invalid signal number %ld, please use valid_signals()";
1337 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1338 goto error;
1339 }
1340 }
1341 }
1342 if (!PyErr_Occurred()) {
1343 Py_DECREF(iterator);
1344 return 1;
1345 }
1346
1347error:
1348 Py_DECREF(iterator);
1349 return 0;
1350}
1351#endif /* HAVE_SIGSET_T */
1352
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001353#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001354
1355static int
Brian Curtind25aef52011-06-13 15:16:04 -05001356win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001357{
Martin Panter70214ad2016-08-04 02:38:59 +00001358 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1359 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001360 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001361
1362 if (0 == DeviceIoControl(
1363 reparse_point_handle,
1364 FSCTL_GET_REPARSE_POINT,
1365 NULL, 0, /* in buffer */
1366 target_buffer, sizeof(target_buffer),
1367 &n_bytes_returned,
1368 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001369 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001370
1371 if (reparse_tag)
1372 *reparse_tag = rdb->ReparseTag;
1373
Brian Curtind25aef52011-06-13 15:16:04 -05001374 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001375}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001376
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001377#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001378
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001379/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001380#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001381/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001382** environ directly, we must obtain it with _NSGetEnviron(). See also
1383** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001384*/
1385#include <crt_externs.h>
1386static char **environ;
pxinwrf2d7ac72019-05-21 18:46:37 +08001387#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001388extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001389#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001390
Barry Warsaw53699e91996-12-10 23:23:01 +00001391static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001392convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001393{
Victor Stinner8c62be82010-05-06 00:08:46 +00001394 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001395#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001396 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001397#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001398 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001399#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001400
Victor Stinner8c62be82010-05-06 00:08:46 +00001401 d = PyDict_New();
1402 if (d == NULL)
1403 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001404#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001405 if (environ == NULL)
1406 environ = *_NSGetEnviron();
1407#endif
1408#ifdef MS_WINDOWS
1409 /* _wenviron must be initialized in this way if the program is started
1410 through main() instead of wmain(). */
1411 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001412 e = _wenviron;
Victor Stinner8c62be82010-05-06 00:08:46 +00001413#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001414 e = environ;
1415#endif
1416 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001417 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001418 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001419 PyObject *k;
1420 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001421#ifdef MS_WINDOWS
1422 const wchar_t *p = wcschr(*e, L'=');
1423#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001424 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001425#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001426 if (p == NULL)
1427 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001428#ifdef MS_WINDOWS
1429 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1430#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001431 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001432#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001433 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001434 Py_DECREF(d);
1435 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001436 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001437#ifdef MS_WINDOWS
1438 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1439#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001440 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001441#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001442 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001443 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001444 Py_DECREF(d);
1445 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001446 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001447 if (PyDict_GetItemWithError(d, k) == NULL) {
1448 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1449 Py_DECREF(v);
1450 Py_DECREF(k);
1451 Py_DECREF(d);
1452 return NULL;
1453 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001454 }
1455 Py_DECREF(k);
1456 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001457 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001458 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001459}
1460
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001461/* Set a POSIX-specific error from errno, and return NULL */
1462
Barry Warsawd58d7641998-07-23 16:14:40 +00001463static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001464posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001465{
Victor Stinner8c62be82010-05-06 00:08:46 +00001466 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001467}
Mark Hammondef8b6542001-05-13 08:04:26 +00001468
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001469#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001470static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001471win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001472{
Victor Stinner8c62be82010-05-06 00:08:46 +00001473 /* XXX We should pass the function name along in the future.
1474 (winreg.c also wants to pass the function name.)
1475 This would however require an additional param to the
1476 Windows error object, which is non-trivial.
1477 */
1478 errno = GetLastError();
1479 if (filename)
1480 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1481 else
1482 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001483}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001484
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001485static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001486win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001487{
1488 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001489 if (filename)
1490 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001491 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001492 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001493 filename);
1494 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001495 return PyErr_SetFromWindowsErr(err);
1496}
1497
1498static PyObject *
1499win32_error_object(const char* function, PyObject* filename)
1500{
1501 errno = GetLastError();
1502 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001503}
1504
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001505#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001506
Larry Hastings9cf065c2012-06-22 16:30:09 -07001507static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001508posix_path_object_error(PyObject *path)
1509{
1510 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1511}
1512
1513static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001514path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001515{
1516#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001517 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1518 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001519#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001520 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001521#endif
1522}
1523
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001524static PyObject *
1525path_object_error2(PyObject *path, PyObject *path2)
1526{
1527#ifdef MS_WINDOWS
1528 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1529 PyExc_OSError, 0, path, path2);
1530#else
1531 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1532#endif
1533}
1534
1535static PyObject *
1536path_error(path_t *path)
1537{
1538 return path_object_error(path->object);
1539}
Larry Hastings31826802013-10-19 00:09:25 -07001540
Larry Hastingsb0827312014-02-09 22:05:19 -08001541static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001542posix_path_error(path_t *path)
1543{
1544 return posix_path_object_error(path->object);
1545}
1546
1547static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001548path_error2(path_t *path, path_t *path2)
1549{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001550 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001551}
1552
1553
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001554/* POSIX generic methods */
1555
Larry Hastings2f936352014-08-05 14:04:04 +10001556static int
1557fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001558{
Victor Stinner8c62be82010-05-06 00:08:46 +00001559 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001560 int *pointer = (int *)p;
1561 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001562 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001563 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001564 *pointer = fd;
1565 return 1;
1566}
1567
1568static PyObject *
1569posix_fildes_fd(int fd, int (*func)(int))
1570{
1571 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001572 int async_err = 0;
1573
1574 do {
1575 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001576 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001577 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001578 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001579 Py_END_ALLOW_THREADS
1580 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1581 if (res != 0)
1582 return (!async_err) ? posix_error() : NULL;
1583 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001584}
Guido van Rossum21142a01999-01-08 21:05:37 +00001585
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001586
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001587#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001588/* This is a reimplementation of the C library's chdir function,
1589 but one that produces Win32 errors instead of DOS error codes.
1590 chdir is essentially a wrapper around SetCurrentDirectory; however,
1591 it also needs to set "magic" environment variables indicating
1592 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001593static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001594win32_wchdir(LPCWSTR path)
1595{
Victor Stinnered537822015-12-13 21:40:26 +01001596 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001597 int result;
1598 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001599
Victor Stinner8c62be82010-05-06 00:08:46 +00001600 if(!SetCurrentDirectoryW(path))
1601 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001602 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001603 if (!result)
1604 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001605 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001606 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001607 if (!new_path) {
1608 SetLastError(ERROR_OUTOFMEMORY);
1609 return FALSE;
1610 }
1611 result = GetCurrentDirectoryW(result, new_path);
1612 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001613 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001614 return FALSE;
1615 }
1616 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001617 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1618 wcsncmp(new_path, L"//", 2) == 0);
1619 if (!is_unc_like_path) {
1620 env[1] = new_path[0];
1621 result = SetEnvironmentVariableW(env, new_path);
1622 }
Victor Stinnered537822015-12-13 21:40:26 +01001623 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001624 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001625 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001626}
1627#endif
1628
Martin v. Löwis14694662006-02-03 12:54:16 +00001629#ifdef MS_WINDOWS
1630/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1631 - time stamps are restricted to second resolution
1632 - file modification times suffer from forth-and-back conversions between
1633 UTC and local time
1634 Therefore, we implement our own stat, based on the Win32 API directly.
1635*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001636#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001637#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001638
Victor Stinner6036e442015-03-08 01:58:04 +01001639static void
Steve Dowercc16be82016-09-08 10:35:16 -07001640find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1641 BY_HANDLE_FILE_INFORMATION *info,
1642 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001643{
1644 memset(info, 0, sizeof(*info));
1645 info->dwFileAttributes = pFileData->dwFileAttributes;
1646 info->ftCreationTime = pFileData->ftCreationTime;
1647 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1648 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1649 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1650 info->nFileSizeLow = pFileData->nFileSizeLow;
1651/* info->nNumberOfLinks = 1; */
1652 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1653 *reparse_tag = pFileData->dwReserved0;
1654 else
1655 *reparse_tag = 0;
1656}
1657
Guido van Rossumd8faa362007-04-27 19:54:29 +00001658static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001659attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001660{
Victor Stinner8c62be82010-05-06 00:08:46 +00001661 HANDLE hFindFile;
1662 WIN32_FIND_DATAW FileData;
1663 hFindFile = FindFirstFileW(pszFile, &FileData);
1664 if (hFindFile == INVALID_HANDLE_VALUE)
1665 return FALSE;
1666 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001667 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001668 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001669}
1670
Brian Curtind25aef52011-06-13 15:16:04 -05001671static BOOL
1672get_target_path(HANDLE hdl, wchar_t **target_path)
1673{
1674 int buf_size, result_length;
1675 wchar_t *buf;
1676
1677 /* We have a good handle to the target, use it to determine
1678 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001679 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1680 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001681 if(!buf_size)
1682 return FALSE;
1683
Victor Stinnerc36674a2016-03-16 14:30:16 +01001684 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001685 if (!buf) {
1686 SetLastError(ERROR_OUTOFMEMORY);
1687 return FALSE;
1688 }
1689
Steve Dower2ea51c92015-03-20 21:49:12 -07001690 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001691 buf, buf_size, VOLUME_NAME_DOS);
1692
1693 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001694 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001695 return FALSE;
1696 }
1697
Brian Curtind25aef52011-06-13 15:16:04 -05001698 buf[result_length] = 0;
1699
1700 *target_path = buf;
1701 return TRUE;
1702}
1703
1704static int
Steve Dowercc16be82016-09-08 10:35:16 -07001705win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001706 BOOL traverse)
1707{
Victor Stinner26de69d2011-06-17 15:15:38 +02001708 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001709 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001710 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001711 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001712 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001713 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001714
Steve Dowercc16be82016-09-08 10:35:16 -07001715 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001716 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001717 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001718 0, /* share mode */
1719 NULL, /* security attributes */
1720 OPEN_EXISTING,
1721 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001722 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1723 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001724 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001725 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1726 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001727 NULL);
1728
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001729 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001730 /* Either the target doesn't exist, or we don't have access to
1731 get a handle to it. If the former, we need to return an error.
1732 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001733 DWORD lastError = GetLastError();
1734 if (lastError != ERROR_ACCESS_DENIED &&
1735 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001736 return -1;
1737 /* Could not get attributes on open file. Fall back to
1738 reading the directory. */
1739 if (!attributes_from_dir(path, &info, &reparse_tag))
1740 /* Very strange. This should not fail now */
1741 return -1;
1742 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1743 if (traverse) {
1744 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001745 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001746 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001747 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001748 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001749 } else {
1750 if (!GetFileInformationByHandle(hFile, &info)) {
1751 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001752 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001753 }
1754 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Mark Becwarb82bfac2019-02-02 16:08:23 -05001755 if (!win32_get_reparse_tag(hFile, &reparse_tag)) {
1756 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001757 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001758 }
Brian Curtind25aef52011-06-13 15:16:04 -05001759 /* Close the outer open file handle now that we're about to
1760 reopen it with different flags. */
1761 if (!CloseHandle(hFile))
1762 return -1;
1763
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001764 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001765 /* In order to call GetFinalPathNameByHandle we need to open
1766 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001767 hFile2 = CreateFileW(
1768 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1769 NULL, OPEN_EXISTING,
1770 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1771 NULL);
1772 if (hFile2 == INVALID_HANDLE_VALUE)
1773 return -1;
1774
Mark Becwarb82bfac2019-02-02 16:08:23 -05001775 if (!get_target_path(hFile2, &target_path)) {
1776 CloseHandle(hFile2);
Brian Curtind25aef52011-06-13 15:16:04 -05001777 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001778 }
1779
1780 if (!CloseHandle(hFile2)) {
1781 return -1;
1782 }
Brian Curtind25aef52011-06-13 15:16:04 -05001783
Steve Dowercc16be82016-09-08 10:35:16 -07001784 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001785 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001786 return code;
1787 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001788 } else
1789 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001790 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001791 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001792
1793 /* Set S_IEXEC if it is an .exe, .bat, ... */
1794 dot = wcsrchr(path, '.');
1795 if (dot) {
1796 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1797 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1798 result->st_mode |= 0111;
1799 }
1800 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001801}
1802
1803static int
Steve Dowercc16be82016-09-08 10:35:16 -07001804win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001805{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001806 /* Protocol violation: we explicitly clear errno, instead of
1807 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001808 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001809 errno = 0;
1810 return code;
1811}
Brian Curtind25aef52011-06-13 15:16:04 -05001812/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001813
1814 In Posix, stat automatically traverses symlinks and returns the stat
1815 structure for the target. In Windows, the equivalent GetFileAttributes by
1816 default does not traverse symlinks and instead returns attributes for
1817 the symlink.
1818
1819 Therefore, win32_lstat will get the attributes traditionally, and
1820 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001821 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001822
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001823static int
Steve Dowercc16be82016-09-08 10:35:16 -07001824win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001825{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001826 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001827}
1828
Victor Stinner8c62be82010-05-06 00:08:46 +00001829static int
Steve Dowercc16be82016-09-08 10:35:16 -07001830win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001831{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001832 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001833}
1834
Martin v. Löwis14694662006-02-03 12:54:16 +00001835#endif /* MS_WINDOWS */
1836
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001837PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001838"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001839This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001840 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001841or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1842\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001843Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1844or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001845\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001846See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001847
1848static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001849 {"st_mode", "protection bits"},
1850 {"st_ino", "inode"},
1851 {"st_dev", "device"},
1852 {"st_nlink", "number of hard links"},
1853 {"st_uid", "user ID of owner"},
1854 {"st_gid", "group ID of owner"},
1855 {"st_size", "total size, in bytes"},
1856 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1857 {NULL, "integer time of last access"},
1858 {NULL, "integer time of last modification"},
1859 {NULL, "integer time of last change"},
1860 {"st_atime", "time of last access"},
1861 {"st_mtime", "time of last modification"},
1862 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001863 {"st_atime_ns", "time of last access in nanoseconds"},
1864 {"st_mtime_ns", "time of last modification in nanoseconds"},
1865 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001866#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001867 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001868#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001869#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001870 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001871#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001872#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001873 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001874#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001875#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001876 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001877#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001878#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001879 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001880#endif
1881#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001882 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001883#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001884#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1885 {"st_file_attributes", "Windows file attribute bits"},
1886#endif
jcea6c51d512018-01-28 14:00:08 +01001887#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1888 {"st_fstype", "Type of filesystem"},
1889#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001890 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001891};
1892
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001893#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001894#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001895#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001896#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001897#endif
1898
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001899#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001900#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1901#else
1902#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1903#endif
1904
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001905#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001906#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1907#else
1908#define ST_RDEV_IDX ST_BLOCKS_IDX
1909#endif
1910
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001911#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1912#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1913#else
1914#define ST_FLAGS_IDX ST_RDEV_IDX
1915#endif
1916
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001917#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001918#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001919#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001920#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001921#endif
1922
1923#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1924#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1925#else
1926#define ST_BIRTHTIME_IDX ST_GEN_IDX
1927#endif
1928
Zachary Ware63f277b2014-06-19 09:46:37 -05001929#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1930#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1931#else
1932#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1933#endif
1934
jcea6c51d512018-01-28 14:00:08 +01001935#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1936#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1937#else
1938#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1939#endif
1940
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001941static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001942 "stat_result", /* name */
1943 stat_result__doc__, /* doc */
1944 stat_result_fields,
1945 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001946};
1947
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001948PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001949"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1950This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001951 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001952or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001953\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001954See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001955
1956static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001957 {"f_bsize", },
1958 {"f_frsize", },
1959 {"f_blocks", },
1960 {"f_bfree", },
1961 {"f_bavail", },
1962 {"f_files", },
1963 {"f_ffree", },
1964 {"f_favail", },
1965 {"f_flag", },
1966 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001967 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001968 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001969};
1970
1971static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001972 "statvfs_result", /* name */
1973 statvfs_result__doc__, /* doc */
1974 statvfs_result_fields,
1975 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001976};
1977
Ross Lagerwall7807c352011-03-17 20:20:30 +02001978#if defined(HAVE_WAITID) && !defined(__APPLE__)
1979PyDoc_STRVAR(waitid_result__doc__,
1980"waitid_result: Result from waitid.\n\n\
1981This object may be accessed either as a tuple of\n\
1982 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1983or via the attributes si_pid, si_uid, and so on.\n\
1984\n\
1985See os.waitid for more information.");
1986
1987static PyStructSequence_Field waitid_result_fields[] = {
1988 {"si_pid", },
1989 {"si_uid", },
1990 {"si_signo", },
1991 {"si_status", },
1992 {"si_code", },
1993 {0}
1994};
1995
1996static PyStructSequence_Desc waitid_result_desc = {
1997 "waitid_result", /* name */
1998 waitid_result__doc__, /* doc */
1999 waitid_result_fields,
2000 5
2001};
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002002static PyTypeObject* WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +02002003#endif
2004
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002005static int initialized;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002006static PyTypeObject* StatResultType;
2007static PyTypeObject* StatVFSResultType;
William Orr81574b82018-10-01 22:19:56 -07002008#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002009static PyTypeObject* SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002010#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002011static newfunc structseq_new;
2012
2013static PyObject *
2014statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2015{
Victor Stinner8c62be82010-05-06 00:08:46 +00002016 PyStructSequence *result;
2017 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002018
Victor Stinner8c62be82010-05-06 00:08:46 +00002019 result = (PyStructSequence*)structseq_new(type, args, kwds);
2020 if (!result)
2021 return NULL;
2022 /* If we have been initialized from a tuple,
2023 st_?time might be set to None. Initialize it
2024 from the int slots. */
2025 for (i = 7; i <= 9; i++) {
2026 if (result->ob_item[i+3] == Py_None) {
2027 Py_DECREF(Py_None);
2028 Py_INCREF(result->ob_item[i]);
2029 result->ob_item[i+3] = result->ob_item[i];
2030 }
2031 }
2032 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002033}
2034
2035
Larry Hastings6fe20b32012-04-19 15:07:49 -07002036static PyObject *billion = NULL;
2037
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002038static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002039fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002040{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002041 PyObject *s = _PyLong_FromTime_t(sec);
2042 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2043 PyObject *s_in_ns = NULL;
2044 PyObject *ns_total = NULL;
2045 PyObject *float_s = NULL;
2046
2047 if (!(s && ns_fractional))
2048 goto exit;
2049
2050 s_in_ns = PyNumber_Multiply(s, billion);
2051 if (!s_in_ns)
2052 goto exit;
2053
2054 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2055 if (!ns_total)
2056 goto exit;
2057
Victor Stinner01b5aab2017-10-24 02:02:00 -07002058 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2059 if (!float_s) {
2060 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002061 }
2062
2063 PyStructSequence_SET_ITEM(v, index, s);
2064 PyStructSequence_SET_ITEM(v, index+3, float_s);
2065 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2066 s = NULL;
2067 float_s = NULL;
2068 ns_total = NULL;
2069exit:
2070 Py_XDECREF(s);
2071 Py_XDECREF(ns_fractional);
2072 Py_XDECREF(s_in_ns);
2073 Py_XDECREF(ns_total);
2074 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002075}
2076
Tim Peters5aa91602002-01-30 05:46:57 +00002077/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002078 (used by posix_stat() and posix_fstat()) */
2079static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002080_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002081{
Victor Stinner8c62be82010-05-06 00:08:46 +00002082 unsigned long ansec, mnsec, cnsec;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002083 PyObject *v = PyStructSequence_New(StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 if (v == NULL)
2085 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002086
Victor Stinner8c62be82010-05-06 00:08:46 +00002087 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002088 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002089 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002090#ifdef MS_WINDOWS
2091 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002092#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002093 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002094#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002095 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002096#if defined(MS_WINDOWS)
2097 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2098 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2099#else
2100 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2101 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2102#endif
xdegaye50e86032017-05-22 11:15:08 +02002103 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2104 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002105
Martin v. Löwis14694662006-02-03 12:54:16 +00002106#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002107 ansec = st->st_atim.tv_nsec;
2108 mnsec = st->st_mtim.tv_nsec;
2109 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002110#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002111 ansec = st->st_atimespec.tv_nsec;
2112 mnsec = st->st_mtimespec.tv_nsec;
2113 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002114#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002115 ansec = st->st_atime_nsec;
2116 mnsec = st->st_mtime_nsec;
2117 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002118#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002119 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002120#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002121 fill_time(v, 7, st->st_atime, ansec);
2122 fill_time(v, 8, st->st_mtime, mnsec);
2123 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002124
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002125#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002126 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2127 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002128#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002129#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002130 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2131 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002132#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002133#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002134 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2135 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002136#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002137#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002138 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2139 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002140#endif
2141#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002142 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002143 PyObject *val;
2144 unsigned long bsec,bnsec;
2145 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002146#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002147 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002148#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002149 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002150#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002151 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002152 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2153 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002154 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002155#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002156#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002157 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2158 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002159#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002160#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2161 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2162 PyLong_FromUnsignedLong(st->st_file_attributes));
2163#endif
jcea6c51d512018-01-28 14:00:08 +01002164#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2165 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2166 PyUnicode_FromString(st->st_fstype));
2167#endif
Fred Drake699f3522000-06-29 21:12:41 +00002168
Victor Stinner8c62be82010-05-06 00:08:46 +00002169 if (PyErr_Occurred()) {
2170 Py_DECREF(v);
2171 return NULL;
2172 }
Fred Drake699f3522000-06-29 21:12:41 +00002173
Victor Stinner8c62be82010-05-06 00:08:46 +00002174 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002175}
2176
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002177/* POSIX methods */
2178
Guido van Rossum94f6f721999-01-06 18:42:14 +00002179
2180static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002181posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002182 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002183{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002184 STRUCT_STAT st;
2185 int result;
2186
2187#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2188 if (follow_symlinks_specified(function_name, follow_symlinks))
2189 return NULL;
2190#endif
2191
2192 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2193 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2194 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2195 return NULL;
2196
2197 Py_BEGIN_ALLOW_THREADS
2198 if (path->fd != -1)
2199 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002200#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002201 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002202 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002203 else
Steve Dowercc16be82016-09-08 10:35:16 -07002204 result = win32_lstat(path->wide, &st);
2205#else
2206 else
2207#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002208 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2209 result = LSTAT(path->narrow, &st);
2210 else
Steve Dowercc16be82016-09-08 10:35:16 -07002211#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002212#ifdef HAVE_FSTATAT
2213 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2214 result = fstatat(dir_fd, path->narrow, &st,
2215 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2216 else
Steve Dowercc16be82016-09-08 10:35:16 -07002217#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002218 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002219#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002220 Py_END_ALLOW_THREADS
2221
Victor Stinner292c8352012-10-30 02:17:38 +01002222 if (result != 0) {
2223 return path_error(path);
2224 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002225
2226 return _pystat_fromstructstat(&st);
2227}
2228
Larry Hastings2f936352014-08-05 14:04:04 +10002229/*[python input]
2230
2231for s in """
2232
2233FACCESSAT
2234FCHMODAT
2235FCHOWNAT
2236FSTATAT
2237LINKAT
2238MKDIRAT
2239MKFIFOAT
2240MKNODAT
2241OPENAT
2242READLINKAT
2243SYMLINKAT
2244UNLINKAT
2245
2246""".strip().split():
2247 s = s.strip()
2248 print("""
2249#ifdef HAVE_{s}
2250 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002251#else
Larry Hastings2f936352014-08-05 14:04:04 +10002252 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002253#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002254""".rstrip().format(s=s))
2255
2256for s in """
2257
2258FCHDIR
2259FCHMOD
2260FCHOWN
2261FDOPENDIR
2262FEXECVE
2263FPATHCONF
2264FSTATVFS
2265FTRUNCATE
2266
2267""".strip().split():
2268 s = s.strip()
2269 print("""
2270#ifdef HAVE_{s}
2271 #define PATH_HAVE_{s} 1
2272#else
2273 #define PATH_HAVE_{s} 0
2274#endif
2275
2276""".rstrip().format(s=s))
2277[python start generated code]*/
2278
2279#ifdef HAVE_FACCESSAT
2280 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2281#else
2282 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2283#endif
2284
2285#ifdef HAVE_FCHMODAT
2286 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2287#else
2288 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2289#endif
2290
2291#ifdef HAVE_FCHOWNAT
2292 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2293#else
2294 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2295#endif
2296
2297#ifdef HAVE_FSTATAT
2298 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2299#else
2300 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2301#endif
2302
2303#ifdef HAVE_LINKAT
2304 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2305#else
2306 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2307#endif
2308
2309#ifdef HAVE_MKDIRAT
2310 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2311#else
2312 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2313#endif
2314
2315#ifdef HAVE_MKFIFOAT
2316 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2317#else
2318 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2319#endif
2320
2321#ifdef HAVE_MKNODAT
2322 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2323#else
2324 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2325#endif
2326
2327#ifdef HAVE_OPENAT
2328 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2329#else
2330 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2331#endif
2332
2333#ifdef HAVE_READLINKAT
2334 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2335#else
2336 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2337#endif
2338
2339#ifdef HAVE_SYMLINKAT
2340 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2341#else
2342 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2343#endif
2344
2345#ifdef HAVE_UNLINKAT
2346 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2347#else
2348 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2349#endif
2350
2351#ifdef HAVE_FCHDIR
2352 #define PATH_HAVE_FCHDIR 1
2353#else
2354 #define PATH_HAVE_FCHDIR 0
2355#endif
2356
2357#ifdef HAVE_FCHMOD
2358 #define PATH_HAVE_FCHMOD 1
2359#else
2360 #define PATH_HAVE_FCHMOD 0
2361#endif
2362
2363#ifdef HAVE_FCHOWN
2364 #define PATH_HAVE_FCHOWN 1
2365#else
2366 #define PATH_HAVE_FCHOWN 0
2367#endif
2368
2369#ifdef HAVE_FDOPENDIR
2370 #define PATH_HAVE_FDOPENDIR 1
2371#else
2372 #define PATH_HAVE_FDOPENDIR 0
2373#endif
2374
2375#ifdef HAVE_FEXECVE
2376 #define PATH_HAVE_FEXECVE 1
2377#else
2378 #define PATH_HAVE_FEXECVE 0
2379#endif
2380
2381#ifdef HAVE_FPATHCONF
2382 #define PATH_HAVE_FPATHCONF 1
2383#else
2384 #define PATH_HAVE_FPATHCONF 0
2385#endif
2386
2387#ifdef HAVE_FSTATVFS
2388 #define PATH_HAVE_FSTATVFS 1
2389#else
2390 #define PATH_HAVE_FSTATVFS 0
2391#endif
2392
2393#ifdef HAVE_FTRUNCATE
2394 #define PATH_HAVE_FTRUNCATE 1
2395#else
2396 #define PATH_HAVE_FTRUNCATE 0
2397#endif
2398/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002399
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002400#ifdef MS_WINDOWS
2401 #undef PATH_HAVE_FTRUNCATE
2402 #define PATH_HAVE_FTRUNCATE 1
2403#endif
Larry Hastings31826802013-10-19 00:09:25 -07002404
Larry Hastings61272b72014-01-07 12:41:53 -08002405/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002406
2407class path_t_converter(CConverter):
2408
2409 type = "path_t"
2410 impl_by_reference = True
2411 parse_by_reference = True
2412
2413 converter = 'path_converter'
2414
2415 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002416 # right now path_t doesn't support default values.
2417 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002418 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002419 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002420
Larry Hastings2f936352014-08-05 14:04:04 +10002421 if self.c_default not in (None, 'Py_None'):
2422 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002423
2424 self.nullable = nullable
2425 self.allow_fd = allow_fd
2426
Larry Hastings7726ac92014-01-31 22:03:12 -08002427 def pre_render(self):
2428 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002429 if isinstance(value, str):
2430 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002431 return str(int(bool(value)))
2432
2433 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002434 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002435 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002436 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002437 strify(self.nullable),
2438 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002439 )
2440
2441 def cleanup(self):
2442 return "path_cleanup(&" + self.name + ");\n"
2443
2444
2445class dir_fd_converter(CConverter):
2446 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002447
Larry Hastings2f936352014-08-05 14:04:04 +10002448 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002449 if self.default in (unspecified, None):
2450 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002451 if isinstance(requires, str):
2452 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2453 else:
2454 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002455
Larry Hastings2f936352014-08-05 14:04:04 +10002456class fildes_converter(CConverter):
2457 type = 'int'
2458 converter = 'fildes_converter'
2459
2460class uid_t_converter(CConverter):
2461 type = "uid_t"
2462 converter = '_Py_Uid_Converter'
2463
2464class gid_t_converter(CConverter):
2465 type = "gid_t"
2466 converter = '_Py_Gid_Converter'
2467
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002468class dev_t_converter(CConverter):
2469 type = 'dev_t'
2470 converter = '_Py_Dev_Converter'
2471
2472class dev_t_return_converter(unsigned_long_return_converter):
2473 type = 'dev_t'
2474 conversion_fn = '_PyLong_FromDev'
2475 unsigned_cast = '(dev_t)'
2476
Larry Hastings2f936352014-08-05 14:04:04 +10002477class FSConverter_converter(CConverter):
2478 type = 'PyObject *'
2479 converter = 'PyUnicode_FSConverter'
2480 def converter_init(self):
2481 if self.default is not unspecified:
2482 fail("FSConverter_converter does not support default values")
2483 self.c_default = 'NULL'
2484
2485 def cleanup(self):
2486 return "Py_XDECREF(" + self.name + ");\n"
2487
2488class pid_t_converter(CConverter):
2489 type = 'pid_t'
2490 format_unit = '" _Py_PARSE_PID "'
2491
2492class idtype_t_converter(int_converter):
2493 type = 'idtype_t'
2494
2495class id_t_converter(CConverter):
2496 type = 'id_t'
2497 format_unit = '" _Py_PARSE_PID "'
2498
Benjamin Petersonca470632016-09-06 13:47:26 -07002499class intptr_t_converter(CConverter):
2500 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002501 format_unit = '" _Py_PARSE_INTPTR "'
2502
2503class Py_off_t_converter(CConverter):
2504 type = 'Py_off_t'
2505 converter = 'Py_off_t_converter'
2506
2507class Py_off_t_return_converter(long_return_converter):
2508 type = 'Py_off_t'
2509 conversion_fn = 'PyLong_FromPy_off_t'
2510
2511class path_confname_converter(CConverter):
2512 type="int"
2513 converter="conv_path_confname"
2514
2515class confstr_confname_converter(path_confname_converter):
2516 converter='conv_confstr_confname'
2517
2518class sysconf_confname_converter(path_confname_converter):
2519 converter="conv_sysconf_confname"
2520
2521class sched_param_converter(CConverter):
2522 type = 'struct sched_param'
2523 converter = 'convert_sched_param'
2524 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002525
Larry Hastings61272b72014-01-07 12:41:53 -08002526[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002527/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002528
Larry Hastings61272b72014-01-07 12:41:53 -08002529/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002530
Larry Hastings2a727912014-01-16 11:32:01 -08002531os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002532
2533 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002534 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002535 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002536
2537 *
2538
Larry Hastings2f936352014-08-05 14:04:04 +10002539 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002540 If not None, it should be a file descriptor open to a directory,
2541 and path should be a relative string; path will then be relative to
2542 that directory.
2543
2544 follow_symlinks: bool = True
2545 If False, and the last element of the path is a symbolic link,
2546 stat will examine the symbolic link itself instead of the file
2547 the link points to.
2548
2549Perform a stat system call on the given path.
2550
2551dir_fd and follow_symlinks may not be implemented
2552 on your platform. If they are unavailable, using them will raise a
2553 NotImplementedError.
2554
2555It's an error to use dir_fd or follow_symlinks when specifying path as
2556 an open file descriptor.
2557
Larry Hastings61272b72014-01-07 12:41:53 -08002558[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002559
Larry Hastings31826802013-10-19 00:09:25 -07002560static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002561os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002562/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002563{
2564 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2565}
2566
Larry Hastings2f936352014-08-05 14:04:04 +10002567
2568/*[clinic input]
2569os.lstat
2570
2571 path : path_t
2572
2573 *
2574
2575 dir_fd : dir_fd(requires='fstatat') = None
2576
2577Perform a stat system call on the given path, without following symbolic links.
2578
2579Like stat(), but do not follow symbolic links.
2580Equivalent to stat(path, follow_symlinks=False).
2581[clinic start generated code]*/
2582
Larry Hastings2f936352014-08-05 14:04:04 +10002583static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002584os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2585/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002586{
2587 int follow_symlinks = 0;
2588 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2589}
Larry Hastings31826802013-10-19 00:09:25 -07002590
Larry Hastings2f936352014-08-05 14:04:04 +10002591
Larry Hastings61272b72014-01-07 12:41:53 -08002592/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002593os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002594
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002595 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002596 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002597
2598 mode: int
2599 Operating-system mode bitfield. Can be F_OK to test existence,
2600 or the inclusive-OR of R_OK, W_OK, and X_OK.
2601
2602 *
2603
Larry Hastings2f936352014-08-05 14:04:04 +10002604 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002605 If not None, it should be a file descriptor open to a directory,
2606 and path should be relative; path will then be relative to that
2607 directory.
2608
2609 effective_ids: bool = False
2610 If True, access will use the effective uid/gid instead of
2611 the real uid/gid.
2612
2613 follow_symlinks: bool = True
2614 If False, and the last element of the path is a symbolic link,
2615 access will examine the symbolic link itself instead of the file
2616 the link points to.
2617
2618Use the real uid/gid to test for access to a path.
2619
2620{parameters}
2621dir_fd, effective_ids, and follow_symlinks may not be implemented
2622 on your platform. If they are unavailable, using them will raise a
2623 NotImplementedError.
2624
2625Note that most operations will use the effective uid/gid, therefore this
2626 routine can be used in a suid/sgid environment to test if the invoking user
2627 has the specified access to the path.
2628
Larry Hastings61272b72014-01-07 12:41:53 -08002629[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002630
Larry Hastings2f936352014-08-05 14:04:04 +10002631static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002632os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002633 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002634/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002635{
Larry Hastings2f936352014-08-05 14:04:04 +10002636 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002637
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002638#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002639 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002640#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002641 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002642#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002643
Larry Hastings9cf065c2012-06-22 16:30:09 -07002644#ifndef HAVE_FACCESSAT
2645 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002646 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002647
2648 if (effective_ids) {
2649 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002650 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002651 }
2652#endif
2653
2654#ifdef MS_WINDOWS
2655 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002656 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002657 Py_END_ALLOW_THREADS
2658
2659 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002660 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002661 * * we didn't get a -1, and
2662 * * write access wasn't requested,
2663 * * or the file isn't read-only,
2664 * * or it's a directory.
2665 * (Directories cannot be read-only on Windows.)
2666 */
Larry Hastings2f936352014-08-05 14:04:04 +10002667 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002668 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002669 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002670 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002671#else
2672
2673 Py_BEGIN_ALLOW_THREADS
2674#ifdef HAVE_FACCESSAT
2675 if ((dir_fd != DEFAULT_DIR_FD) ||
2676 effective_ids ||
2677 !follow_symlinks) {
2678 int flags = 0;
2679 if (!follow_symlinks)
2680 flags |= AT_SYMLINK_NOFOLLOW;
2681 if (effective_ids)
2682 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002683 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002684 }
2685 else
2686#endif
Larry Hastings31826802013-10-19 00:09:25 -07002687 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002688 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002689 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002690#endif
2691
Larry Hastings9cf065c2012-06-22 16:30:09 -07002692 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002693}
2694
Guido van Rossumd371ff11999-01-25 16:12:23 +00002695#ifndef F_OK
2696#define F_OK 0
2697#endif
2698#ifndef R_OK
2699#define R_OK 4
2700#endif
2701#ifndef W_OK
2702#define W_OK 2
2703#endif
2704#ifndef X_OK
2705#define X_OK 1
2706#endif
2707
Larry Hastings31826802013-10-19 00:09:25 -07002708
Guido van Rossumd371ff11999-01-25 16:12:23 +00002709#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002710/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002711os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002712
2713 fd: int
2714 Integer file descriptor handle.
2715
2716 /
2717
2718Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002719[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002720
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002721static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002722os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002723/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002724{
2725 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002726
Larry Hastings31826802013-10-19 00:09:25 -07002727 ret = ttyname(fd);
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002728 if (ret == NULL) {
2729 return posix_error();
2730 }
2731 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002732}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002733#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002734
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002735#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002736/*[clinic input]
2737os.ctermid
2738
2739Return the name of the controlling terminal for this process.
2740[clinic start generated code]*/
2741
Larry Hastings2f936352014-08-05 14:04:04 +10002742static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002743os_ctermid_impl(PyObject *module)
2744/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002745{
Victor Stinner8c62be82010-05-06 00:08:46 +00002746 char *ret;
2747 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002748
Greg Wardb48bc172000-03-01 21:51:56 +00002749#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002750 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002751#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002752 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002753#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002754 if (ret == NULL)
2755 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002756 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002757}
Larry Hastings2f936352014-08-05 14:04:04 +10002758#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002759
Larry Hastings2f936352014-08-05 14:04:04 +10002760
2761/*[clinic input]
2762os.chdir
2763
2764 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2765
2766Change the current working directory to the specified path.
2767
2768path may always be specified as a string.
2769On some platforms, path may also be specified as an open file descriptor.
2770 If this functionality is unavailable, using it raises an exception.
2771[clinic start generated code]*/
2772
Larry Hastings2f936352014-08-05 14:04:04 +10002773static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002774os_chdir_impl(PyObject *module, path_t *path)
2775/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002776{
2777 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002778
2779 Py_BEGIN_ALLOW_THREADS
2780#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002781 /* on unix, success = 0, on windows, success = !0 */
2782 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002783#else
2784#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002785 if (path->fd != -1)
2786 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002787 else
2788#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002789 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002790#endif
2791 Py_END_ALLOW_THREADS
2792
2793 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002794 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795 }
2796
Larry Hastings2f936352014-08-05 14:04:04 +10002797 Py_RETURN_NONE;
2798}
2799
2800
2801#ifdef HAVE_FCHDIR
2802/*[clinic input]
2803os.fchdir
2804
2805 fd: fildes
2806
2807Change to the directory of the given file descriptor.
2808
2809fd must be opened on a directory, not a file.
2810Equivalent to os.chdir(fd).
2811
2812[clinic start generated code]*/
2813
Fred Drake4d1e64b2002-04-15 19:40:07 +00002814static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002815os_fchdir_impl(PyObject *module, int fd)
2816/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002817{
Larry Hastings2f936352014-08-05 14:04:04 +10002818 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002819}
2820#endif /* HAVE_FCHDIR */
2821
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002822
Larry Hastings2f936352014-08-05 14:04:04 +10002823/*[clinic input]
2824os.chmod
2825
2826 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002827 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002828 On some platforms, path may also be specified as an open file descriptor.
2829 If this functionality is unavailable, using it raises an exception.
2830
2831 mode: int
2832 Operating-system mode bitfield.
2833
2834 *
2835
2836 dir_fd : dir_fd(requires='fchmodat') = None
2837 If not None, it should be a file descriptor open to a directory,
2838 and path should be relative; path will then be relative to that
2839 directory.
2840
2841 follow_symlinks: bool = True
2842 If False, and the last element of the path is a symbolic link,
2843 chmod will modify the symbolic link itself instead of the file
2844 the link points to.
2845
2846Change the access permissions of a file.
2847
2848It is an error to use dir_fd or follow_symlinks when specifying path as
2849 an open file descriptor.
2850dir_fd and follow_symlinks may not be implemented on your platform.
2851 If they are unavailable, using them will raise a NotImplementedError.
2852
2853[clinic start generated code]*/
2854
Larry Hastings2f936352014-08-05 14:04:04 +10002855static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002856os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002857 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002858/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002859{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002860 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002861
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002862#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002863 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002864#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002865
Larry Hastings9cf065c2012-06-22 16:30:09 -07002866#ifdef HAVE_FCHMODAT
2867 int fchmodat_nofollow_unsupported = 0;
2868#endif
2869
Larry Hastings9cf065c2012-06-22 16:30:09 -07002870#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2871 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002872 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002873#endif
2874
2875#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002876 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002877 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002878 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002879 result = 0;
2880 else {
2881 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002882 attr &= ~FILE_ATTRIBUTE_READONLY;
2883 else
2884 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002885 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002886 }
2887 Py_END_ALLOW_THREADS
2888
2889 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002890 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002891 }
2892#else /* MS_WINDOWS */
2893 Py_BEGIN_ALLOW_THREADS
2894#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002895 if (path->fd != -1)
2896 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002897 else
2898#endif
2899#ifdef HAVE_LCHMOD
2900 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002901 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002902 else
2903#endif
2904#ifdef HAVE_FCHMODAT
2905 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2906 /*
2907 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2908 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002909 * and then says it isn't implemented yet.
2910 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002911 *
2912 * Once it is supported, os.chmod will automatically
2913 * support dir_fd and follow_symlinks=False. (Hopefully.)
2914 * Until then, we need to be careful what exception we raise.
2915 */
Larry Hastings2f936352014-08-05 14:04:04 +10002916 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002917 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2918 /*
2919 * But wait! We can't throw the exception without allowing threads,
2920 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2921 */
2922 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002923 result &&
2924 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2925 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002926 }
2927 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002928#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002929 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002930 Py_END_ALLOW_THREADS
2931
2932 if (result) {
2933#ifdef HAVE_FCHMODAT
2934 if (fchmodat_nofollow_unsupported) {
2935 if (dir_fd != DEFAULT_DIR_FD)
2936 dir_fd_and_follow_symlinks_invalid("chmod",
2937 dir_fd, follow_symlinks);
2938 else
2939 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002940 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002941 }
2942 else
2943#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002944 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002945 }
2946#endif
2947
Larry Hastings2f936352014-08-05 14:04:04 +10002948 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002949}
2950
Larry Hastings9cf065c2012-06-22 16:30:09 -07002951
Christian Heimes4e30a842007-11-30 22:12:06 +00002952#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002953/*[clinic input]
2954os.fchmod
2955
2956 fd: int
2957 mode: int
2958
2959Change the access permissions of the file given by file descriptor fd.
2960
2961Equivalent to os.chmod(fd, mode).
2962[clinic start generated code]*/
2963
Larry Hastings2f936352014-08-05 14:04:04 +10002964static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002965os_fchmod_impl(PyObject *module, int fd, int mode)
2966/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002967{
2968 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002969 int async_err = 0;
2970
2971 do {
2972 Py_BEGIN_ALLOW_THREADS
2973 res = fchmod(fd, mode);
2974 Py_END_ALLOW_THREADS
2975 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2976 if (res != 0)
2977 return (!async_err) ? posix_error() : NULL;
2978
Victor Stinner8c62be82010-05-06 00:08:46 +00002979 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002980}
2981#endif /* HAVE_FCHMOD */
2982
Larry Hastings2f936352014-08-05 14:04:04 +10002983
Christian Heimes4e30a842007-11-30 22:12:06 +00002984#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002985/*[clinic input]
2986os.lchmod
2987
2988 path: path_t
2989 mode: int
2990
2991Change the access permissions of a file, without following symbolic links.
2992
2993If path is a symlink, this affects the link itself rather than the target.
2994Equivalent to chmod(path, mode, follow_symlinks=False)."
2995[clinic start generated code]*/
2996
Larry Hastings2f936352014-08-05 14:04:04 +10002997static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002998os_lchmod_impl(PyObject *module, path_t *path, int mode)
2999/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003000{
Victor Stinner8c62be82010-05-06 00:08:46 +00003001 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003002 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003003 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003004 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003005 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003006 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003007 return NULL;
3008 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003009 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003010}
3011#endif /* HAVE_LCHMOD */
3012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003013
Thomas Wouterscf297e42007-02-23 15:07:44 +00003014#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003015/*[clinic input]
3016os.chflags
3017
3018 path: path_t
3019 flags: unsigned_long(bitwise=True)
3020 follow_symlinks: bool=True
3021
3022Set file flags.
3023
3024If follow_symlinks is False, and the last element of the path is a symbolic
3025 link, chflags will change flags on the symbolic link itself instead of the
3026 file the link points to.
3027follow_symlinks may not be implemented on your platform. If it is
3028unavailable, using it will raise a NotImplementedError.
3029
3030[clinic start generated code]*/
3031
Larry Hastings2f936352014-08-05 14:04:04 +10003032static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003033os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003034 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003035/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003036{
3037 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003038
3039#ifndef HAVE_LCHFLAGS
3040 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003041 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003042#endif
3043
Victor Stinner8c62be82010-05-06 00:08:46 +00003044 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003045#ifdef HAVE_LCHFLAGS
3046 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003047 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003048 else
3049#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003050 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003051 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003052
Larry Hastings2f936352014-08-05 14:04:04 +10003053 if (result)
3054 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003055
Larry Hastings2f936352014-08-05 14:04:04 +10003056 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003057}
3058#endif /* HAVE_CHFLAGS */
3059
Larry Hastings2f936352014-08-05 14:04:04 +10003060
Thomas Wouterscf297e42007-02-23 15:07:44 +00003061#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003062/*[clinic input]
3063os.lchflags
3064
3065 path: path_t
3066 flags: unsigned_long(bitwise=True)
3067
3068Set file flags.
3069
3070This function will not follow symbolic links.
3071Equivalent to chflags(path, flags, follow_symlinks=False).
3072[clinic start generated code]*/
3073
Larry Hastings2f936352014-08-05 14:04:04 +10003074static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003075os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3076/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003077{
Victor Stinner8c62be82010-05-06 00:08:46 +00003078 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003079 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003080 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003081 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003082 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003083 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003084 }
Victor Stinner292c8352012-10-30 02:17:38 +01003085 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003086}
3087#endif /* HAVE_LCHFLAGS */
3088
Larry Hastings2f936352014-08-05 14:04:04 +10003089
Martin v. Löwis244edc82001-10-04 22:44:26 +00003090#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003091/*[clinic input]
3092os.chroot
3093 path: path_t
3094
3095Change root directory to path.
3096
3097[clinic start generated code]*/
3098
Larry Hastings2f936352014-08-05 14:04:04 +10003099static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003100os_chroot_impl(PyObject *module, path_t *path)
3101/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003102{
3103 int res;
3104 Py_BEGIN_ALLOW_THREADS
3105 res = chroot(path->narrow);
3106 Py_END_ALLOW_THREADS
3107 if (res < 0)
3108 return path_error(path);
3109 Py_RETURN_NONE;
3110}
3111#endif /* HAVE_CHROOT */
3112
Martin v. Löwis244edc82001-10-04 22:44:26 +00003113
Guido van Rossum21142a01999-01-08 21:05:37 +00003114#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003115/*[clinic input]
3116os.fsync
3117
3118 fd: fildes
3119
3120Force write of fd to disk.
3121[clinic start generated code]*/
3122
Larry Hastings2f936352014-08-05 14:04:04 +10003123static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003124os_fsync_impl(PyObject *module, int fd)
3125/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003126{
3127 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003128}
3129#endif /* HAVE_FSYNC */
3130
Larry Hastings2f936352014-08-05 14:04:04 +10003131
Ross Lagerwall7807c352011-03-17 20:20:30 +02003132#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003133/*[clinic input]
3134os.sync
3135
3136Force write of everything to disk.
3137[clinic start generated code]*/
3138
Larry Hastings2f936352014-08-05 14:04:04 +10003139static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003140os_sync_impl(PyObject *module)
3141/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003142{
3143 Py_BEGIN_ALLOW_THREADS
3144 sync();
3145 Py_END_ALLOW_THREADS
3146 Py_RETURN_NONE;
3147}
Larry Hastings2f936352014-08-05 14:04:04 +10003148#endif /* HAVE_SYNC */
3149
Ross Lagerwall7807c352011-03-17 20:20:30 +02003150
Guido van Rossum21142a01999-01-08 21:05:37 +00003151#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003152#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003153extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3154#endif
3155
Larry Hastings2f936352014-08-05 14:04:04 +10003156/*[clinic input]
3157os.fdatasync
3158
3159 fd: fildes
3160
3161Force write of fd to disk without forcing update of metadata.
3162[clinic start generated code]*/
3163
Larry Hastings2f936352014-08-05 14:04:04 +10003164static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003165os_fdatasync_impl(PyObject *module, int fd)
3166/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003167{
3168 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003169}
3170#endif /* HAVE_FDATASYNC */
3171
3172
Fredrik Lundh10723342000-07-10 16:38:09 +00003173#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003174/*[clinic input]
3175os.chown
3176
3177 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003178 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003179
3180 uid: uid_t
3181
3182 gid: gid_t
3183
3184 *
3185
3186 dir_fd : dir_fd(requires='fchownat') = None
3187 If not None, it should be a file descriptor open to a directory,
3188 and path should be relative; path will then be relative to that
3189 directory.
3190
3191 follow_symlinks: bool = True
3192 If False, and the last element of the path is a symbolic link,
3193 stat will examine the symbolic link itself instead of the file
3194 the link points to.
3195
3196Change the owner and group id of path to the numeric uid and gid.\
3197
3198path may always be specified as a string.
3199On some platforms, path may also be specified as an open file descriptor.
3200 If this functionality is unavailable, using it raises an exception.
3201If dir_fd is not None, it should be a file descriptor open to a directory,
3202 and path should be relative; path will then be relative to that directory.
3203If follow_symlinks is False, and the last element of the path is a symbolic
3204 link, chown will modify the symbolic link itself instead of the file the
3205 link points to.
3206It is an error to use dir_fd or follow_symlinks when specifying path as
3207 an open file descriptor.
3208dir_fd and follow_symlinks may not be implemented on your platform.
3209 If they are unavailable, using them will raise a NotImplementedError.
3210
3211[clinic start generated code]*/
3212
Larry Hastings2f936352014-08-05 14:04:04 +10003213static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003214os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003215 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003216/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003217{
3218 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003219
3220#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3221 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003222 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003223#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003224 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3225 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3226 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003227
3228#ifdef __APPLE__
3229 /*
3230 * This is for Mac OS X 10.3, which doesn't have lchown.
3231 * (But we still have an lchown symbol because of weak-linking.)
3232 * It doesn't have fchownat either. So there's no possibility
3233 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003234 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003235 if ((!follow_symlinks) && (lchown == NULL)) {
3236 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003237 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003238 }
3239#endif
3240
Victor Stinner8c62be82010-05-06 00:08:46 +00003241 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003242#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003243 if (path->fd != -1)
3244 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003245 else
3246#endif
3247#ifdef HAVE_LCHOWN
3248 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003249 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250 else
3251#endif
3252#ifdef HAVE_FCHOWNAT
3253 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003254 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003255 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3256 else
3257#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003258 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003259 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003260
Larry Hastings2f936352014-08-05 14:04:04 +10003261 if (result)
3262 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003263
Larry Hastings2f936352014-08-05 14:04:04 +10003264 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003265}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003266#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003267
Larry Hastings2f936352014-08-05 14:04:04 +10003268
Christian Heimes4e30a842007-11-30 22:12:06 +00003269#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003270/*[clinic input]
3271os.fchown
3272
3273 fd: int
3274 uid: uid_t
3275 gid: gid_t
3276
3277Change the owner and group id of the file specified by file descriptor.
3278
3279Equivalent to os.chown(fd, uid, gid).
3280
3281[clinic start generated code]*/
3282
Larry Hastings2f936352014-08-05 14:04:04 +10003283static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003284os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3285/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003286{
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003288 int async_err = 0;
3289
3290 do {
3291 Py_BEGIN_ALLOW_THREADS
3292 res = fchown(fd, uid, gid);
3293 Py_END_ALLOW_THREADS
3294 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3295 if (res != 0)
3296 return (!async_err) ? posix_error() : NULL;
3297
Victor Stinner8c62be82010-05-06 00:08:46 +00003298 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003299}
3300#endif /* HAVE_FCHOWN */
3301
Larry Hastings2f936352014-08-05 14:04:04 +10003302
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003303#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003304/*[clinic input]
3305os.lchown
3306
3307 path : path_t
3308 uid: uid_t
3309 gid: gid_t
3310
3311Change the owner and group id of path to the numeric uid and gid.
3312
3313This function will not follow symbolic links.
3314Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3315[clinic start generated code]*/
3316
Larry Hastings2f936352014-08-05 14:04:04 +10003317static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003318os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3319/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003320{
Victor Stinner8c62be82010-05-06 00:08:46 +00003321 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003322 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003323 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003324 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003325 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003326 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003327 }
Larry Hastings2f936352014-08-05 14:04:04 +10003328 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003329}
3330#endif /* HAVE_LCHOWN */
3331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003332
Barry Warsaw53699e91996-12-10 23:23:01 +00003333static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003334posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003335{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003336 char *buf, *tmpbuf;
3337 char *cwd;
3338 const size_t chunk = 1024;
3339 size_t buflen = 0;
3340 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003341
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003342#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003343 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003344 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003345 wchar_t *wbuf2 = wbuf;
3346 PyObject *resobj;
3347 DWORD len;
3348 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003349 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003350 /* If the buffer is large enough, len does not include the
3351 terminating \0. If the buffer is too small, len includes
3352 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003353 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003354 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003355 if (wbuf2)
3356 len = GetCurrentDirectoryW(len, wbuf2);
3357 }
3358 Py_END_ALLOW_THREADS
3359 if (!wbuf2) {
3360 PyErr_NoMemory();
3361 return NULL;
3362 }
3363 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003364 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003365 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003366 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003367 }
3368 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003369 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003370 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003371 return resobj;
3372 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003373
3374 if (win32_warn_bytes_api())
3375 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003376#endif
3377
Victor Stinner4403d7d2015-04-25 00:16:10 +02003378 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003379 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003380 do {
3381 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003382#ifdef MS_WINDOWS
3383 if (buflen > INT_MAX) {
3384 PyErr_NoMemory();
3385 break;
3386 }
3387#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003388 tmpbuf = PyMem_RawRealloc(buf, buflen);
3389 if (tmpbuf == NULL)
3390 break;
3391
3392 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003393#ifdef MS_WINDOWS
3394 cwd = getcwd(buf, (int)buflen);
3395#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003396 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003397#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003398 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003399 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003400
3401 if (cwd == NULL) {
3402 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003403 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003404 }
3405
Victor Stinner8c62be82010-05-06 00:08:46 +00003406 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003407 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3408 else
3409 obj = PyUnicode_DecodeFSDefault(buf);
3410 PyMem_RawFree(buf);
3411
3412 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003413}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003414
Larry Hastings2f936352014-08-05 14:04:04 +10003415
3416/*[clinic input]
3417os.getcwd
3418
3419Return a unicode string representing the current working directory.
3420[clinic start generated code]*/
3421
Larry Hastings2f936352014-08-05 14:04:04 +10003422static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003423os_getcwd_impl(PyObject *module)
3424/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003425{
3426 return posix_getcwd(0);
3427}
3428
Larry Hastings2f936352014-08-05 14:04:04 +10003429
3430/*[clinic input]
3431os.getcwdb
3432
3433Return a bytes string representing the current working directory.
3434[clinic start generated code]*/
3435
Larry Hastings2f936352014-08-05 14:04:04 +10003436static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003437os_getcwdb_impl(PyObject *module)
3438/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003439{
3440 return posix_getcwd(1);
3441}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003442
Larry Hastings2f936352014-08-05 14:04:04 +10003443
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3445#define HAVE_LINK 1
3446#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003447
Guido van Rossumb6775db1994-08-01 11:34:53 +00003448#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003449/*[clinic input]
3450
3451os.link
3452
3453 src : path_t
3454 dst : path_t
3455 *
3456 src_dir_fd : dir_fd = None
3457 dst_dir_fd : dir_fd = None
3458 follow_symlinks: bool = True
3459
3460Create a hard link to a file.
3461
3462If either src_dir_fd or dst_dir_fd is not None, it should be a file
3463 descriptor open to a directory, and the respective path string (src or dst)
3464 should be relative; the path will then be relative to that directory.
3465If follow_symlinks is False, and the last element of src is a symbolic
3466 link, link will create a link to the symbolic link itself instead of the
3467 file the link points to.
3468src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3469 platform. If they are unavailable, using them will raise a
3470 NotImplementedError.
3471[clinic start generated code]*/
3472
Larry Hastings2f936352014-08-05 14:04:04 +10003473static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003474os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003475 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003476/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003477{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003479 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003480#else
3481 int result;
3482#endif
3483
Larry Hastings9cf065c2012-06-22 16:30:09 -07003484#ifndef HAVE_LINKAT
3485 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3486 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003487 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003488 }
3489#endif
3490
Steve Dowercc16be82016-09-08 10:35:16 -07003491#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003492 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 PyErr_SetString(PyExc_NotImplementedError,
3494 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003495 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496 }
Steve Dowercc16be82016-09-08 10:35:16 -07003497#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003498
Brian Curtin1b9df392010-11-24 20:24:31 +00003499#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003500 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003501 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003503
Larry Hastings2f936352014-08-05 14:04:04 +10003504 if (!result)
3505 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506#else
3507 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003508#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003509 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3510 (dst_dir_fd != DEFAULT_DIR_FD) ||
3511 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003512 result = linkat(src_dir_fd, src->narrow,
3513 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003514 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3515 else
Steve Dowercc16be82016-09-08 10:35:16 -07003516#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003517 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003518 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003519
Larry Hastings2f936352014-08-05 14:04:04 +10003520 if (result)
3521 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003522#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003523
Larry Hastings2f936352014-08-05 14:04:04 +10003524 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003525}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526#endif
3527
Brian Curtin1b9df392010-11-24 20:24:31 +00003528
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003529#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003530static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003531_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003532{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003533 PyObject *v;
3534 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3535 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003536 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003538 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003539 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003540
Steve Dowercc16be82016-09-08 10:35:16 -07003541 WIN32_FIND_DATAW wFileData;
3542 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003543
Steve Dowercc16be82016-09-08 10:35:16 -07003544 if (!path->wide) { /* Default arg: "." */
3545 po_wchars = L".";
3546 len = 1;
3547 } else {
3548 po_wchars = path->wide;
3549 len = wcslen(path->wide);
3550 }
3551 /* The +5 is so we can append "\\*.*\0" */
3552 wnamebuf = PyMem_New(wchar_t, len + 5);
3553 if (!wnamebuf) {
3554 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003555 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003556 }
Steve Dowercc16be82016-09-08 10:35:16 -07003557 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003559 wchar_t wch = wnamebuf[len-1];
3560 if (wch != SEP && wch != ALTSEP && wch != L':')
3561 wnamebuf[len++] = SEP;
3562 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003563 }
Steve Dowercc16be82016-09-08 10:35:16 -07003564 if ((list = PyList_New(0)) == NULL) {
3565 goto exit;
3566 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003567 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003568 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003569 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003570 if (hFindFile == INVALID_HANDLE_VALUE) {
3571 int error = GetLastError();
3572 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573 goto exit;
3574 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003575 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003576 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 }
3578 do {
3579 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003580 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3581 wcscmp(wFileData.cFileName, L"..") != 0) {
3582 v = PyUnicode_FromWideChar(wFileData.cFileName,
3583 wcslen(wFileData.cFileName));
3584 if (path->narrow && v) {
3585 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3586 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003588 Py_DECREF(list);
3589 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 break;
3591 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003594 Py_DECREF(list);
3595 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003596 break;
3597 }
3598 Py_DECREF(v);
3599 }
3600 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003601 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 Py_END_ALLOW_THREADS
3603 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3604 it got to the end of the directory. */
3605 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003607 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003608 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003609 }
3610 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003611
Larry Hastings9cf065c2012-06-22 16:30:09 -07003612exit:
3613 if (hFindFile != INVALID_HANDLE_VALUE) {
3614 if (FindClose(hFindFile) == FALSE) {
3615 if (list != NULL) {
3616 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003617 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618 }
3619 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003620 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003621 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003622
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003624} /* end of _listdir_windows_no_opendir */
3625
3626#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3627
3628static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003629_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003630{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003631 PyObject *v;
3632 DIR *dirp = NULL;
3633 struct dirent *ep;
3634 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003635#ifdef HAVE_FDOPENDIR
3636 int fd = -1;
3637#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003638
Victor Stinner8c62be82010-05-06 00:08:46 +00003639 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003640#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003641 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003643 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003644 if (fd == -1)
3645 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003646
Larry Hastingsfdaea062012-06-25 04:42:23 -07003647 return_str = 1;
3648
Larry Hastings9cf065c2012-06-22 16:30:09 -07003649 Py_BEGIN_ALLOW_THREADS
3650 dirp = fdopendir(fd);
3651 Py_END_ALLOW_THREADS
3652 }
3653 else
3654#endif
3655 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003656 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003657 if (path->narrow) {
3658 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003659 /* only return bytes if they specified a bytes-like object */
3660 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003661 }
3662 else {
3663 name = ".";
3664 return_str = 1;
3665 }
3666
Larry Hastings9cf065c2012-06-22 16:30:09 -07003667 Py_BEGIN_ALLOW_THREADS
3668 dirp = opendir(name);
3669 Py_END_ALLOW_THREADS
3670 }
3671
3672 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003673 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003674#ifdef HAVE_FDOPENDIR
3675 if (fd != -1) {
3676 Py_BEGIN_ALLOW_THREADS
3677 close(fd);
3678 Py_END_ALLOW_THREADS
3679 }
3680#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003681 goto exit;
3682 }
3683 if ((list = PyList_New(0)) == NULL) {
3684 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003685 }
3686 for (;;) {
3687 errno = 0;
3688 Py_BEGIN_ALLOW_THREADS
3689 ep = readdir(dirp);
3690 Py_END_ALLOW_THREADS
3691 if (ep == NULL) {
3692 if (errno == 0) {
3693 break;
3694 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003695 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003696 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003697 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003698 }
3699 }
3700 if (ep->d_name[0] == '.' &&
3701 (NAMLEN(ep) == 1 ||
3702 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3703 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003704 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003705 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3706 else
3707 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003708 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003709 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003710 break;
3711 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003712 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003713 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003714 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003715 break;
3716 }
3717 Py_DECREF(v);
3718 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003719
Larry Hastings9cf065c2012-06-22 16:30:09 -07003720exit:
3721 if (dirp != NULL) {
3722 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003723#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003724 if (fd > -1)
3725 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003726#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003727 closedir(dirp);
3728 Py_END_ALLOW_THREADS
3729 }
3730
Larry Hastings9cf065c2012-06-22 16:30:09 -07003731 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003732} /* end of _posix_listdir */
3733#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003734
Larry Hastings2f936352014-08-05 14:04:04 +10003735
3736/*[clinic input]
3737os.listdir
3738
3739 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3740
3741Return a list containing the names of the files in the directory.
3742
BNMetricsb9427072018-11-02 15:20:19 +00003743path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003744 the filenames returned will also be bytes; in all other circumstances
3745 the filenames returned will be str.
3746If path is None, uses the path='.'.
3747On some platforms, path may also be specified as an open file descriptor;\
3748 the file descriptor must refer to a directory.
3749 If this functionality is unavailable, using it raises NotImplementedError.
3750
3751The list is in arbitrary order. It does not include the special
3752entries '.' and '..' even if they are present in the directory.
3753
3754
3755[clinic start generated code]*/
3756
Larry Hastings2f936352014-08-05 14:04:04 +10003757static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003758os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003759/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003760{
Miss Islington (bot)8763d432019-06-24 09:09:47 -07003761 if (PySys_Audit("os.listdir", "O",
3762 path->object ? path->object : Py_None) < 0) {
3763 return NULL;
3764 }
Larry Hastings2f936352014-08-05 14:04:04 +10003765#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3766 return _listdir_windows_no_opendir(path, NULL);
3767#else
3768 return _posix_listdir(path, NULL);
3769#endif
3770}
3771
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003772#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003773/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003774/*[clinic input]
3775os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003776
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003777 path: path_t
3778 /
3779
3780[clinic start generated code]*/
3781
3782static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003783os__getfullpathname_impl(PyObject *module, path_t *path)
3784/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003785{
Steve Dowercc16be82016-09-08 10:35:16 -07003786 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3787 wchar_t *wtemp;
3788 DWORD result;
3789 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003790
Steve Dowercc16be82016-09-08 10:35:16 -07003791 result = GetFullPathNameW(path->wide,
3792 Py_ARRAY_LENGTH(woutbuf),
3793 woutbuf, &wtemp);
3794 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3795 woutbufp = PyMem_New(wchar_t, result);
3796 if (!woutbufp)
3797 return PyErr_NoMemory();
3798 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003799 }
Steve Dowercc16be82016-09-08 10:35:16 -07003800 if (result) {
3801 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3802 if (path->narrow)
3803 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3804 } else
3805 v = win32_error_object("GetFullPathNameW", path->object);
3806 if (woutbufp != woutbuf)
3807 PyMem_Free(woutbufp);
3808 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003809}
Brian Curtind40e6f72010-07-08 21:39:08 +00003810
Brian Curtind25aef52011-06-13 15:16:04 -05003811
Larry Hastings2f936352014-08-05 14:04:04 +10003812/*[clinic input]
3813os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003814
Steve Dower23ad6d02018-02-22 10:39:10 -08003815 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003816 /
3817
3818A helper function for samepath on windows.
3819[clinic start generated code]*/
3820
Larry Hastings2f936352014-08-05 14:04:04 +10003821static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003822os__getfinalpathname_impl(PyObject *module, path_t *path)
3823/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003824{
3825 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003826 wchar_t buf[MAXPATHLEN], *target_path = buf;
3827 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003828 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003829 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003830
Steve Dower23ad6d02018-02-22 10:39:10 -08003831 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003832 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003833 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003834 0, /* desired access */
3835 0, /* share mode */
3836 NULL, /* security attributes */
3837 OPEN_EXISTING,
3838 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3839 FILE_FLAG_BACKUP_SEMANTICS,
3840 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003841 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003842
Steve Dower23ad6d02018-02-22 10:39:10 -08003843 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003844 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003845 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003846
3847 /* We have a good handle to the target, use it to determine the
3848 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003849 while (1) {
3850 Py_BEGIN_ALLOW_THREADS
3851 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3852 buf_size, VOLUME_NAME_DOS);
3853 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003854
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003855 if (!result_length) {
3856 result = win32_error_object("GetFinalPathNameByHandleW",
3857 path->object);
3858 goto cleanup;
3859 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003860
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003861 if (result_length < buf_size) {
3862 break;
3863 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003864
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003865 wchar_t *tmp;
3866 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3867 result_length * sizeof(*tmp));
3868 if (!tmp) {
3869 result = PyErr_NoMemory();
3870 goto cleanup;
3871 }
3872
3873 buf_size = result_length;
3874 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003875 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003876
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003877 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003878 if (path->narrow)
3879 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003880
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003881cleanup:
3882 if (target_path != buf) {
3883 PyMem_Free(target_path);
3884 }
3885 CloseHandle(hFile);
3886 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003887}
Brian Curtin62857742010-09-06 17:07:27 +00003888
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003889/*[clinic input]
3890os._isdir
3891
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003892 path as arg: object
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003893 /
3894
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003895Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003896[clinic start generated code]*/
3897
Brian Curtin9c669cc2011-06-08 18:17:18 -05003898static PyObject *
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003899os__isdir(PyObject *module, PyObject *arg)
3900/*[clinic end generated code: output=404f334d85d4bf25 input=36cb6785874d479e]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003901{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003902 DWORD attributes;
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003903 path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0);
3904
3905 if (!path_converter(arg, &path)) {
3906 if (PyErr_ExceptionMatches(PyExc_ValueError)) {
3907 PyErr_Clear();
3908 Py_RETURN_FALSE;
3909 }
3910 return NULL;
3911 }
Brian Curtin9c669cc2011-06-08 18:17:18 -05003912
Steve Dowerb22a6772016-07-17 20:49:38 -07003913 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003914 attributes = GetFileAttributesW(path.wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003915 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003916
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003917 path_cleanup(&path);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003918 if (attributes == INVALID_FILE_ATTRIBUTES)
3919 Py_RETURN_FALSE;
3920
Brian Curtin9c669cc2011-06-08 18:17:18 -05003921 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3922 Py_RETURN_TRUE;
3923 else
3924 Py_RETURN_FALSE;
3925}
Tim Golden6b528062013-08-01 12:44:00 +01003926
Tim Golden6b528062013-08-01 12:44:00 +01003927
Larry Hastings2f936352014-08-05 14:04:04 +10003928/*[clinic input]
3929os._getvolumepathname
3930
Steve Dower23ad6d02018-02-22 10:39:10 -08003931 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003932
3933A helper function for ismount on Win32.
3934[clinic start generated code]*/
3935
Larry Hastings2f936352014-08-05 14:04:04 +10003936static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003937os__getvolumepathname_impl(PyObject *module, path_t *path)
3938/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003939{
3940 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003941 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003942 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003943 BOOL ret;
3944
Tim Golden6b528062013-08-01 12:44:00 +01003945 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003946 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003947
Victor Stinner850a18e2017-10-24 16:53:32 -07003948 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003949 PyErr_SetString(PyExc_OverflowError, "path too long");
3950 return NULL;
3951 }
3952
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003953 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003954 if (mountpath == NULL)
3955 return PyErr_NoMemory();
3956
3957 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003958 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003959 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003960 Py_END_ALLOW_THREADS
3961
3962 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003963 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003964 goto exit;
3965 }
3966 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003967 if (path->narrow)
3968 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003969
3970exit:
3971 PyMem_Free(mountpath);
3972 return result;
3973}
Tim Golden6b528062013-08-01 12:44:00 +01003974
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003975#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003976
Larry Hastings2f936352014-08-05 14:04:04 +10003977
3978/*[clinic input]
3979os.mkdir
3980
3981 path : path_t
3982
3983 mode: int = 0o777
3984
3985 *
3986
3987 dir_fd : dir_fd(requires='mkdirat') = None
3988
3989# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3990
3991Create a directory.
3992
3993If dir_fd is not None, it should be a file descriptor open to a directory,
3994 and path should be relative; path will then be relative to that directory.
3995dir_fd may not be implemented on your platform.
3996 If it is unavailable, using it will raise a NotImplementedError.
3997
3998The mode argument is ignored on Windows.
3999[clinic start generated code]*/
4000
Larry Hastings2f936352014-08-05 14:04:04 +10004001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004002os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4003/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004004{
4005 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004006
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004007#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004008 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004009 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004010 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004011
Larry Hastings2f936352014-08-05 14:04:04 +10004012 if (!result)
4013 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004014#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004015 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004016#if HAVE_MKDIRAT
4017 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004018 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004019 else
4020#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004021#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004022 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004023#else
Larry Hastings2f936352014-08-05 14:04:04 +10004024 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004025#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004026 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004027 if (result < 0)
4028 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004029#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004030 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004031}
4032
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004033
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004034/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4035#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004036#include <sys/resource.h>
4037#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004038
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004039
4040#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004041/*[clinic input]
4042os.nice
4043
4044 increment: int
4045 /
4046
4047Add increment to the priority of process and return the new priority.
4048[clinic start generated code]*/
4049
Larry Hastings2f936352014-08-05 14:04:04 +10004050static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004051os_nice_impl(PyObject *module, int increment)
4052/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004053{
4054 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004055
Victor Stinner8c62be82010-05-06 00:08:46 +00004056 /* There are two flavours of 'nice': one that returns the new
4057 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004058 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004059 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004060
Victor Stinner8c62be82010-05-06 00:08:46 +00004061 If we are of the nice family that returns the new priority, we
4062 need to clear errno before the call, and check if errno is filled
4063 before calling posix_error() on a returnvalue of -1, because the
4064 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004065
Victor Stinner8c62be82010-05-06 00:08:46 +00004066 errno = 0;
4067 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004068#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004069 if (value == 0)
4070 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004071#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004072 if (value == -1 && errno != 0)
4073 /* either nice() or getpriority() returned an error */
4074 return posix_error();
4075 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004076}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004077#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004078
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004079
4080#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004081/*[clinic input]
4082os.getpriority
4083
4084 which: int
4085 who: int
4086
4087Return program scheduling priority.
4088[clinic start generated code]*/
4089
Larry Hastings2f936352014-08-05 14:04:04 +10004090static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004091os_getpriority_impl(PyObject *module, int which, int who)
4092/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004093{
4094 int retval;
4095
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004096 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004097 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004098 if (errno != 0)
4099 return posix_error();
4100 return PyLong_FromLong((long)retval);
4101}
4102#endif /* HAVE_GETPRIORITY */
4103
4104
4105#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004106/*[clinic input]
4107os.setpriority
4108
4109 which: int
4110 who: int
4111 priority: int
4112
4113Set program scheduling priority.
4114[clinic start generated code]*/
4115
Larry Hastings2f936352014-08-05 14:04:04 +10004116static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004117os_setpriority_impl(PyObject *module, int which, int who, int priority)
4118/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004119{
4120 int retval;
4121
4122 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004123 if (retval == -1)
4124 return posix_error();
4125 Py_RETURN_NONE;
4126}
4127#endif /* HAVE_SETPRIORITY */
4128
4129
Barry Warsaw53699e91996-12-10 23:23:01 +00004130static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004131internal_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 +00004132{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004133 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004135
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004136#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004137 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004138 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004139#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004140 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004141#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004142
Larry Hastings9cf065c2012-06-22 16:30:09 -07004143 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4144 (dst_dir_fd != DEFAULT_DIR_FD);
4145#ifndef HAVE_RENAMEAT
4146 if (dir_fd_specified) {
4147 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004148 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004149 }
4150#endif
4151
Larry Hastings9cf065c2012-06-22 16:30:09 -07004152#ifdef MS_WINDOWS
4153 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004154 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004155 Py_END_ALLOW_THREADS
4156
Larry Hastings2f936352014-08-05 14:04:04 +10004157 if (!result)
4158 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004159
4160#else
Steve Dowercc16be82016-09-08 10:35:16 -07004161 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4162 PyErr_Format(PyExc_ValueError,
4163 "%s: src and dst must be the same type", function_name);
4164 return NULL;
4165 }
4166
Larry Hastings9cf065c2012-06-22 16:30:09 -07004167 Py_BEGIN_ALLOW_THREADS
4168#ifdef HAVE_RENAMEAT
4169 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004170 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004171 else
4172#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004173 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004174 Py_END_ALLOW_THREADS
4175
Larry Hastings2f936352014-08-05 14:04:04 +10004176 if (result)
4177 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004178#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004179 Py_RETURN_NONE;
4180}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004181
Larry Hastings2f936352014-08-05 14:04:04 +10004182
4183/*[clinic input]
4184os.rename
4185
4186 src : path_t
4187 dst : path_t
4188 *
4189 src_dir_fd : dir_fd = None
4190 dst_dir_fd : dir_fd = None
4191
4192Rename a file or directory.
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.
4198 If they are unavailable, using them will raise a NotImplementedError.
4199[clinic start generated code]*/
4200
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004201static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004202os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004203 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004204/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004205{
Larry Hastings2f936352014-08-05 14:04:04 +10004206 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004207}
4208
Larry Hastings2f936352014-08-05 14:04:04 +10004209
4210/*[clinic input]
4211os.replace = os.rename
4212
4213Rename a file or directory, overwriting the destination.
4214
4215If either src_dir_fd or dst_dir_fd is not None, it should be a file
4216 descriptor open to a directory, and the respective path string (src or dst)
4217 should be relative; the path will then be relative to that directory.
4218src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004219 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004220[clinic start generated code]*/
4221
Larry Hastings2f936352014-08-05 14:04:04 +10004222static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004223os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4224 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004225/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004226{
4227 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4228}
4229
4230
4231/*[clinic input]
4232os.rmdir
4233
4234 path: path_t
4235 *
4236 dir_fd: dir_fd(requires='unlinkat') = None
4237
4238Remove a directory.
4239
4240If dir_fd is not None, it should be a file descriptor open to a directory,
4241 and path should be relative; path will then be relative to that directory.
4242dir_fd may not be implemented on your platform.
4243 If it is unavailable, using it will raise a NotImplementedError.
4244[clinic start generated code]*/
4245
Larry Hastings2f936352014-08-05 14:04:04 +10004246static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004247os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4248/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004249{
4250 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004251
4252 Py_BEGIN_ALLOW_THREADS
4253#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004254 /* Windows, success=1, UNIX, success=0 */
4255 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004256#else
4257#ifdef HAVE_UNLINKAT
4258 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004259 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004260 else
4261#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004262 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004263#endif
4264 Py_END_ALLOW_THREADS
4265
Larry Hastings2f936352014-08-05 14:04:04 +10004266 if (result)
4267 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004268
Larry Hastings2f936352014-08-05 14:04:04 +10004269 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004270}
4271
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004272
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004273#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004274#ifdef MS_WINDOWS
4275/*[clinic input]
4276os.system -> long
4277
4278 command: Py_UNICODE
4279
4280Execute the command in a subshell.
4281[clinic start generated code]*/
4282
Larry Hastings2f936352014-08-05 14:04:04 +10004283static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004284os_system_impl(PyObject *module, const Py_UNICODE *command)
4285/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004286{
4287 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004288
4289 if (PySys_Audit("system", "(u)", command) < 0) {
4290 return -1;
4291 }
4292
Victor Stinner8c62be82010-05-06 00:08:46 +00004293 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004294 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004295 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004296 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004297 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004298 return result;
4299}
4300#else /* MS_WINDOWS */
4301/*[clinic input]
4302os.system -> long
4303
4304 command: FSConverter
4305
4306Execute the command in a subshell.
4307[clinic start generated code]*/
4308
Larry Hastings2f936352014-08-05 14:04:04 +10004309static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004310os_system_impl(PyObject *module, PyObject *command)
4311/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004312{
4313 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004314 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004315
4316 if (PySys_Audit("system", "(O)", command) < 0) {
4317 return -1;
4318 }
4319
Larry Hastings2f936352014-08-05 14:04:04 +10004320 Py_BEGIN_ALLOW_THREADS
4321 result = system(bytes);
4322 Py_END_ALLOW_THREADS
4323 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004324}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004325#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004326#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004328
Larry Hastings2f936352014-08-05 14:04:04 +10004329/*[clinic input]
4330os.umask
4331
4332 mask: int
4333 /
4334
4335Set the current numeric umask and return the previous umask.
4336[clinic start generated code]*/
4337
Larry Hastings2f936352014-08-05 14:04:04 +10004338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004339os_umask_impl(PyObject *module, int mask)
4340/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004341{
4342 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004343 if (i < 0)
4344 return posix_error();
4345 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004346}
4347
Brian Curtind40e6f72010-07-08 21:39:08 +00004348#ifdef MS_WINDOWS
4349
4350/* override the default DeleteFileW behavior so that directory
4351symlinks can be removed with this function, the same as with
4352Unix symlinks */
4353BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4354{
4355 WIN32_FILE_ATTRIBUTE_DATA info;
4356 WIN32_FIND_DATAW find_data;
4357 HANDLE find_data_handle;
4358 int is_directory = 0;
4359 int is_link = 0;
4360
4361 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4362 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004363
Brian Curtind40e6f72010-07-08 21:39:08 +00004364 /* Get WIN32_FIND_DATA structure for the path to determine if
4365 it is a symlink */
4366 if(is_directory &&
4367 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4368 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4369
4370 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004371 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4372 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4373 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4374 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004375 FindClose(find_data_handle);
4376 }
4377 }
4378 }
4379
4380 if (is_directory && is_link)
4381 return RemoveDirectoryW(lpFileName);
4382
4383 return DeleteFileW(lpFileName);
4384}
4385#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004387
Larry Hastings2f936352014-08-05 14:04:04 +10004388/*[clinic input]
4389os.unlink
4390
4391 path: path_t
4392 *
4393 dir_fd: dir_fd(requires='unlinkat')=None
4394
4395Remove a file (same as remove()).
4396
4397If dir_fd is not None, it should be a file descriptor open to a directory,
4398 and path should be relative; path will then be relative to that directory.
4399dir_fd may not be implemented on your platform.
4400 If it is unavailable, using it will raise a NotImplementedError.
4401
4402[clinic start generated code]*/
4403
Larry Hastings2f936352014-08-05 14:04:04 +10004404static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004405os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4406/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004407{
4408 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004409
4410 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004411 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004412#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004413 /* Windows, success=1, UNIX, success=0 */
4414 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004415#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004416#ifdef HAVE_UNLINKAT
4417 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004418 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004419 else
4420#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004421 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004422#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004423 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004424 Py_END_ALLOW_THREADS
4425
Larry Hastings2f936352014-08-05 14:04:04 +10004426 if (result)
4427 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004428
Larry Hastings2f936352014-08-05 14:04:04 +10004429 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004430}
4431
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004432
Larry Hastings2f936352014-08-05 14:04:04 +10004433/*[clinic input]
4434os.remove = os.unlink
4435
4436Remove a file (same as unlink()).
4437
4438If dir_fd is not None, it should be a file descriptor open to a directory,
4439 and path should be relative; path will then be relative to that directory.
4440dir_fd may not be implemented on your platform.
4441 If it is unavailable, using it will raise a NotImplementedError.
4442[clinic start generated code]*/
4443
Larry Hastings2f936352014-08-05 14:04:04 +10004444static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004445os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4446/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004447{
4448 return os_unlink_impl(module, path, dir_fd);
4449}
4450
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004451
Larry Hastings605a62d2012-06-24 04:33:36 -07004452static PyStructSequence_Field uname_result_fields[] = {
4453 {"sysname", "operating system name"},
4454 {"nodename", "name of machine on network (implementation-defined)"},
4455 {"release", "operating system release"},
4456 {"version", "operating system version"},
4457 {"machine", "hardware identifier"},
4458 {NULL}
4459};
4460
4461PyDoc_STRVAR(uname_result__doc__,
4462"uname_result: Result from os.uname().\n\n\
4463This object may be accessed either as a tuple of\n\
4464 (sysname, nodename, release, version, machine),\n\
4465or via the attributes sysname, nodename, release, version, and machine.\n\
4466\n\
4467See os.uname for more information.");
4468
4469static PyStructSequence_Desc uname_result_desc = {
4470 "uname_result", /* name */
4471 uname_result__doc__, /* doc */
4472 uname_result_fields,
4473 5
4474};
4475
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004476static PyTypeObject* UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07004477
4478
4479#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004480/*[clinic input]
4481os.uname
4482
4483Return an object identifying the current operating system.
4484
4485The object behaves like a named tuple with the following fields:
4486 (sysname, nodename, release, version, machine)
4487
4488[clinic start generated code]*/
4489
Larry Hastings2f936352014-08-05 14:04:04 +10004490static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004491os_uname_impl(PyObject *module)
4492/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004493{
Victor Stinner8c62be82010-05-06 00:08:46 +00004494 struct utsname u;
4495 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004496 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004497
Victor Stinner8c62be82010-05-06 00:08:46 +00004498 Py_BEGIN_ALLOW_THREADS
4499 res = uname(&u);
4500 Py_END_ALLOW_THREADS
4501 if (res < 0)
4502 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004503
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004504 value = PyStructSequence_New(UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004505 if (value == NULL)
4506 return NULL;
4507
4508#define SET(i, field) \
4509 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004510 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004511 if (!o) { \
4512 Py_DECREF(value); \
4513 return NULL; \
4514 } \
4515 PyStructSequence_SET_ITEM(value, i, o); \
4516 } \
4517
4518 SET(0, u.sysname);
4519 SET(1, u.nodename);
4520 SET(2, u.release);
4521 SET(3, u.version);
4522 SET(4, u.machine);
4523
4524#undef SET
4525
4526 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004527}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004528#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004529
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004530
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531
4532typedef struct {
4533 int now;
4534 time_t atime_s;
4535 long atime_ns;
4536 time_t mtime_s;
4537 long mtime_ns;
4538} utime_t;
4539
4540/*
Victor Stinner484df002014-10-09 13:52:31 +02004541 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542 * they also intentionally leak the declaration of a pointer named "time"
4543 */
4544#define UTIME_TO_TIMESPEC \
4545 struct timespec ts[2]; \
4546 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004547 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004548 time = NULL; \
4549 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004550 ts[0].tv_sec = ut->atime_s; \
4551 ts[0].tv_nsec = ut->atime_ns; \
4552 ts[1].tv_sec = ut->mtime_s; \
4553 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004554 time = ts; \
4555 } \
4556
4557#define UTIME_TO_TIMEVAL \
4558 struct timeval tv[2]; \
4559 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004560 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004561 time = NULL; \
4562 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004563 tv[0].tv_sec = ut->atime_s; \
4564 tv[0].tv_usec = ut->atime_ns / 1000; \
4565 tv[1].tv_sec = ut->mtime_s; \
4566 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004567 time = tv; \
4568 } \
4569
4570#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004571 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004573 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574 time = NULL; \
4575 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004576 u.actime = ut->atime_s; \
4577 u.modtime = ut->mtime_s; \
4578 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004579 }
4580
4581#define UTIME_TO_TIME_T \
4582 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004583 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004584 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004585 time = NULL; \
4586 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004587 timet[0] = ut->atime_s; \
4588 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004589 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590 } \
4591
4592
Victor Stinner528a9ab2015-09-03 21:30:26 +02004593#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004594
4595static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004596utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004597{
4598#ifdef HAVE_UTIMENSAT
4599 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4600 UTIME_TO_TIMESPEC;
4601 return utimensat(dir_fd, path, time, flags);
4602#elif defined(HAVE_FUTIMESAT)
4603 UTIME_TO_TIMEVAL;
4604 /*
4605 * follow_symlinks will never be false here;
4606 * we only allow !follow_symlinks and dir_fd together
4607 * if we have utimensat()
4608 */
4609 assert(follow_symlinks);
4610 return futimesat(dir_fd, path, time);
4611#endif
4612}
4613
Larry Hastings2f936352014-08-05 14:04:04 +10004614 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4615#else
4616 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004617#endif
4618
Victor Stinner528a9ab2015-09-03 21:30:26 +02004619#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004620
4621static int
Victor Stinner484df002014-10-09 13:52:31 +02004622utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004623{
4624#ifdef HAVE_FUTIMENS
4625 UTIME_TO_TIMESPEC;
4626 return futimens(fd, time);
4627#else
4628 UTIME_TO_TIMEVAL;
4629 return futimes(fd, time);
4630#endif
4631}
4632
Larry Hastings2f936352014-08-05 14:04:04 +10004633 #define PATH_UTIME_HAVE_FD 1
4634#else
4635 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004636#endif
4637
Victor Stinner5ebae872015-09-22 01:29:33 +02004638#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4639# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4640#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641
Victor Stinner4552ced2015-09-21 22:37:15 +02004642#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004643
4644static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004645utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004646{
4647#ifdef HAVE_UTIMENSAT
4648 UTIME_TO_TIMESPEC;
4649 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4650#else
4651 UTIME_TO_TIMEVAL;
4652 return lutimes(path, time);
4653#endif
4654}
4655
4656#endif
4657
4658#ifndef MS_WINDOWS
4659
4660static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004661utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004662{
4663#ifdef HAVE_UTIMENSAT
4664 UTIME_TO_TIMESPEC;
4665 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4666#elif defined(HAVE_UTIMES)
4667 UTIME_TO_TIMEVAL;
4668 return utimes(path, time);
4669#elif defined(HAVE_UTIME_H)
4670 UTIME_TO_UTIMBUF;
4671 return utime(path, time);
4672#else
4673 UTIME_TO_TIME_T;
4674 return utime(path, time);
4675#endif
4676}
4677
4678#endif
4679
Larry Hastings76ad59b2012-05-03 00:30:07 -07004680static int
4681split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4682{
4683 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004684 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004685 divmod = PyNumber_Divmod(py_long, billion);
4686 if (!divmod)
4687 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004688 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4689 PyErr_Format(PyExc_TypeError,
4690 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4691 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4692 goto exit;
4693 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004694 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4695 if ((*s == -1) && PyErr_Occurred())
4696 goto exit;
4697 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004698 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004699 goto exit;
4700
4701 result = 1;
4702exit:
4703 Py_XDECREF(divmod);
4704 return result;
4705}
4706
Larry Hastings2f936352014-08-05 14:04:04 +10004707
4708/*[clinic input]
4709os.utime
4710
4711 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4712 times: object = NULL
4713 *
4714 ns: object = NULL
4715 dir_fd: dir_fd(requires='futimensat') = None
4716 follow_symlinks: bool=True
4717
Martin Panter0ff89092015-09-09 01:56:53 +00004718# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004719
4720Set the access and modified time of path.
4721
4722path may always be specified as a string.
4723On some platforms, path may also be specified as an open file descriptor.
4724 If this functionality is unavailable, using it raises an exception.
4725
4726If times is not None, it must be a tuple (atime, mtime);
4727 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004728If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004729 atime_ns and mtime_ns should be expressed as integer nanoseconds
4730 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004731If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004732Specifying tuples for both times and ns is an error.
4733
4734If dir_fd is not None, it should be a file descriptor open to a directory,
4735 and path should be relative; path will then be relative to that directory.
4736If follow_symlinks is False, and the last element of the path is a symbolic
4737 link, utime will modify the symbolic link itself instead of the file the
4738 link points to.
4739It is an error to use dir_fd or follow_symlinks when specifying path
4740 as an open file descriptor.
4741dir_fd and follow_symlinks may not be available on your platform.
4742 If they are unavailable, using them will raise a NotImplementedError.
4743
4744[clinic start generated code]*/
4745
Larry Hastings2f936352014-08-05 14:04:04 +10004746static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004747os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4748 int dir_fd, int follow_symlinks)
4749/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004750{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004751#ifdef MS_WINDOWS
4752 HANDLE hFile;
4753 FILETIME atime, mtime;
4754#else
4755 int result;
4756#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004757
Larry Hastings2f936352014-08-05 14:04:04 +10004758 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004759
Christian Heimesb3c87242013-08-01 00:08:16 +02004760 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004761
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762 if (times && (times != Py_None) && ns) {
4763 PyErr_SetString(PyExc_ValueError,
4764 "utime: you may specify either 'times'"
4765 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004766 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004767 }
4768
4769 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004770 time_t a_sec, m_sec;
4771 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004772 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004773 PyErr_SetString(PyExc_TypeError,
4774 "utime: 'times' must be either"
4775 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004776 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004777 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004778 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004779 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004780 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004781 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004782 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004783 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004784 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004785 utime.atime_s = a_sec;
4786 utime.atime_ns = a_nsec;
4787 utime.mtime_s = m_sec;
4788 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004789 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004790 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004791 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004792 PyErr_SetString(PyExc_TypeError,
4793 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004794 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004795 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004796 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004797 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004798 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004799 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004800 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004801 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004802 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004803 }
4804 else {
4805 /* times and ns are both None/unspecified. use "now". */
4806 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004807 }
4808
Victor Stinner4552ced2015-09-21 22:37:15 +02004809#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004810 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004811 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004812#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004813
Larry Hastings2f936352014-08-05 14:04:04 +10004814 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4815 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4816 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004817 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004818
Larry Hastings9cf065c2012-06-22 16:30:09 -07004819#if !defined(HAVE_UTIMENSAT)
4820 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004821 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004822 "utime: cannot use dir_fd and follow_symlinks "
4823 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004824 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004825 }
4826#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004827
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004828#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004829 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004830 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4831 NULL, OPEN_EXISTING,
4832 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004833 Py_END_ALLOW_THREADS
4834 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004835 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004836 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004837 }
4838
Larry Hastings9cf065c2012-06-22 16:30:09 -07004839 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004840 GetSystemTimeAsFileTime(&mtime);
4841 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004843 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004844 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4845 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004846 }
4847 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4848 /* Avoid putting the file name into the error here,
4849 as that may confuse the user into believing that
4850 something is wrong with the file, when it also
4851 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004852 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004853 CloseHandle(hFile);
4854 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004855 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004856 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004857#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004858 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004859
Victor Stinner4552ced2015-09-21 22:37:15 +02004860#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004861 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004862 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004863 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004864#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004865
Victor Stinner528a9ab2015-09-03 21:30:26 +02004866#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004867 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004868 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004869 else
4870#endif
4871
Victor Stinner528a9ab2015-09-03 21:30:26 +02004872#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004873 if (path->fd != -1)
4874 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004875 else
4876#endif
4877
Larry Hastings2f936352014-08-05 14:04:04 +10004878 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004879
4880 Py_END_ALLOW_THREADS
4881
4882 if (result < 0) {
4883 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004884 posix_error();
4885 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004886 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004887
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004888#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004889
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004890 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004891}
4892
Guido van Rossum3b066191991-06-04 19:40:25 +00004893/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004894
Larry Hastings2f936352014-08-05 14:04:04 +10004895
4896/*[clinic input]
4897os._exit
4898
4899 status: int
4900
4901Exit to the system with specified status, without normal exit processing.
4902[clinic start generated code]*/
4903
Larry Hastings2f936352014-08-05 14:04:04 +10004904static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004905os__exit_impl(PyObject *module, int status)
4906/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004907{
4908 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004910}
4911
Steve Dowercc16be82016-09-08 10:35:16 -07004912#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4913#define EXECV_CHAR wchar_t
4914#else
4915#define EXECV_CHAR char
4916#endif
4917
pxinwrf2d7ac72019-05-21 18:46:37 +08004918#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004919static void
Steve Dowercc16be82016-09-08 10:35:16 -07004920free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004921{
Victor Stinner8c62be82010-05-06 00:08:46 +00004922 Py_ssize_t i;
4923 for (i = 0; i < count; i++)
4924 PyMem_Free(array[i]);
4925 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004926}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004927
Berker Peksag81816462016-09-15 20:19:47 +03004928static int
4929fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004930{
Victor Stinner8c62be82010-05-06 00:08:46 +00004931 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004932 PyObject *ub;
4933 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004934#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004935 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004936 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004937 *out = PyUnicode_AsWideCharString(ub, &size);
4938 if (*out)
4939 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004940#else
Berker Peksag81816462016-09-15 20:19:47 +03004941 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004943 size = PyBytes_GET_SIZE(ub);
4944 *out = PyMem_Malloc(size + 1);
4945 if (*out) {
4946 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4947 result = 1;
4948 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004949 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004950#endif
Berker Peksag81816462016-09-15 20:19:47 +03004951 Py_DECREF(ub);
4952 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004953}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004954#endif
4955
pxinwrf2d7ac72019-05-21 18:46:37 +08004956#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07004957static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004958parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4959{
Victor Stinner8c62be82010-05-06 00:08:46 +00004960 Py_ssize_t i, pos, envc;
4961 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004962 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004963 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004964
Victor Stinner8c62be82010-05-06 00:08:46 +00004965 i = PyMapping_Size(env);
4966 if (i < 0)
4967 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004968 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 if (envlist == NULL) {
4970 PyErr_NoMemory();
4971 return NULL;
4972 }
4973 envc = 0;
4974 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004975 if (!keys)
4976 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004978 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004979 goto error;
4980 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4981 PyErr_Format(PyExc_TypeError,
4982 "env.keys() or env.values() is not a list");
4983 goto error;
4984 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004985
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 for (pos = 0; pos < i; pos++) {
4987 key = PyList_GetItem(keys, pos);
4988 val = PyList_GetItem(vals, pos);
4989 if (!key || !val)
4990 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004991
Berker Peksag81816462016-09-15 20:19:47 +03004992#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4993 if (!PyUnicode_FSDecoder(key, &key2))
4994 goto error;
4995 if (!PyUnicode_FSDecoder(val, &val2)) {
4996 Py_DECREF(key2);
4997 goto error;
4998 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004999 /* Search from index 1 because on Windows starting '=' is allowed for
5000 defining hidden environment variables. */
5001 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5002 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5003 {
5004 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005005 Py_DECREF(key2);
5006 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005007 goto error;
5008 }
Berker Peksag81816462016-09-15 20:19:47 +03005009 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5010#else
5011 if (!PyUnicode_FSConverter(key, &key2))
5012 goto error;
5013 if (!PyUnicode_FSConverter(val, &val2)) {
5014 Py_DECREF(key2);
5015 goto error;
5016 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005017 if (PyBytes_GET_SIZE(key2) == 0 ||
5018 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5019 {
5020 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005021 Py_DECREF(key2);
5022 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005023 goto error;
5024 }
Berker Peksag81816462016-09-15 20:19:47 +03005025 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5026 PyBytes_AS_STRING(val2));
5027#endif
5028 Py_DECREF(key2);
5029 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005030 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005031 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005032
5033 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5034 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005035 goto error;
5036 }
Berker Peksag81816462016-09-15 20:19:47 +03005037
Steve Dowercc16be82016-09-08 10:35:16 -07005038 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005039 }
5040 Py_DECREF(vals);
5041 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005042
Victor Stinner8c62be82010-05-06 00:08:46 +00005043 envlist[envc] = 0;
5044 *envc_ptr = envc;
5045 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005046
5047error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005048 Py_XDECREF(keys);
5049 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005050 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005051 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005052}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005053
Steve Dowercc16be82016-09-08 10:35:16 -07005054static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005055parse_arglist(PyObject* argv, Py_ssize_t *argc)
5056{
5057 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005058 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005059 if (argvlist == NULL) {
5060 PyErr_NoMemory();
5061 return NULL;
5062 }
5063 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005064 PyObject* item = PySequence_ITEM(argv, i);
5065 if (item == NULL)
5066 goto fail;
5067 if (!fsconvert_strdup(item, &argvlist[i])) {
5068 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005069 goto fail;
5070 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005071 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005072 }
5073 argvlist[*argc] = NULL;
5074 return argvlist;
5075fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005076 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005077 free_string_array(argvlist, *argc);
5078 return NULL;
5079}
Steve Dowercc16be82016-09-08 10:35:16 -07005080
Ross Lagerwall7807c352011-03-17 20:20:30 +02005081#endif
5082
Larry Hastings2f936352014-08-05 14:04:04 +10005083
Ross Lagerwall7807c352011-03-17 20:20:30 +02005084#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005085/*[clinic input]
5086os.execv
5087
Steve Dowercc16be82016-09-08 10:35:16 -07005088 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005089 Path of executable file.
5090 argv: object
5091 Tuple or list of strings.
5092 /
5093
5094Execute an executable path with arguments, replacing current process.
5095[clinic start generated code]*/
5096
Larry Hastings2f936352014-08-05 14:04:04 +10005097static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005098os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5099/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005100{
Steve Dowercc16be82016-09-08 10:35:16 -07005101 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005102 Py_ssize_t argc;
5103
5104 /* execv has two arguments: (path, argv), where
5105 argv is a list or tuple of strings. */
5106
Ross Lagerwall7807c352011-03-17 20:20:30 +02005107 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5108 PyErr_SetString(PyExc_TypeError,
5109 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005110 return NULL;
5111 }
5112 argc = PySequence_Size(argv);
5113 if (argc < 1) {
5114 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005115 return NULL;
5116 }
5117
5118 argvlist = parse_arglist(argv, &argc);
5119 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005120 return NULL;
5121 }
Steve Dowerbce26262016-11-19 19:17:26 -08005122 if (!argvlist[0][0]) {
5123 PyErr_SetString(PyExc_ValueError,
5124 "execv() arg 2 first element cannot be empty");
5125 free_string_array(argvlist, argc);
5126 return NULL;
5127 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005128
Steve Dowerbce26262016-11-19 19:17:26 -08005129 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005130#ifdef HAVE_WEXECV
5131 _wexecv(path->wide, argvlist);
5132#else
5133 execv(path->narrow, argvlist);
5134#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005135 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005136
5137 /* If we get here it's definitely an error */
5138
5139 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005140 return posix_error();
5141}
5142
Larry Hastings2f936352014-08-05 14:04:04 +10005143
5144/*[clinic input]
5145os.execve
5146
5147 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5148 Path of executable file.
5149 argv: object
5150 Tuple or list of strings.
5151 env: object
5152 Dictionary of strings mapping to strings.
5153
5154Execute an executable path with arguments, replacing current process.
5155[clinic start generated code]*/
5156
Larry Hastings2f936352014-08-05 14:04:04 +10005157static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005158os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5159/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005160{
Steve Dowercc16be82016-09-08 10:35:16 -07005161 EXECV_CHAR **argvlist = NULL;
5162 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005163 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005164
Victor Stinner8c62be82010-05-06 00:08:46 +00005165 /* execve has three arguments: (path, argv, env), where
5166 argv is a list or tuple of strings and env is a dictionary
5167 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005168
Ross Lagerwall7807c352011-03-17 20:20:30 +02005169 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005170 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005171 "execve: argv must be a tuple or list");
5172 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005173 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005174 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005175 if (argc < 1) {
5176 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5177 return NULL;
5178 }
5179
Victor Stinner8c62be82010-05-06 00:08:46 +00005180 if (!PyMapping_Check(env)) {
5181 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005182 "execve: environment must be a mapping object");
5183 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005184 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005185
Ross Lagerwall7807c352011-03-17 20:20:30 +02005186 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005187 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005188 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005189 }
Steve Dowerbce26262016-11-19 19:17:26 -08005190 if (!argvlist[0][0]) {
5191 PyErr_SetString(PyExc_ValueError,
5192 "execve: argv first element cannot be empty");
5193 goto fail;
5194 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005195
Victor Stinner8c62be82010-05-06 00:08:46 +00005196 envlist = parse_envlist(env, &envc);
5197 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005198 goto fail;
5199
Steve Dowerbce26262016-11-19 19:17:26 -08005200 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005201#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005202 if (path->fd > -1)
5203 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005204 else
5205#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005206#ifdef HAVE_WEXECV
5207 _wexecve(path->wide, argvlist, envlist);
5208#else
Larry Hastings2f936352014-08-05 14:04:04 +10005209 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005210#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005211 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005212
5213 /* If we get here it's definitely an error */
5214
Alexey Izbyshev83460312018-10-20 03:28:22 +03005215 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005216
Steve Dowercc16be82016-09-08 10:35:16 -07005217 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005218 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005219 if (argvlist)
5220 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005221 return NULL;
5222}
Steve Dowercc16be82016-09-08 10:35:16 -07005223
Larry Hastings9cf065c2012-06-22 16:30:09 -07005224#endif /* HAVE_EXECV */
5225
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005226#ifdef HAVE_POSIX_SPAWN
5227
5228enum posix_spawn_file_actions_identifier {
5229 POSIX_SPAWN_OPEN,
5230 POSIX_SPAWN_CLOSE,
5231 POSIX_SPAWN_DUP2
5232};
5233
William Orr81574b82018-10-01 22:19:56 -07005234#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005235static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005236convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005237#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005238
5239static int
Victor Stinner325e4ba2019-02-01 15:47:24 +01005240parse_posix_spawn_flags(const char *func_name, PyObject *setpgroup,
5241 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005242 PyObject *setsigdef, PyObject *scheduler,
5243 posix_spawnattr_t *attrp)
5244{
5245 long all_flags = 0;
5246
5247 errno = posix_spawnattr_init(attrp);
5248 if (errno) {
5249 posix_error();
5250 return -1;
5251 }
5252
5253 if (setpgroup) {
5254 pid_t pgid = PyLong_AsPid(setpgroup);
5255 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5256 goto fail;
5257 }
5258 errno = posix_spawnattr_setpgroup(attrp, pgid);
5259 if (errno) {
5260 posix_error();
5261 goto fail;
5262 }
5263 all_flags |= POSIX_SPAWN_SETPGROUP;
5264 }
5265
5266 if (resetids) {
5267 all_flags |= POSIX_SPAWN_RESETIDS;
5268 }
5269
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005270 if (setsid) {
5271#ifdef POSIX_SPAWN_SETSID
5272 all_flags |= POSIX_SPAWN_SETSID;
5273#elif defined(POSIX_SPAWN_SETSID_NP)
5274 all_flags |= POSIX_SPAWN_SETSID_NP;
5275#else
5276 argument_unavailable_error(func_name, "setsid");
5277 return -1;
5278#endif
5279 }
5280
Pablo Galindo254a4662018-09-07 16:44:24 +01005281 if (setsigmask) {
5282 sigset_t set;
5283 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5284 goto fail;
5285 }
5286 errno = posix_spawnattr_setsigmask(attrp, &set);
5287 if (errno) {
5288 posix_error();
5289 goto fail;
5290 }
5291 all_flags |= POSIX_SPAWN_SETSIGMASK;
5292 }
5293
5294 if (setsigdef) {
5295 sigset_t set;
5296 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5297 goto fail;
5298 }
5299 errno = posix_spawnattr_setsigdefault(attrp, &set);
5300 if (errno) {
5301 posix_error();
5302 goto fail;
5303 }
5304 all_flags |= POSIX_SPAWN_SETSIGDEF;
5305 }
5306
5307 if (scheduler) {
5308#ifdef POSIX_SPAWN_SETSCHEDULER
5309 PyObject *py_schedpolicy;
5310 struct sched_param schedparam;
5311
5312 if (!PyArg_ParseTuple(scheduler, "OO&"
5313 ";A scheduler tuple must have two elements",
5314 &py_schedpolicy, convert_sched_param, &schedparam)) {
5315 goto fail;
5316 }
5317 if (py_schedpolicy != Py_None) {
5318 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5319
5320 if (schedpolicy == -1 && PyErr_Occurred()) {
5321 goto fail;
5322 }
5323 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5324 if (errno) {
5325 posix_error();
5326 goto fail;
5327 }
5328 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5329 }
5330 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5331 if (errno) {
5332 posix_error();
5333 goto fail;
5334 }
5335 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5336#else
5337 PyErr_SetString(PyExc_NotImplementedError,
5338 "The scheduler option is not supported in this system.");
5339 goto fail;
5340#endif
5341 }
5342
5343 errno = posix_spawnattr_setflags(attrp, all_flags);
5344 if (errno) {
5345 posix_error();
5346 goto fail;
5347 }
5348
5349 return 0;
5350
5351fail:
5352 (void)posix_spawnattr_destroy(attrp);
5353 return -1;
5354}
5355
5356static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005357parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005358 posix_spawn_file_actions_t *file_actionsp,
5359 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005360{
5361 PyObject *seq;
5362 PyObject *file_action = NULL;
5363 PyObject *tag_obj;
5364
5365 seq = PySequence_Fast(file_actions,
5366 "file_actions must be a sequence or None");
5367 if (seq == NULL) {
5368 return -1;
5369 }
5370
5371 errno = posix_spawn_file_actions_init(file_actionsp);
5372 if (errno) {
5373 posix_error();
5374 Py_DECREF(seq);
5375 return -1;
5376 }
5377
5378 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5379 file_action = PySequence_Fast_GET_ITEM(seq, i);
5380 Py_INCREF(file_action);
5381 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5382 PyErr_SetString(PyExc_TypeError,
5383 "Each file_actions element must be a non-empty tuple");
5384 goto fail;
5385 }
5386 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5387 if (tag == -1 && PyErr_Occurred()) {
5388 goto fail;
5389 }
5390
5391 /* Populate the file_actions object */
5392 switch (tag) {
5393 case POSIX_SPAWN_OPEN: {
5394 int fd, oflag;
5395 PyObject *path;
5396 unsigned long mode;
5397 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5398 ";A open file_action tuple must have 5 elements",
5399 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5400 &oflag, &mode))
5401 {
5402 goto fail;
5403 }
Pablo Galindocb970732018-06-19 09:19:50 +01005404 if (PyList_Append(temp_buffer, path)) {
5405 Py_DECREF(path);
5406 goto fail;
5407 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005408 errno = posix_spawn_file_actions_addopen(file_actionsp,
5409 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005410 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005411 if (errno) {
5412 posix_error();
5413 goto fail;
5414 }
5415 break;
5416 }
5417 case POSIX_SPAWN_CLOSE: {
5418 int fd;
5419 if (!PyArg_ParseTuple(file_action, "Oi"
5420 ";A close file_action tuple must have 2 elements",
5421 &tag_obj, &fd))
5422 {
5423 goto fail;
5424 }
5425 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5426 if (errno) {
5427 posix_error();
5428 goto fail;
5429 }
5430 break;
5431 }
5432 case POSIX_SPAWN_DUP2: {
5433 int fd1, fd2;
5434 if (!PyArg_ParseTuple(file_action, "Oii"
5435 ";A dup2 file_action tuple must have 3 elements",
5436 &tag_obj, &fd1, &fd2))
5437 {
5438 goto fail;
5439 }
5440 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5441 fd1, fd2);
5442 if (errno) {
5443 posix_error();
5444 goto fail;
5445 }
5446 break;
5447 }
5448 default: {
5449 PyErr_SetString(PyExc_TypeError,
5450 "Unknown file_actions identifier");
5451 goto fail;
5452 }
5453 }
5454 Py_DECREF(file_action);
5455 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005456
Serhiy Storchakaef347532018-05-01 16:45:04 +03005457 Py_DECREF(seq);
5458 return 0;
5459
5460fail:
5461 Py_DECREF(seq);
5462 Py_DECREF(file_action);
5463 (void)posix_spawn_file_actions_destroy(file_actionsp);
5464 return -1;
5465}
5466
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005467
5468static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005469py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5470 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005471 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005472 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005473{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005474 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005475 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005476 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005477 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005478 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005479 posix_spawnattr_t attr;
5480 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005481 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005482 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005483 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005484 pid_t pid;
5485 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005486
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005487 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005488 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005489 like posix.environ. */
5490
Serhiy Storchakaef347532018-05-01 16:45:04 +03005491 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005492 PyErr_Format(PyExc_TypeError,
5493 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005494 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005495 }
5496 argc = PySequence_Size(argv);
5497 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005498 PyErr_Format(PyExc_ValueError,
5499 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005500 return NULL;
5501 }
5502
5503 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005504 PyErr_Format(PyExc_TypeError,
5505 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005506 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005507 }
5508
5509 argvlist = parse_arglist(argv, &argc);
5510 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005511 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005512 }
5513 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005514 PyErr_Format(PyExc_ValueError,
5515 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005516 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005517 }
5518
5519 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005520 if (envlist == NULL) {
5521 goto exit;
5522 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005523
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005524 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005525 /* There is a bug in old versions of glibc that makes some of the
5526 * helper functions for manipulating file actions not copy the provided
5527 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5528 * copy the value of path for some old versions of glibc (<2.20).
5529 * The use of temp_buffer here is a workaround that keeps the
5530 * python objects that own the buffers alive until posix_spawn gets called.
5531 * Check https://bugs.python.org/issue33630 and
5532 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5533 temp_buffer = PyList_New(0);
5534 if (!temp_buffer) {
5535 goto exit;
5536 }
5537 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005538 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005539 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005540 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005541 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005542
Victor Stinner325e4ba2019-02-01 15:47:24 +01005543 if (parse_posix_spawn_flags(func_name, setpgroup, resetids, setsid,
5544 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005545 goto exit;
5546 }
5547 attrp = &attr;
5548
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005549 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005550#ifdef HAVE_POSIX_SPAWNP
5551 if (use_posix_spawnp) {
5552 err_code = posix_spawnp(&pid, path->narrow,
5553 file_actionsp, attrp, argvlist, envlist);
5554 }
5555 else
5556#endif /* HAVE_POSIX_SPAWNP */
5557 {
5558 err_code = posix_spawn(&pid, path->narrow,
5559 file_actionsp, attrp, argvlist, envlist);
5560 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005561 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005562
Serhiy Storchakaef347532018-05-01 16:45:04 +03005563 if (err_code) {
5564 errno = err_code;
5565 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005566 goto exit;
5567 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005568#ifdef _Py_MEMORY_SANITIZER
5569 __msan_unpoison(&pid, sizeof(pid));
5570#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005571 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005572
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005573exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005574 if (file_actionsp) {
5575 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005576 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005577 if (attrp) {
5578 (void)posix_spawnattr_destroy(attrp);
5579 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005580 if (envlist) {
5581 free_string_array(envlist, envc);
5582 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005583 if (argvlist) {
5584 free_string_array(argvlist, argc);
5585 }
Pablo Galindocb970732018-06-19 09:19:50 +01005586 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005587 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005588}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005589
5590
5591/*[clinic input]
5592
5593os.posix_spawn
5594 path: path_t
5595 Path of executable file.
5596 argv: object
5597 Tuple or list of strings.
5598 env: object
5599 Dictionary of strings mapping to strings.
5600 /
5601 *
5602 file_actions: object(c_default='NULL') = ()
5603 A sequence of file action tuples.
5604 setpgroup: object = NULL
5605 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5606 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005607 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5608 setsid: bool(accept={int}) = False
5609 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005610 setsigmask: object(c_default='NULL') = ()
5611 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5612 setsigdef: object(c_default='NULL') = ()
5613 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5614 scheduler: object = NULL
5615 A tuple with the scheduler policy (optional) and parameters.
5616
5617Execute the program specified by path in a new process.
5618[clinic start generated code]*/
5619
5620static PyObject *
5621os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5622 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005623 PyObject *setpgroup, int resetids, int setsid,
5624 PyObject *setsigmask, PyObject *setsigdef,
5625 PyObject *scheduler)
5626/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005627{
5628 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005629 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005630 scheduler);
5631}
5632 #endif /* HAVE_POSIX_SPAWN */
5633
5634
5635
5636#ifdef HAVE_POSIX_SPAWNP
5637/*[clinic input]
5638
5639os.posix_spawnp
5640 path: path_t
5641 Path of executable file.
5642 argv: object
5643 Tuple or list of strings.
5644 env: object
5645 Dictionary of strings mapping to strings.
5646 /
5647 *
5648 file_actions: object(c_default='NULL') = ()
5649 A sequence of file action tuples.
5650 setpgroup: object = NULL
5651 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5652 resetids: bool(accept={int}) = False
5653 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005654 setsid: bool(accept={int}) = False
5655 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005656 setsigmask: object(c_default='NULL') = ()
5657 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5658 setsigdef: object(c_default='NULL') = ()
5659 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5660 scheduler: object = NULL
5661 A tuple with the scheduler policy (optional) and parameters.
5662
5663Execute the program specified by path in a new process.
5664[clinic start generated code]*/
5665
5666static PyObject *
5667os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5668 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005669 PyObject *setpgroup, int resetids, int setsid,
5670 PyObject *setsigmask, PyObject *setsigdef,
5671 PyObject *scheduler)
5672/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005673{
5674 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005675 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005676 scheduler);
5677}
5678#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005679
pxinwrf2d7ac72019-05-21 18:46:37 +08005680#ifdef HAVE_RTPSPAWN
5681static intptr_t
5682_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5683 const char *envp[])
5684{
5685 RTP_ID rtpid;
5686 int status;
5687 pid_t res;
5688 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005689
pxinwrf2d7ac72019-05-21 18:46:37 +08005690 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5691 uStackSize=0 cannot be used, the default stack size is too small for
5692 Python. */
5693 if (envp) {
5694 rtpid = rtpSpawn(rtpFileName, argv, envp,
5695 100, 0x1000000, 0, VX_FP_TASK);
5696 }
5697 else {
5698 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5699 100, 0x1000000, 0, VX_FP_TASK);
5700 }
5701 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5702 do {
5703 res = waitpid((pid_t)rtpid, &status, 0);
5704 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5705
5706 if (res < 0)
5707 return RTP_ID_ERROR;
5708 return ((intptr_t)status);
5709 }
5710 return ((intptr_t)rtpid);
5711}
5712#endif
5713
5714#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10005715/*[clinic input]
5716os.spawnv
5717
5718 mode: int
5719 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005720 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005721 Path of executable file.
5722 argv: object
5723 Tuple or list of strings.
5724 /
5725
5726Execute the program specified by path in a new process.
5727[clinic start generated code]*/
5728
Larry Hastings2f936352014-08-05 14:04:04 +10005729static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005730os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5731/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005732{
Steve Dowercc16be82016-09-08 10:35:16 -07005733 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005734 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005735 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005736 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005737 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005738
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 /* spawnv has three arguments: (mode, path, argv), where
5740 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005741
Victor Stinner8c62be82010-05-06 00:08:46 +00005742 if (PyList_Check(argv)) {
5743 argc = PyList_Size(argv);
5744 getitem = PyList_GetItem;
5745 }
5746 else if (PyTuple_Check(argv)) {
5747 argc = PyTuple_Size(argv);
5748 getitem = PyTuple_GetItem;
5749 }
5750 else {
5751 PyErr_SetString(PyExc_TypeError,
5752 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005753 return NULL;
5754 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005755 if (argc == 0) {
5756 PyErr_SetString(PyExc_ValueError,
5757 "spawnv() arg 2 cannot be empty");
5758 return NULL;
5759 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005760
Steve Dowercc16be82016-09-08 10:35:16 -07005761 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005762 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005763 return PyErr_NoMemory();
5764 }
5765 for (i = 0; i < argc; i++) {
5766 if (!fsconvert_strdup((*getitem)(argv, i),
5767 &argvlist[i])) {
5768 free_string_array(argvlist, i);
5769 PyErr_SetString(
5770 PyExc_TypeError,
5771 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005772 return NULL;
5773 }
Steve Dower93ff8722016-11-19 19:03:54 -08005774 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005775 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005776 PyErr_SetString(
5777 PyExc_ValueError,
5778 "spawnv() arg 2 first element cannot be empty");
5779 return NULL;
5780 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005781 }
5782 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005783
pxinwrf2d7ac72019-05-21 18:46:37 +08005784#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005785 if (mode == _OLD_P_OVERLAY)
5786 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005787#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005788
Victor Stinner8c62be82010-05-06 00:08:46 +00005789 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005790 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005791#ifdef HAVE_WSPAWNV
5792 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005793#elif defined(HAVE_RTPSPAWN)
5794 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07005795#else
5796 spawnval = _spawnv(mode, path->narrow, argvlist);
5797#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005798 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005799 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005800
Victor Stinner8c62be82010-05-06 00:08:46 +00005801 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005802
Victor Stinner8c62be82010-05-06 00:08:46 +00005803 if (spawnval == -1)
5804 return posix_error();
5805 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005806 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005807}
5808
Larry Hastings2f936352014-08-05 14:04:04 +10005809/*[clinic input]
5810os.spawnve
5811
5812 mode: int
5813 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005814 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005815 Path of executable file.
5816 argv: object
5817 Tuple or list of strings.
5818 env: object
5819 Dictionary of strings mapping to strings.
5820 /
5821
5822Execute the program specified by path in a new process.
5823[clinic start generated code]*/
5824
Larry Hastings2f936352014-08-05 14:04:04 +10005825static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005826os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005827 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005828/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005829{
Steve Dowercc16be82016-09-08 10:35:16 -07005830 EXECV_CHAR **argvlist;
5831 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005832 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005833 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005834 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005835 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005836 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005837
Victor Stinner8c62be82010-05-06 00:08:46 +00005838 /* spawnve has four arguments: (mode, path, argv, env), where
5839 argv is a list or tuple of strings and env is a dictionary
5840 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005841
Victor Stinner8c62be82010-05-06 00:08:46 +00005842 if (PyList_Check(argv)) {
5843 argc = PyList_Size(argv);
5844 getitem = PyList_GetItem;
5845 }
5846 else if (PyTuple_Check(argv)) {
5847 argc = PyTuple_Size(argv);
5848 getitem = PyTuple_GetItem;
5849 }
5850 else {
5851 PyErr_SetString(PyExc_TypeError,
5852 "spawnve() arg 2 must be a tuple or list");
5853 goto fail_0;
5854 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005855 if (argc == 0) {
5856 PyErr_SetString(PyExc_ValueError,
5857 "spawnve() arg 2 cannot be empty");
5858 goto fail_0;
5859 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005860 if (!PyMapping_Check(env)) {
5861 PyErr_SetString(PyExc_TypeError,
5862 "spawnve() arg 3 must be a mapping object");
5863 goto fail_0;
5864 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005865
Steve Dowercc16be82016-09-08 10:35:16 -07005866 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005867 if (argvlist == NULL) {
5868 PyErr_NoMemory();
5869 goto fail_0;
5870 }
5871 for (i = 0; i < argc; i++) {
5872 if (!fsconvert_strdup((*getitem)(argv, i),
5873 &argvlist[i]))
5874 {
5875 lastarg = i;
5876 goto fail_1;
5877 }
Steve Dowerbce26262016-11-19 19:17:26 -08005878 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005879 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005880 PyErr_SetString(
5881 PyExc_ValueError,
5882 "spawnv() arg 2 first element cannot be empty");
5883 goto fail_1;
5884 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005885 }
5886 lastarg = argc;
5887 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005888
Victor Stinner8c62be82010-05-06 00:08:46 +00005889 envlist = parse_envlist(env, &envc);
5890 if (envlist == NULL)
5891 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005892
pxinwrf2d7ac72019-05-21 18:46:37 +08005893#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005894 if (mode == _OLD_P_OVERLAY)
5895 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005896#endif
Tim Peters25059d32001-12-07 20:35:43 +00005897
Victor Stinner8c62be82010-05-06 00:08:46 +00005898 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005899 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005900#ifdef HAVE_WSPAWNV
5901 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005902#elif defined(HAVE_RTPSPAWN)
5903 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
5904 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005905#else
5906 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5907#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005908 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005909 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005910
Victor Stinner8c62be82010-05-06 00:08:46 +00005911 if (spawnval == -1)
5912 (void) posix_error();
5913 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005914 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005915
Victor Stinner8c62be82010-05-06 00:08:46 +00005916 while (--envc >= 0)
5917 PyMem_DEL(envlist[envc]);
5918 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005919 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005920 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005921 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005922 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005923}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005924
Guido van Rossuma1065681999-01-25 23:20:23 +00005925#endif /* HAVE_SPAWNV */
5926
5927
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005928#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005929
5930/* Helper function to validate arguments.
5931 Returns 0 on success. non-zero on failure with a TypeError raised.
5932 If obj is non-NULL it must be callable. */
5933static int
5934check_null_or_callable(PyObject *obj, const char* obj_name)
5935{
5936 if (obj && !PyCallable_Check(obj)) {
5937 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5938 obj_name, Py_TYPE(obj)->tp_name);
5939 return -1;
5940 }
5941 return 0;
5942}
5943
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005944/*[clinic input]
5945os.register_at_fork
5946
Gregory P. Smith163468a2017-05-29 10:03:41 -07005947 *
5948 before: object=NULL
5949 A callable to be called in the parent before the fork() syscall.
5950 after_in_child: object=NULL
5951 A callable to be called in the child after fork().
5952 after_in_parent: object=NULL
5953 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005954
Gregory P. Smith163468a2017-05-29 10:03:41 -07005955Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005956
Gregory P. Smith163468a2017-05-29 10:03:41 -07005957'before' callbacks are called in reverse order.
5958'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005959
5960[clinic start generated code]*/
5961
5962static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005963os_register_at_fork_impl(PyObject *module, PyObject *before,
5964 PyObject *after_in_child, PyObject *after_in_parent)
5965/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005966{
5967 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005968
Gregory P. Smith163468a2017-05-29 10:03:41 -07005969 if (!before && !after_in_child && !after_in_parent) {
5970 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5971 return NULL;
5972 }
5973 if (check_null_or_callable(before, "before") ||
5974 check_null_or_callable(after_in_child, "after_in_child") ||
5975 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005976 return NULL;
5977 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02005978 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005979
Gregory P. Smith163468a2017-05-29 10:03:41 -07005980 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005981 return NULL;
5982 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005983 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005984 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005985 }
5986 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5987 return NULL;
5988 }
5989 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005990}
5991#endif /* HAVE_FORK */
5992
5993
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005994#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005995/*[clinic input]
5996os.fork1
5997
5998Fork a child process with a single multiplexed (i.e., not bound) thread.
5999
6000Return 0 to child process and PID of child to parent process.
6001[clinic start generated code]*/
6002
Larry Hastings2f936352014-08-05 14:04:04 +10006003static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006004os_fork1_impl(PyObject *module)
6005/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006006{
Victor Stinner8c62be82010-05-06 00:08:46 +00006007 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006008
Eric Snow59032962018-09-14 14:17:20 -07006009 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6010 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6011 return NULL;
6012 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006013 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006014 pid = fork1();
6015 if (pid == 0) {
6016 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006017 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 } else {
6019 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006020 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006021 }
6022 if (pid == -1)
6023 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006024 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006025}
Larry Hastings2f936352014-08-05 14:04:04 +10006026#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006027
6028
Guido van Rossumad0ee831995-03-01 10:34:45 +00006029#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006030/*[clinic input]
6031os.fork
6032
6033Fork a child process.
6034
6035Return 0 to child process and PID of child to parent process.
6036[clinic start generated code]*/
6037
Larry Hastings2f936352014-08-05 14:04:04 +10006038static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006039os_fork_impl(PyObject *module)
6040/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006041{
Victor Stinner8c62be82010-05-06 00:08:46 +00006042 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006043
Eric Snow59032962018-09-14 14:17:20 -07006044 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6045 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6046 return NULL;
6047 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006048 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006049 pid = fork();
6050 if (pid == 0) {
6051 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006052 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006053 } else {
6054 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006055 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006056 }
6057 if (pid == -1)
6058 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006059 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006060}
Larry Hastings2f936352014-08-05 14:04:04 +10006061#endif /* HAVE_FORK */
6062
Guido van Rossum85e3b011991-06-03 12:42:10 +00006063
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006064#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006065#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006066/*[clinic input]
6067os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006068
Larry Hastings2f936352014-08-05 14:04:04 +10006069 policy: int
6070
6071Get the maximum scheduling priority for policy.
6072[clinic start generated code]*/
6073
Larry Hastings2f936352014-08-05 14:04:04 +10006074static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006075os_sched_get_priority_max_impl(PyObject *module, int policy)
6076/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006077{
6078 int max;
6079
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006080 max = sched_get_priority_max(policy);
6081 if (max < 0)
6082 return posix_error();
6083 return PyLong_FromLong(max);
6084}
6085
Larry Hastings2f936352014-08-05 14:04:04 +10006086
6087/*[clinic input]
6088os.sched_get_priority_min
6089
6090 policy: int
6091
6092Get the minimum scheduling priority for policy.
6093[clinic start generated code]*/
6094
Larry Hastings2f936352014-08-05 14:04:04 +10006095static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006096os_sched_get_priority_min_impl(PyObject *module, int policy)
6097/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006098{
6099 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006100 if (min < 0)
6101 return posix_error();
6102 return PyLong_FromLong(min);
6103}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006104#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6105
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006106
Larry Hastings2f936352014-08-05 14:04:04 +10006107#ifdef HAVE_SCHED_SETSCHEDULER
6108/*[clinic input]
6109os.sched_getscheduler
6110 pid: pid_t
6111 /
6112
6113Get the scheduling policy for the process identifiedy by pid.
6114
6115Passing 0 for pid returns the scheduling policy for the calling process.
6116[clinic start generated code]*/
6117
Larry Hastings2f936352014-08-05 14:04:04 +10006118static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006119os_sched_getscheduler_impl(PyObject *module, pid_t pid)
6120/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006121{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006122 int policy;
6123
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006124 policy = sched_getscheduler(pid);
6125 if (policy < 0)
6126 return posix_error();
6127 return PyLong_FromLong(policy);
6128}
Larry Hastings2f936352014-08-05 14:04:04 +10006129#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006130
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006131
William Orr81574b82018-10-01 22:19:56 -07006132#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006133/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006134class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006135
6136@classmethod
6137os.sched_param.__new__
6138
6139 sched_priority: object
6140 A scheduling parameter.
6141
6142Current has only one field: sched_priority");
6143[clinic start generated code]*/
6144
Larry Hastings2f936352014-08-05 14:04:04 +10006145static PyObject *
6146os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006147/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006148{
6149 PyObject *res;
6150
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006151 res = PyStructSequence_New(type);
6152 if (!res)
6153 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006154 Py_INCREF(sched_priority);
6155 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006156 return res;
6157}
6158
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006159
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006160PyDoc_VAR(os_sched_param__doc__);
6161
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006162static PyStructSequence_Field sched_param_fields[] = {
6163 {"sched_priority", "the scheduling priority"},
6164 {0}
6165};
6166
6167static PyStructSequence_Desc sched_param_desc = {
6168 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006169 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006170 sched_param_fields,
6171 1
6172};
6173
6174static int
6175convert_sched_param(PyObject *param, struct sched_param *res)
6176{
6177 long priority;
6178
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006179 if (Py_TYPE(param) != SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006180 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6181 return 0;
6182 }
6183 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6184 if (priority == -1 && PyErr_Occurred())
6185 return 0;
6186 if (priority > INT_MAX || priority < INT_MIN) {
6187 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6188 return 0;
6189 }
6190 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6191 return 1;
6192}
William Orr81574b82018-10-01 22:19:56 -07006193#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006194
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006195
6196#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006197/*[clinic input]
6198os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006199
Larry Hastings2f936352014-08-05 14:04:04 +10006200 pid: pid_t
6201 policy: int
6202 param: sched_param
6203 /
6204
6205Set the scheduling policy for the process identified by pid.
6206
6207If pid is 0, the calling process is changed.
6208param is an instance of sched_param.
6209[clinic start generated code]*/
6210
Larry Hastings2f936352014-08-05 14:04:04 +10006211static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006212os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006213 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006214/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006215{
Jesus Cea9c822272011-09-10 01:40:52 +02006216 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006217 ** sched_setscheduler() returns 0 in Linux, but the previous
6218 ** scheduling policy under Solaris/Illumos, and others.
6219 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006220 */
Larry Hastings2f936352014-08-05 14:04:04 +10006221 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006222 return posix_error();
6223 Py_RETURN_NONE;
6224}
Larry Hastings2f936352014-08-05 14:04:04 +10006225#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006226
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006227
6228#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006229/*[clinic input]
6230os.sched_getparam
6231 pid: pid_t
6232 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006233
Larry Hastings2f936352014-08-05 14:04:04 +10006234Returns scheduling parameters for the process identified by pid.
6235
6236If pid is 0, returns parameters for the calling process.
6237Return value is an instance of sched_param.
6238[clinic start generated code]*/
6239
Larry Hastings2f936352014-08-05 14:04:04 +10006240static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006241os_sched_getparam_impl(PyObject *module, pid_t pid)
6242/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006243{
6244 struct sched_param param;
6245 PyObject *result;
6246 PyObject *priority;
6247
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006248 if (sched_getparam(pid, &param))
6249 return posix_error();
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006250 result = PyStructSequence_New(SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006251 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006252 return NULL;
6253 priority = PyLong_FromLong(param.sched_priority);
6254 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006255 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006256 return NULL;
6257 }
Larry Hastings2f936352014-08-05 14:04:04 +10006258 PyStructSequence_SET_ITEM(result, 0, priority);
6259 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006260}
6261
Larry Hastings2f936352014-08-05 14:04:04 +10006262
6263/*[clinic input]
6264os.sched_setparam
6265 pid: pid_t
6266 param: sched_param
6267 /
6268
6269Set scheduling parameters for the process identified by pid.
6270
6271If pid is 0, sets parameters for the calling process.
6272param should be an instance of sched_param.
6273[clinic start generated code]*/
6274
Larry Hastings2f936352014-08-05 14:04:04 +10006275static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006276os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006277 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006278/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006279{
6280 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006281 return posix_error();
6282 Py_RETURN_NONE;
6283}
Larry Hastings2f936352014-08-05 14:04:04 +10006284#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006285
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006286
6287#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006288/*[clinic input]
6289os.sched_rr_get_interval -> double
6290 pid: pid_t
6291 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006292
Larry Hastings2f936352014-08-05 14:04:04 +10006293Return the round-robin quantum for the process identified by pid, in seconds.
6294
6295Value returned is a float.
6296[clinic start generated code]*/
6297
Larry Hastings2f936352014-08-05 14:04:04 +10006298static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006299os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6300/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006301{
6302 struct timespec interval;
6303 if (sched_rr_get_interval(pid, &interval)) {
6304 posix_error();
6305 return -1.0;
6306 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006307#ifdef _Py_MEMORY_SANITIZER
6308 __msan_unpoison(&interval, sizeof(interval));
6309#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006310 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6311}
6312#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006313
Larry Hastings2f936352014-08-05 14:04:04 +10006314
6315/*[clinic input]
6316os.sched_yield
6317
6318Voluntarily relinquish the CPU.
6319[clinic start generated code]*/
6320
Larry Hastings2f936352014-08-05 14:04:04 +10006321static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006322os_sched_yield_impl(PyObject *module)
6323/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006324{
6325 if (sched_yield())
6326 return posix_error();
6327 Py_RETURN_NONE;
6328}
6329
Benjamin Peterson2740af82011-08-02 17:41:34 -05006330#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006331/* The minimum number of CPUs allocated in a cpu_set_t */
6332static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006333
Larry Hastings2f936352014-08-05 14:04:04 +10006334/*[clinic input]
6335os.sched_setaffinity
6336 pid: pid_t
6337 mask : object
6338 /
6339
6340Set the CPU affinity of the process identified by pid to mask.
6341
6342mask should be an iterable of integers identifying CPUs.
6343[clinic start generated code]*/
6344
Larry Hastings2f936352014-08-05 14:04:04 +10006345static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006346os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6347/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006348{
Antoine Pitrou84869872012-08-04 16:16:35 +02006349 int ncpus;
6350 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006351 cpu_set_t *cpu_set = NULL;
6352 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006353
Larry Hastings2f936352014-08-05 14:04:04 +10006354 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006355 if (iterator == NULL)
6356 return NULL;
6357
6358 ncpus = NCPUS_START;
6359 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006360 cpu_set = CPU_ALLOC(ncpus);
6361 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006362 PyErr_NoMemory();
6363 goto error;
6364 }
Larry Hastings2f936352014-08-05 14:04:04 +10006365 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006366
6367 while ((item = PyIter_Next(iterator))) {
6368 long cpu;
6369 if (!PyLong_Check(item)) {
6370 PyErr_Format(PyExc_TypeError,
6371 "expected an iterator of ints, "
6372 "but iterator yielded %R",
6373 Py_TYPE(item));
6374 Py_DECREF(item);
6375 goto error;
6376 }
6377 cpu = PyLong_AsLong(item);
6378 Py_DECREF(item);
6379 if (cpu < 0) {
6380 if (!PyErr_Occurred())
6381 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6382 goto error;
6383 }
6384 if (cpu > INT_MAX - 1) {
6385 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6386 goto error;
6387 }
6388 if (cpu >= ncpus) {
6389 /* Grow CPU mask to fit the CPU number */
6390 int newncpus = ncpus;
6391 cpu_set_t *newmask;
6392 size_t newsetsize;
6393 while (newncpus <= cpu) {
6394 if (newncpus > INT_MAX / 2)
6395 newncpus = cpu + 1;
6396 else
6397 newncpus = newncpus * 2;
6398 }
6399 newmask = CPU_ALLOC(newncpus);
6400 if (newmask == NULL) {
6401 PyErr_NoMemory();
6402 goto error;
6403 }
6404 newsetsize = CPU_ALLOC_SIZE(newncpus);
6405 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006406 memcpy(newmask, cpu_set, setsize);
6407 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006408 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006409 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006410 ncpus = newncpus;
6411 }
Larry Hastings2f936352014-08-05 14:04:04 +10006412 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006413 }
6414 Py_CLEAR(iterator);
6415
Larry Hastings2f936352014-08-05 14:04:04 +10006416 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006417 posix_error();
6418 goto error;
6419 }
Larry Hastings2f936352014-08-05 14:04:04 +10006420 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006421 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006422
6423error:
Larry Hastings2f936352014-08-05 14:04:04 +10006424 if (cpu_set)
6425 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006426 Py_XDECREF(iterator);
6427 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006428}
6429
Larry Hastings2f936352014-08-05 14:04:04 +10006430
6431/*[clinic input]
6432os.sched_getaffinity
6433 pid: pid_t
6434 /
6435
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006436Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006437
6438The affinity is returned as a set of CPU identifiers.
6439[clinic start generated code]*/
6440
Larry Hastings2f936352014-08-05 14:04:04 +10006441static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006442os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006443/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006444{
Antoine Pitrou84869872012-08-04 16:16:35 +02006445 int cpu, ncpus, count;
6446 size_t setsize;
6447 cpu_set_t *mask = NULL;
6448 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006449
Antoine Pitrou84869872012-08-04 16:16:35 +02006450 ncpus = NCPUS_START;
6451 while (1) {
6452 setsize = CPU_ALLOC_SIZE(ncpus);
6453 mask = CPU_ALLOC(ncpus);
6454 if (mask == NULL)
6455 return PyErr_NoMemory();
6456 if (sched_getaffinity(pid, setsize, mask) == 0)
6457 break;
6458 CPU_FREE(mask);
6459 if (errno != EINVAL)
6460 return posix_error();
6461 if (ncpus > INT_MAX / 2) {
6462 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6463 "a large enough CPU set");
6464 return NULL;
6465 }
6466 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006467 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006468
6469 res = PySet_New(NULL);
6470 if (res == NULL)
6471 goto error;
6472 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6473 if (CPU_ISSET_S(cpu, setsize, mask)) {
6474 PyObject *cpu_num = PyLong_FromLong(cpu);
6475 --count;
6476 if (cpu_num == NULL)
6477 goto error;
6478 if (PySet_Add(res, cpu_num)) {
6479 Py_DECREF(cpu_num);
6480 goto error;
6481 }
6482 Py_DECREF(cpu_num);
6483 }
6484 }
6485 CPU_FREE(mask);
6486 return res;
6487
6488error:
6489 if (mask)
6490 CPU_FREE(mask);
6491 Py_XDECREF(res);
6492 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006493}
6494
Benjamin Peterson2740af82011-08-02 17:41:34 -05006495#endif /* HAVE_SCHED_SETAFFINITY */
6496
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006497#endif /* HAVE_SCHED_H */
6498
Larry Hastings2f936352014-08-05 14:04:04 +10006499
Neal Norwitzb59798b2003-03-21 01:43:31 +00006500/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006501/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6502#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006503#define DEV_PTY_FILE "/dev/ptc"
6504#define HAVE_DEV_PTMX
6505#else
6506#define DEV_PTY_FILE "/dev/ptmx"
6507#endif
6508
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006509#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006510#ifdef HAVE_PTY_H
6511#include <pty.h>
6512#else
6513#ifdef HAVE_LIBUTIL_H
6514#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006515#else
6516#ifdef HAVE_UTIL_H
6517#include <util.h>
6518#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006519#endif /* HAVE_LIBUTIL_H */
6520#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006521#ifdef HAVE_STROPTS_H
6522#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006523#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006524#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006525
Larry Hastings2f936352014-08-05 14:04:04 +10006526
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006527#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006528/*[clinic input]
6529os.openpty
6530
6531Open a pseudo-terminal.
6532
6533Return a tuple of (master_fd, slave_fd) containing open file descriptors
6534for both the master and slave ends.
6535[clinic start generated code]*/
6536
Larry Hastings2f936352014-08-05 14:04:04 +10006537static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006538os_openpty_impl(PyObject *module)
6539/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006540{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006541 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006542#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006543 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006544#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006545#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006546 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006547#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006548 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006549#endif
6550#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006551
Thomas Wouters70c21a12000-07-14 14:28:33 +00006552#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006553 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006554 goto posix_error;
6555
6556 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6557 goto error;
6558 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6559 goto error;
6560
Neal Norwitzb59798b2003-03-21 01:43:31 +00006561#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6563 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006564 goto posix_error;
6565 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6566 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006567
Victor Stinnerdaf45552013-08-28 00:53:59 +02006568 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006569 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006570 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006571
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006572#else
Victor Stinner000de532013-11-25 23:19:58 +01006573 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006574 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006575 goto posix_error;
6576
Victor Stinner8c62be82010-05-06 00:08:46 +00006577 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006578
Victor Stinner8c62be82010-05-06 00:08:46 +00006579 /* change permission of slave */
6580 if (grantpt(master_fd) < 0) {
6581 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006582 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006583 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006584
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 /* unlock slave */
6586 if (unlockpt(master_fd) < 0) {
6587 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006588 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006590
Victor Stinner8c62be82010-05-06 00:08:46 +00006591 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006592
Victor Stinner8c62be82010-05-06 00:08:46 +00006593 slave_name = ptsname(master_fd); /* get name of slave */
6594 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006595 goto posix_error;
6596
6597 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006598 if (slave_fd == -1)
6599 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006600
6601 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6602 goto posix_error;
6603
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006604#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6606 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006607#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006609#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006610#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006611#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006612
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006614
Victor Stinnerdaf45552013-08-28 00:53:59 +02006615posix_error:
6616 posix_error();
6617error:
6618 if (master_fd != -1)
6619 close(master_fd);
6620 if (slave_fd != -1)
6621 close(slave_fd);
6622 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006623}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006624#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006625
Larry Hastings2f936352014-08-05 14:04:04 +10006626
Fred Drake8cef4cf2000-06-28 16:40:38 +00006627#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006628/*[clinic input]
6629os.forkpty
6630
6631Fork a new process with a new pseudo-terminal as controlling tty.
6632
6633Returns a tuple of (pid, master_fd).
6634Like fork(), return pid of 0 to the child process,
6635and pid of child to the parent process.
6636To both, return fd of newly opened pseudo-terminal.
6637[clinic start generated code]*/
6638
Larry Hastings2f936352014-08-05 14:04:04 +10006639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006640os_forkpty_impl(PyObject *module)
6641/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006642{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006643 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006645
Eric Snow59032962018-09-14 14:17:20 -07006646 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6647 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6648 return NULL;
6649 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006650 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006651 pid = forkpty(&master_fd, NULL, NULL, NULL);
6652 if (pid == 0) {
6653 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006654 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006655 } else {
6656 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006657 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006658 }
6659 if (pid == -1)
6660 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006662}
Larry Hastings2f936352014-08-05 14:04:04 +10006663#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006664
Ross Lagerwall7807c352011-03-17 20:20:30 +02006665
Guido van Rossumad0ee831995-03-01 10:34:45 +00006666#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006667/*[clinic input]
6668os.getegid
6669
6670Return the current process's effective group id.
6671[clinic start generated code]*/
6672
Larry Hastings2f936352014-08-05 14:04:04 +10006673static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006674os_getegid_impl(PyObject *module)
6675/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006676{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006677 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006678}
Larry Hastings2f936352014-08-05 14:04:04 +10006679#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006680
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006681
Guido van Rossumad0ee831995-03-01 10:34:45 +00006682#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006683/*[clinic input]
6684os.geteuid
6685
6686Return the current process's effective user id.
6687[clinic start generated code]*/
6688
Larry Hastings2f936352014-08-05 14:04:04 +10006689static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006690os_geteuid_impl(PyObject *module)
6691/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006692{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006693 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006694}
Larry Hastings2f936352014-08-05 14:04:04 +10006695#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006696
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006697
Guido van Rossumad0ee831995-03-01 10:34:45 +00006698#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006699/*[clinic input]
6700os.getgid
6701
6702Return the current process's group id.
6703[clinic start generated code]*/
6704
Larry Hastings2f936352014-08-05 14:04:04 +10006705static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006706os_getgid_impl(PyObject *module)
6707/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006708{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006709 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006710}
Larry Hastings2f936352014-08-05 14:04:04 +10006711#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006712
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006713
Berker Peksag39404992016-09-15 20:45:16 +03006714#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006715/*[clinic input]
6716os.getpid
6717
6718Return the current process id.
6719[clinic start generated code]*/
6720
Larry Hastings2f936352014-08-05 14:04:04 +10006721static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006722os_getpid_impl(PyObject *module)
6723/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006724{
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006726}
Berker Peksag39404992016-09-15 20:45:16 +03006727#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006728
Miss Islington (bot)c80183e2019-06-13 00:27:23 -07006729#ifdef NGROUPS_MAX
6730#define MAX_GROUPS NGROUPS_MAX
6731#else
6732 /* defined to be 16 on Solaris7, so this should be a small number */
6733#define MAX_GROUPS 64
6734#endif
6735
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006736#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006737
6738/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006739PyDoc_STRVAR(posix_getgrouplist__doc__,
6740"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6741Returns a list of groups to which a user belongs.\n\n\
6742 user: username to lookup\n\
6743 group: base group id of the user");
6744
6745static PyObject *
6746posix_getgrouplist(PyObject *self, PyObject *args)
6747{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006748 const char *user;
6749 int i, ngroups;
6750 PyObject *list;
6751#ifdef __APPLE__
6752 int *groups, basegid;
6753#else
6754 gid_t *groups, basegid;
6755#endif
Miss Islington (bot)c80183e2019-06-13 00:27:23 -07006756
6757 /*
6758 * NGROUPS_MAX is defined by POSIX.1 as the maximum
6759 * number of supplimental groups a users can belong to.
6760 * We have to increment it by one because
6761 * getgrouplist() returns both the supplemental groups
6762 * and the primary group, i.e. all of the groups the
6763 * user belongs to.
6764 */
6765 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006766
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006767#ifdef __APPLE__
6768 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006769 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006770#else
6771 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6772 _Py_Gid_Converter, &basegid))
6773 return NULL;
6774#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006775
6776#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006777 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006778#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006779 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006780#endif
6781 if (groups == NULL)
6782 return PyErr_NoMemory();
6783
6784 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6785 PyMem_Del(groups);
6786 return posix_error();
6787 }
6788
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006789#ifdef _Py_MEMORY_SANITIZER
6790 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6791 __msan_unpoison(&ngroups, sizeof(ngroups));
6792 __msan_unpoison(groups, ngroups*sizeof(*groups));
6793#endif
6794
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006795 list = PyList_New(ngroups);
6796 if (list == NULL) {
6797 PyMem_Del(groups);
6798 return NULL;
6799 }
6800
6801 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006802#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006803 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006804#else
6805 PyObject *o = _PyLong_FromGid(groups[i]);
6806#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006807 if (o == NULL) {
6808 Py_DECREF(list);
6809 PyMem_Del(groups);
6810 return NULL;
6811 }
6812 PyList_SET_ITEM(list, i, o);
6813 }
6814
6815 PyMem_Del(groups);
6816
6817 return list;
6818}
Larry Hastings2f936352014-08-05 14:04:04 +10006819#endif /* HAVE_GETGROUPLIST */
6820
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006821
Fred Drakec9680921999-12-13 16:37:25 +00006822#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006823/*[clinic input]
6824os.getgroups
6825
6826Return list of supplemental group IDs for the process.
6827[clinic start generated code]*/
6828
Larry Hastings2f936352014-08-05 14:04:04 +10006829static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006830os_getgroups_impl(PyObject *module)
6831/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006832{
6833 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006834 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006835
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006836 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006837 * This is a helper variable to store the intermediate result when
6838 * that happens.
6839 *
6840 * To keep the code readable the OSX behaviour is unconditional,
6841 * according to the POSIX spec this should be safe on all unix-y
6842 * systems.
6843 */
6844 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006846
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006847#ifdef __APPLE__
6848 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6849 * there are more groups than can fit in grouplist. Therefore, on OS X
6850 * always first call getgroups with length 0 to get the actual number
6851 * of groups.
6852 */
6853 n = getgroups(0, NULL);
6854 if (n < 0) {
6855 return posix_error();
6856 } else if (n <= MAX_GROUPS) {
6857 /* groups will fit in existing array */
6858 alt_grouplist = grouplist;
6859 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006860 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006861 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006862 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006863 }
6864 }
6865
6866 n = getgroups(n, alt_grouplist);
6867 if (n == -1) {
6868 if (alt_grouplist != grouplist) {
6869 PyMem_Free(alt_grouplist);
6870 }
6871 return posix_error();
6872 }
6873#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006875 if (n < 0) {
6876 if (errno == EINVAL) {
6877 n = getgroups(0, NULL);
6878 if (n == -1) {
6879 return posix_error();
6880 }
6881 if (n == 0) {
6882 /* Avoid malloc(0) */
6883 alt_grouplist = grouplist;
6884 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006885 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006886 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006887 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006888 }
6889 n = getgroups(n, alt_grouplist);
6890 if (n == -1) {
6891 PyMem_Free(alt_grouplist);
6892 return posix_error();
6893 }
6894 }
6895 } else {
6896 return posix_error();
6897 }
6898 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006899#endif
6900
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006901 result = PyList_New(n);
6902 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006903 int i;
6904 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006905 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006906 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006907 Py_DECREF(result);
6908 result = NULL;
6909 break;
Fred Drakec9680921999-12-13 16:37:25 +00006910 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006912 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006913 }
6914
6915 if (alt_grouplist != grouplist) {
6916 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006917 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006918
Fred Drakec9680921999-12-13 16:37:25 +00006919 return result;
6920}
Larry Hastings2f936352014-08-05 14:04:04 +10006921#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006922
Antoine Pitroub7572f02009-12-02 20:46:48 +00006923#ifdef HAVE_INITGROUPS
6924PyDoc_STRVAR(posix_initgroups__doc__,
6925"initgroups(username, gid) -> None\n\n\
6926Call the system initgroups() to initialize the group access list with all of\n\
6927the groups of which the specified username is a member, plus the specified\n\
6928group id.");
6929
Larry Hastings2f936352014-08-05 14:04:04 +10006930/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006931static PyObject *
6932posix_initgroups(PyObject *self, PyObject *args)
6933{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006934 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006935 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006936 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006937#ifdef __APPLE__
6938 int gid;
6939#else
6940 gid_t gid;
6941#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006942
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006943#ifdef __APPLE__
6944 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6945 PyUnicode_FSConverter, &oname,
6946 &gid))
6947#else
6948 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6949 PyUnicode_FSConverter, &oname,
6950 _Py_Gid_Converter, &gid))
6951#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006953 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006954
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006955 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006956 Py_DECREF(oname);
6957 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006959
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006960 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006961}
Larry Hastings2f936352014-08-05 14:04:04 +10006962#endif /* HAVE_INITGROUPS */
6963
Antoine Pitroub7572f02009-12-02 20:46:48 +00006964
Martin v. Löwis606edc12002-06-13 21:09:11 +00006965#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006966/*[clinic input]
6967os.getpgid
6968
6969 pid: pid_t
6970
6971Call the system call getpgid(), and return the result.
6972[clinic start generated code]*/
6973
Larry Hastings2f936352014-08-05 14:04:04 +10006974static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006975os_getpgid_impl(PyObject *module, pid_t pid)
6976/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006977{
6978 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006979 if (pgid < 0)
6980 return posix_error();
6981 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006982}
6983#endif /* HAVE_GETPGID */
6984
6985
Guido van Rossumb6775db1994-08-01 11:34:53 +00006986#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006987/*[clinic input]
6988os.getpgrp
6989
6990Return the current process group id.
6991[clinic start generated code]*/
6992
Larry Hastings2f936352014-08-05 14:04:04 +10006993static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006994os_getpgrp_impl(PyObject *module)
6995/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006996{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006997#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006998 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006999#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007000 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007001#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007002}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007003#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007004
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007005
Guido van Rossumb6775db1994-08-01 11:34:53 +00007006#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007007/*[clinic input]
7008os.setpgrp
7009
7010Make the current process the leader of its process group.
7011[clinic start generated code]*/
7012
Larry Hastings2f936352014-08-05 14:04:04 +10007013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007014os_setpgrp_impl(PyObject *module)
7015/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007016{
Guido van Rossum64933891994-10-20 21:56:42 +00007017#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007019#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007020 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007021#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007022 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007023 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007024}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007025#endif /* HAVE_SETPGRP */
7026
Guido van Rossumad0ee831995-03-01 10:34:45 +00007027#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007028
7029#ifdef MS_WINDOWS
7030#include <tlhelp32.h>
7031
7032static PyObject*
7033win32_getppid()
7034{
7035 HANDLE snapshot;
7036 pid_t mypid;
7037 PyObject* result = NULL;
7038 BOOL have_record;
7039 PROCESSENTRY32 pe;
7040
7041 mypid = getpid(); /* This function never fails */
7042
7043 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7044 if (snapshot == INVALID_HANDLE_VALUE)
7045 return PyErr_SetFromWindowsErr(GetLastError());
7046
7047 pe.dwSize = sizeof(pe);
7048 have_record = Process32First(snapshot, &pe);
7049 while (have_record) {
7050 if (mypid == (pid_t)pe.th32ProcessID) {
7051 /* We could cache the ulong value in a static variable. */
7052 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7053 break;
7054 }
7055
7056 have_record = Process32Next(snapshot, &pe);
7057 }
7058
7059 /* If our loop exits and our pid was not found (result will be NULL)
7060 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7061 * error anyway, so let's raise it. */
7062 if (!result)
7063 result = PyErr_SetFromWindowsErr(GetLastError());
7064
7065 CloseHandle(snapshot);
7066
7067 return result;
7068}
7069#endif /*MS_WINDOWS*/
7070
Larry Hastings2f936352014-08-05 14:04:04 +10007071
7072/*[clinic input]
7073os.getppid
7074
7075Return the parent's process id.
7076
7077If the parent process has already exited, Windows machines will still
7078return its id; others systems will return the id of the 'init' process (1).
7079[clinic start generated code]*/
7080
Larry Hastings2f936352014-08-05 14:04:04 +10007081static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007082os_getppid_impl(PyObject *module)
7083/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007084{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007085#ifdef MS_WINDOWS
7086 return win32_getppid();
7087#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007088 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007089#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007090}
7091#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007093
Fred Drake12c6e2d1999-12-14 21:25:03 +00007094#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007095/*[clinic input]
7096os.getlogin
7097
7098Return the actual login name.
7099[clinic start generated code]*/
7100
Larry Hastings2f936352014-08-05 14:04:04 +10007101static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007102os_getlogin_impl(PyObject *module)
7103/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007104{
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007106#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007107 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007108 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007109
7110 if (GetUserNameW(user_name, &num_chars)) {
7111 /* num_chars is the number of unicode chars plus null terminator */
7112 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007113 }
7114 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007115 result = PyErr_SetFromWindowsErr(GetLastError());
7116#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 char *name;
7118 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007119
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 errno = 0;
7121 name = getlogin();
7122 if (name == NULL) {
7123 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007124 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007125 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007126 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007127 }
7128 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007129 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007130 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007131#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007132 return result;
7133}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007134#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007135
Larry Hastings2f936352014-08-05 14:04:04 +10007136
Guido van Rossumad0ee831995-03-01 10:34:45 +00007137#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007138/*[clinic input]
7139os.getuid
7140
7141Return the current process's user id.
7142[clinic start generated code]*/
7143
Larry Hastings2f936352014-08-05 14:04:04 +10007144static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007145os_getuid_impl(PyObject *module)
7146/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007147{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007148 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007149}
Larry Hastings2f936352014-08-05 14:04:04 +10007150#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007152
Brian Curtineb24d742010-04-12 17:16:38 +00007153#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007154#define HAVE_KILL
7155#endif /* MS_WINDOWS */
7156
7157#ifdef HAVE_KILL
7158/*[clinic input]
7159os.kill
7160
7161 pid: pid_t
7162 signal: Py_ssize_t
7163 /
7164
7165Kill a process with a signal.
7166[clinic start generated code]*/
7167
Larry Hastings2f936352014-08-05 14:04:04 +10007168static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007169os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7170/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007171#ifndef MS_WINDOWS
7172{
7173 if (kill(pid, (int)signal) == -1)
7174 return posix_error();
7175 Py_RETURN_NONE;
7176}
7177#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00007178{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007179 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007180 DWORD sig = (DWORD)signal;
7181 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007182 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007183
Victor Stinner8c62be82010-05-06 00:08:46 +00007184 /* Console processes which share a common console can be sent CTRL+C or
7185 CTRL+BREAK events, provided they handle said events. */
7186 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007187 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007188 err = GetLastError();
7189 PyErr_SetFromWindowsErr(err);
7190 }
7191 else
7192 Py_RETURN_NONE;
7193 }
Brian Curtineb24d742010-04-12 17:16:38 +00007194
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7196 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007197 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007198 if (handle == NULL) {
7199 err = GetLastError();
7200 return PyErr_SetFromWindowsErr(err);
7201 }
Brian Curtineb24d742010-04-12 17:16:38 +00007202
Victor Stinner8c62be82010-05-06 00:08:46 +00007203 if (TerminateProcess(handle, sig) == 0) {
7204 err = GetLastError();
7205 result = PyErr_SetFromWindowsErr(err);
7206 } else {
7207 Py_INCREF(Py_None);
7208 result = Py_None;
7209 }
Brian Curtineb24d742010-04-12 17:16:38 +00007210
Victor Stinner8c62be82010-05-06 00:08:46 +00007211 CloseHandle(handle);
7212 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00007213}
Larry Hastings2f936352014-08-05 14:04:04 +10007214#endif /* !MS_WINDOWS */
7215#endif /* HAVE_KILL */
7216
7217
7218#ifdef HAVE_KILLPG
7219/*[clinic input]
7220os.killpg
7221
7222 pgid: pid_t
7223 signal: int
7224 /
7225
7226Kill a process group with a signal.
7227[clinic start generated code]*/
7228
Larry Hastings2f936352014-08-05 14:04:04 +10007229static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007230os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7231/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007232{
7233 /* XXX some man pages make the `pgid` parameter an int, others
7234 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7235 take the same type. Moreover, pid_t is always at least as wide as
7236 int (else compilation of this module fails), which is safe. */
7237 if (killpg(pgid, signal) == -1)
7238 return posix_error();
7239 Py_RETURN_NONE;
7240}
7241#endif /* HAVE_KILLPG */
7242
Brian Curtineb24d742010-04-12 17:16:38 +00007243
Guido van Rossumc0125471996-06-28 18:55:32 +00007244#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007245#ifdef HAVE_SYS_LOCK_H
7246#include <sys/lock.h>
7247#endif
7248
Larry Hastings2f936352014-08-05 14:04:04 +10007249/*[clinic input]
7250os.plock
7251 op: int
7252 /
7253
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007254Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007255[clinic start generated code]*/
7256
Larry Hastings2f936352014-08-05 14:04:04 +10007257static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007258os_plock_impl(PyObject *module, int op)
7259/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007260{
Victor Stinner8c62be82010-05-06 00:08:46 +00007261 if (plock(op) == -1)
7262 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007263 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007264}
Larry Hastings2f936352014-08-05 14:04:04 +10007265#endif /* HAVE_PLOCK */
7266
Guido van Rossumc0125471996-06-28 18:55:32 +00007267
Guido van Rossumb6775db1994-08-01 11:34:53 +00007268#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007269/*[clinic input]
7270os.setuid
7271
7272 uid: uid_t
7273 /
7274
7275Set the current process's user id.
7276[clinic start generated code]*/
7277
Larry Hastings2f936352014-08-05 14:04:04 +10007278static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007279os_setuid_impl(PyObject *module, uid_t uid)
7280/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007281{
Victor Stinner8c62be82010-05-06 00:08:46 +00007282 if (setuid(uid) < 0)
7283 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007284 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007285}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007286#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007287
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007288
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007289#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007290/*[clinic input]
7291os.seteuid
7292
7293 euid: uid_t
7294 /
7295
7296Set the current process's effective user id.
7297[clinic start generated code]*/
7298
Larry Hastings2f936352014-08-05 14:04:04 +10007299static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007300os_seteuid_impl(PyObject *module, uid_t euid)
7301/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007302{
7303 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007304 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007305 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007306}
7307#endif /* HAVE_SETEUID */
7308
Larry Hastings2f936352014-08-05 14:04:04 +10007309
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007310#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007311/*[clinic input]
7312os.setegid
7313
7314 egid: gid_t
7315 /
7316
7317Set the current process's effective group id.
7318[clinic start generated code]*/
7319
Larry Hastings2f936352014-08-05 14:04:04 +10007320static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007321os_setegid_impl(PyObject *module, gid_t egid)
7322/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007323{
7324 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007325 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007326 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007327}
7328#endif /* HAVE_SETEGID */
7329
Larry Hastings2f936352014-08-05 14:04:04 +10007330
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007331#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007332/*[clinic input]
7333os.setreuid
7334
7335 ruid: uid_t
7336 euid: uid_t
7337 /
7338
7339Set the current process's real and effective user ids.
7340[clinic start generated code]*/
7341
Larry Hastings2f936352014-08-05 14:04:04 +10007342static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007343os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7344/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007345{
Victor Stinner8c62be82010-05-06 00:08:46 +00007346 if (setreuid(ruid, euid) < 0) {
7347 return posix_error();
7348 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007349 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007350 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007351}
7352#endif /* HAVE_SETREUID */
7353
Larry Hastings2f936352014-08-05 14:04:04 +10007354
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007355#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007356/*[clinic input]
7357os.setregid
7358
7359 rgid: gid_t
7360 egid: gid_t
7361 /
7362
7363Set the current process's real and effective group ids.
7364[clinic start generated code]*/
7365
Larry Hastings2f936352014-08-05 14:04:04 +10007366static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007367os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7368/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007369{
7370 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007371 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007372 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007373}
7374#endif /* HAVE_SETREGID */
7375
Larry Hastings2f936352014-08-05 14:04:04 +10007376
Guido van Rossumb6775db1994-08-01 11:34:53 +00007377#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007378/*[clinic input]
7379os.setgid
7380 gid: gid_t
7381 /
7382
7383Set the current process's group id.
7384[clinic start generated code]*/
7385
Larry Hastings2f936352014-08-05 14:04:04 +10007386static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007387os_setgid_impl(PyObject *module, gid_t gid)
7388/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007389{
Victor Stinner8c62be82010-05-06 00:08:46 +00007390 if (setgid(gid) < 0)
7391 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007392 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007393}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007394#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007395
Larry Hastings2f936352014-08-05 14:04:04 +10007396
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007397#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007398/*[clinic input]
7399os.setgroups
7400
7401 groups: object
7402 /
7403
7404Set the groups of the current process to list.
7405[clinic start generated code]*/
7406
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007407static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007408os_setgroups(PyObject *module, PyObject *groups)
7409/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007410{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007411 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007412 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007413
Victor Stinner8c62be82010-05-06 00:08:46 +00007414 if (!PySequence_Check(groups)) {
7415 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7416 return NULL;
7417 }
7418 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007419 if (len < 0) {
7420 return NULL;
7421 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007422 if (len > MAX_GROUPS) {
7423 PyErr_SetString(PyExc_ValueError, "too many groups");
7424 return NULL;
7425 }
7426 for(i = 0; i < len; i++) {
7427 PyObject *elem;
7428 elem = PySequence_GetItem(groups, i);
7429 if (!elem)
7430 return NULL;
7431 if (!PyLong_Check(elem)) {
7432 PyErr_SetString(PyExc_TypeError,
7433 "groups must be integers");
7434 Py_DECREF(elem);
7435 return NULL;
7436 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007437 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007438 Py_DECREF(elem);
7439 return NULL;
7440 }
7441 }
7442 Py_DECREF(elem);
7443 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007444
Victor Stinner8c62be82010-05-06 00:08:46 +00007445 if (setgroups(len, grouplist) < 0)
7446 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007447 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007448}
7449#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007450
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007451#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7452static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007453wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007454{
Victor Stinner8c62be82010-05-06 00:08:46 +00007455 PyObject *result;
7456 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007457 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007458
Victor Stinner8c62be82010-05-06 00:08:46 +00007459 if (pid == -1)
7460 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007461
Victor Stinner8c62be82010-05-06 00:08:46 +00007462 if (struct_rusage == NULL) {
7463 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7464 if (m == NULL)
7465 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007466 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007467 Py_DECREF(m);
7468 if (struct_rusage == NULL)
7469 return NULL;
7470 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007471
Victor Stinner8c62be82010-05-06 00:08:46 +00007472 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7473 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7474 if (!result)
7475 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007476
7477#ifndef doubletime
7478#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7479#endif
7480
Victor Stinner8c62be82010-05-06 00:08:46 +00007481 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007482 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007483 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007484 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007485#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007486 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7487 SET_INT(result, 2, ru->ru_maxrss);
7488 SET_INT(result, 3, ru->ru_ixrss);
7489 SET_INT(result, 4, ru->ru_idrss);
7490 SET_INT(result, 5, ru->ru_isrss);
7491 SET_INT(result, 6, ru->ru_minflt);
7492 SET_INT(result, 7, ru->ru_majflt);
7493 SET_INT(result, 8, ru->ru_nswap);
7494 SET_INT(result, 9, ru->ru_inblock);
7495 SET_INT(result, 10, ru->ru_oublock);
7496 SET_INT(result, 11, ru->ru_msgsnd);
7497 SET_INT(result, 12, ru->ru_msgrcv);
7498 SET_INT(result, 13, ru->ru_nsignals);
7499 SET_INT(result, 14, ru->ru_nvcsw);
7500 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007501#undef SET_INT
7502
Victor Stinner8c62be82010-05-06 00:08:46 +00007503 if (PyErr_Occurred()) {
7504 Py_DECREF(result);
7505 return NULL;
7506 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007507
Victor Stinner8c62be82010-05-06 00:08:46 +00007508 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007509}
7510#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7511
Larry Hastings2f936352014-08-05 14:04:04 +10007512
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007513#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007514/*[clinic input]
7515os.wait3
7516
7517 options: int
7518Wait for completion of a child process.
7519
7520Returns a tuple of information about the child process:
7521 (pid, status, rusage)
7522[clinic start generated code]*/
7523
Larry Hastings2f936352014-08-05 14:04:04 +10007524static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007525os_wait3_impl(PyObject *module, int options)
7526/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007527{
Victor Stinner8c62be82010-05-06 00:08:46 +00007528 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007530 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007531 WAIT_TYPE status;
7532 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007533
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007534 do {
7535 Py_BEGIN_ALLOW_THREADS
7536 pid = wait3(&status, options, &ru);
7537 Py_END_ALLOW_THREADS
7538 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7539 if (pid < 0)
7540 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007541
Victor Stinner4195b5c2012-02-08 23:03:19 +01007542 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007543}
7544#endif /* HAVE_WAIT3 */
7545
Larry Hastings2f936352014-08-05 14:04:04 +10007546
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007547#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007548/*[clinic input]
7549
7550os.wait4
7551
7552 pid: pid_t
7553 options: int
7554
7555Wait for completion of a specific child process.
7556
7557Returns a tuple of information about the child process:
7558 (pid, status, rusage)
7559[clinic start generated code]*/
7560
Larry Hastings2f936352014-08-05 14:04:04 +10007561static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007562os_wait4_impl(PyObject *module, pid_t pid, int options)
7563/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007564{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007565 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007566 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007567 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007568 WAIT_TYPE status;
7569 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007570
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007571 do {
7572 Py_BEGIN_ALLOW_THREADS
7573 res = wait4(pid, &status, options, &ru);
7574 Py_END_ALLOW_THREADS
7575 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7576 if (res < 0)
7577 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007578
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007579 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007580}
7581#endif /* HAVE_WAIT4 */
7582
Larry Hastings2f936352014-08-05 14:04:04 +10007583
Ross Lagerwall7807c352011-03-17 20:20:30 +02007584#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007585/*[clinic input]
7586os.waitid
7587
7588 idtype: idtype_t
7589 Must be one of be P_PID, P_PGID or P_ALL.
7590 id: id_t
7591 The id to wait on.
7592 options: int
7593 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7594 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7595 /
7596
7597Returns the result of waiting for a process or processes.
7598
7599Returns either waitid_result or None if WNOHANG is specified and there are
7600no children in a waitable state.
7601[clinic start generated code]*/
7602
Larry Hastings2f936352014-08-05 14:04:04 +10007603static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007604os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7605/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007606{
7607 PyObject *result;
7608 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007609 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007610 siginfo_t si;
7611 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007612
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007613 do {
7614 Py_BEGIN_ALLOW_THREADS
7615 res = waitid(idtype, id, &si, options);
7616 Py_END_ALLOW_THREADS
7617 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7618 if (res < 0)
7619 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007620
7621 if (si.si_pid == 0)
7622 Py_RETURN_NONE;
7623
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007624 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007625 if (!result)
7626 return NULL;
7627
7628 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007629 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007630 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7631 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7632 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7633 if (PyErr_Occurred()) {
7634 Py_DECREF(result);
7635 return NULL;
7636 }
7637
7638 return result;
7639}
Larry Hastings2f936352014-08-05 14:04:04 +10007640#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007641
Larry Hastings2f936352014-08-05 14:04:04 +10007642
7643#if defined(HAVE_WAITPID)
7644/*[clinic input]
7645os.waitpid
7646 pid: pid_t
7647 options: int
7648 /
7649
7650Wait for completion of a given child process.
7651
7652Returns a tuple of information regarding the child process:
7653 (pid, status)
7654
7655The options argument is ignored on Windows.
7656[clinic start generated code]*/
7657
Larry Hastings2f936352014-08-05 14:04:04 +10007658static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007659os_waitpid_impl(PyObject *module, pid_t pid, int options)
7660/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007661{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007662 pid_t res;
7663 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007664 WAIT_TYPE status;
7665 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007666
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007667 do {
7668 Py_BEGIN_ALLOW_THREADS
7669 res = waitpid(pid, &status, options);
7670 Py_END_ALLOW_THREADS
7671 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7672 if (res < 0)
7673 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007674
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007675 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007676}
Tim Petersab034fa2002-02-01 11:27:43 +00007677#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007678/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007679/*[clinic input]
7680os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007681 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007682 options: int
7683 /
7684
7685Wait for completion of a given process.
7686
7687Returns a tuple of information regarding the process:
7688 (pid, status << 8)
7689
7690The options argument is ignored on Windows.
7691[clinic start generated code]*/
7692
Larry Hastings2f936352014-08-05 14:04:04 +10007693static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007694os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007695/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007696{
7697 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007698 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007699 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007700
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007701 do {
7702 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007703 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007704 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007705 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007706 Py_END_ALLOW_THREADS
7707 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007708 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007709 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007710
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007712 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007713}
Larry Hastings2f936352014-08-05 14:04:04 +10007714#endif
7715
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007716
Guido van Rossumad0ee831995-03-01 10:34:45 +00007717#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007718/*[clinic input]
7719os.wait
7720
7721Wait for completion of a child process.
7722
7723Returns a tuple of information about the child process:
7724 (pid, status)
7725[clinic start generated code]*/
7726
Larry Hastings2f936352014-08-05 14:04:04 +10007727static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007728os_wait_impl(PyObject *module)
7729/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007730{
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007732 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007733 WAIT_TYPE status;
7734 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007735
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007736 do {
7737 Py_BEGIN_ALLOW_THREADS
7738 pid = wait(&status);
7739 Py_END_ALLOW_THREADS
7740 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7741 if (pid < 0)
7742 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007743
Victor Stinner8c62be82010-05-06 00:08:46 +00007744 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007745}
Larry Hastings2f936352014-08-05 14:04:04 +10007746#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007747
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007748
Larry Hastings9cf065c2012-06-22 16:30:09 -07007749#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007750/*[clinic input]
7751os.readlink
7752
7753 path: path_t
7754 *
7755 dir_fd: dir_fd(requires='readlinkat') = None
7756
7757Return a string representing the path to which the symbolic link points.
7758
7759If dir_fd is not None, it should be a file descriptor open to a directory,
7760and path should be relative; path will then be relative to that directory.
7761
7762dir_fd may not be implemented on your platform. If it is unavailable,
7763using it will raise a NotImplementedError.
7764[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007765
Barry Warsaw53699e91996-12-10 23:23:01 +00007766static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007767os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7768/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007769{
Berker Peksage0b5b202018-08-15 13:03:41 +03007770#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007771 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007772 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007773
7774 Py_BEGIN_ALLOW_THREADS
7775#ifdef HAVE_READLINKAT
7776 if (dir_fd != DEFAULT_DIR_FD)
7777 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7778 else
7779#endif
7780 length = readlink(path->narrow, buffer, MAXPATHLEN);
7781 Py_END_ALLOW_THREADS
7782
7783 if (length < 0) {
7784 return path_error(path);
7785 }
7786 buffer[length] = '\0';
7787
7788 if (PyUnicode_Check(path->object))
7789 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7790 else
7791 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007792#elif defined(MS_WINDOWS)
7793 DWORD n_bytes_returned;
7794 DWORD io_result;
7795 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007796 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7797 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
7798 const wchar_t *print_name;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007799 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007800
Larry Hastings2f936352014-08-05 14:04:04 +10007801 /* First get a handle to the reparse point */
7802 Py_BEGIN_ALLOW_THREADS
7803 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007804 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007805 0,
7806 0,
7807 0,
7808 OPEN_EXISTING,
7809 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7810 0);
7811 Py_END_ALLOW_THREADS
7812
Berker Peksage0b5b202018-08-15 13:03:41 +03007813 if (reparse_point_handle == INVALID_HANDLE_VALUE) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007814 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007815 }
Larry Hastings2f936352014-08-05 14:04:04 +10007816
7817 Py_BEGIN_ALLOW_THREADS
7818 /* New call DeviceIoControl to read the reparse point */
7819 io_result = DeviceIoControl(
7820 reparse_point_handle,
7821 FSCTL_GET_REPARSE_POINT,
7822 0, 0, /* in buffer */
7823 target_buffer, sizeof(target_buffer),
7824 &n_bytes_returned,
7825 0 /* we're not using OVERLAPPED_IO */
7826 );
7827 CloseHandle(reparse_point_handle);
7828 Py_END_ALLOW_THREADS
7829
Berker Peksage0b5b202018-08-15 13:03:41 +03007830 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007831 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007832 }
Larry Hastings2f936352014-08-05 14:04:04 +10007833
7834 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7835 {
7836 PyErr_SetString(PyExc_ValueError,
7837 "not a symbolic link");
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007838 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007839 }
SSE43c34aad2018-02-13 00:10:35 +07007840 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7841 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007842
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007843 result = PyUnicode_FromWideChar(print_name,
7844 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
7845 if (path->narrow) {
7846 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Berker Peksage0b5b202018-08-15 13:03:41 +03007847 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007848 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007849#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007850}
Berker Peksage0b5b202018-08-15 13:03:41 +03007851#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007852
Larry Hastings9cf065c2012-06-22 16:30:09 -07007853#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007854
7855#if defined(MS_WINDOWS)
7856
Steve Dower6921e732018-03-05 14:26:08 -08007857/* Remove the last portion of the path - return 0 on success */
7858static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007859_dirnameW(WCHAR *path)
7860{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007861 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007862 size_t length = wcsnlen_s(path, MAX_PATH);
7863 if (length == MAX_PATH) {
7864 return -1;
7865 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007866
7867 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007868 for(ptr = path + length; ptr != path; ptr--) {
7869 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007870 break;
Steve Dower6921e732018-03-05 14:26:08 -08007871 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007872 }
7873 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007874 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007875}
7876
Victor Stinner31b3b922013-06-05 01:49:17 +02007877/* Is this path absolute? */
7878static int
7879_is_absW(const WCHAR *path)
7880{
Steve Dower6921e732018-03-05 14:26:08 -08007881 return path[0] == L'\\' || path[0] == L'/' ||
7882 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007883}
7884
Steve Dower6921e732018-03-05 14:26:08 -08007885/* join root and rest with a backslash - return 0 on success */
7886static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007887_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7888{
Victor Stinner31b3b922013-06-05 01:49:17 +02007889 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007890 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007891 }
7892
Steve Dower6921e732018-03-05 14:26:08 -08007893 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7894 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007895 }
Steve Dower6921e732018-03-05 14:26:08 -08007896
7897 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7898 return -1;
7899 }
7900
7901 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007902}
7903
Victor Stinner31b3b922013-06-05 01:49:17 +02007904/* Return True if the path at src relative to dest is a directory */
7905static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007906_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007907{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007908 WIN32_FILE_ATTRIBUTE_DATA src_info;
7909 WCHAR dest_parent[MAX_PATH];
7910 WCHAR src_resolved[MAX_PATH] = L"";
7911
7912 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007913 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7914 _dirnameW(dest_parent)) {
7915 return 0;
7916 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007917 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007918 if (_joinW(src_resolved, dest_parent, src)) {
7919 return 0;
7920 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007921 return (
7922 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7923 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7924 );
7925}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007926#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007927
Larry Hastings2f936352014-08-05 14:04:04 +10007928
7929/*[clinic input]
7930os.symlink
7931 src: path_t
7932 dst: path_t
7933 target_is_directory: bool = False
7934 *
7935 dir_fd: dir_fd(requires='symlinkat')=None
7936
7937# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7938
7939Create a symbolic link pointing to src named dst.
7940
7941target_is_directory is required on Windows if the target is to be
7942 interpreted as a directory. (On Windows, symlink requires
7943 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7944 target_is_directory is ignored on non-Windows platforms.
7945
7946If dir_fd is not None, it should be a file descriptor open to a directory,
7947 and path should be relative; path will then be relative to that directory.
7948dir_fd may not be implemented on your platform.
7949 If it is unavailable, using it will raise a NotImplementedError.
7950
7951[clinic start generated code]*/
7952
Larry Hastings2f936352014-08-05 14:04:04 +10007953static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007954os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007955 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007956/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007957{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007958#ifdef MS_WINDOWS
7959 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007960 DWORD flags = 0;
7961
7962 /* Assumed true, set to false if detected to not be available. */
7963 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007964#else
7965 int result;
7966#endif
7967
Larry Hastings9cf065c2012-06-22 16:30:09 -07007968#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007969
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007970 if (windows_has_symlink_unprivileged_flag) {
7971 /* Allow non-admin symlinks if system allows it. */
7972 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
7973 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007974
Larry Hastings9cf065c2012-06-22 16:30:09 -07007975 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007976 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007977 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
7978 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
7979 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
7980 }
7981
7982 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08007983 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007984 Py_END_ALLOW_THREADS
7985
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007986 if (windows_has_symlink_unprivileged_flag && !result &&
7987 ERROR_INVALID_PARAMETER == GetLastError()) {
7988
7989 Py_BEGIN_ALLOW_THREADS
7990 _Py_BEGIN_SUPPRESS_IPH
7991 /* This error might be caused by
7992 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
7993 Try again, and update windows_has_symlink_unprivileged_flag if we
7994 are successful this time.
7995
7996 NOTE: There is a risk of a race condition here if there are other
7997 conditions than the flag causing ERROR_INVALID_PARAMETER, and
7998 another process (or thread) changes that condition in between our
7999 calls to CreateSymbolicLink.
8000 */
8001 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8002 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8003 _Py_END_SUPPRESS_IPH
8004 Py_END_ALLOW_THREADS
8005
8006 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8007 windows_has_symlink_unprivileged_flag = FALSE;
8008 }
8009 }
8010
Larry Hastings2f936352014-08-05 14:04:04 +10008011 if (!result)
8012 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008013
8014#else
8015
Steve Dower6921e732018-03-05 14:26:08 -08008016 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8017 PyErr_SetString(PyExc_ValueError,
8018 "symlink: src and dst must be the same type");
8019 return NULL;
8020 }
8021
Larry Hastings9cf065c2012-06-22 16:30:09 -07008022 Py_BEGIN_ALLOW_THREADS
8023#if HAVE_SYMLINKAT
8024 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10008025 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008026 else
8027#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008028 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008029 Py_END_ALLOW_THREADS
8030
Larry Hastings2f936352014-08-05 14:04:04 +10008031 if (result)
8032 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008033#endif
8034
Larry Hastings2f936352014-08-05 14:04:04 +10008035 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008036}
8037#endif /* HAVE_SYMLINK */
8038
Larry Hastings9cf065c2012-06-22 16:30:09 -07008039
Brian Curtind40e6f72010-07-08 21:39:08 +00008040
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008041
Larry Hastings605a62d2012-06-24 04:33:36 -07008042static PyStructSequence_Field times_result_fields[] = {
8043 {"user", "user time"},
8044 {"system", "system time"},
8045 {"children_user", "user time of children"},
8046 {"children_system", "system time of children"},
8047 {"elapsed", "elapsed time since an arbitrary point in the past"},
8048 {NULL}
8049};
8050
8051PyDoc_STRVAR(times_result__doc__,
8052"times_result: Result from os.times().\n\n\
8053This object may be accessed either as a tuple of\n\
8054 (user, system, children_user, children_system, elapsed),\n\
8055or via the attributes user, system, children_user, children_system,\n\
8056and elapsed.\n\
8057\n\
8058See os.times for more information.");
8059
8060static PyStructSequence_Desc times_result_desc = {
8061 "times_result", /* name */
8062 times_result__doc__, /* doc */
8063 times_result_fields,
8064 5
8065};
8066
Eddie Elizondo474eedf2018-11-13 04:09:31 -08008067static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07008068
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008069#ifdef MS_WINDOWS
8070#define HAVE_TIMES /* mandatory, for the method table */
8071#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008072
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008073#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008074
8075static PyObject *
8076build_times_result(double user, double system,
8077 double children_user, double children_system,
8078 double elapsed)
8079{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08008080 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008081 if (value == NULL)
8082 return NULL;
8083
8084#define SET(i, field) \
8085 { \
8086 PyObject *o = PyFloat_FromDouble(field); \
8087 if (!o) { \
8088 Py_DECREF(value); \
8089 return NULL; \
8090 } \
8091 PyStructSequence_SET_ITEM(value, i, o); \
8092 } \
8093
8094 SET(0, user);
8095 SET(1, system);
8096 SET(2, children_user);
8097 SET(3, children_system);
8098 SET(4, elapsed);
8099
8100#undef SET
8101
8102 return value;
8103}
8104
Larry Hastings605a62d2012-06-24 04:33:36 -07008105
Larry Hastings2f936352014-08-05 14:04:04 +10008106#ifndef MS_WINDOWS
8107#define NEED_TICKS_PER_SECOND
8108static long ticks_per_second = -1;
8109#endif /* MS_WINDOWS */
8110
8111/*[clinic input]
8112os.times
8113
8114Return a collection containing process timing information.
8115
8116The object returned behaves like a named tuple with these fields:
8117 (utime, stime, cutime, cstime, elapsed_time)
8118All fields are floating point numbers.
8119[clinic start generated code]*/
8120
Larry Hastings2f936352014-08-05 14:04:04 +10008121static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008122os_times_impl(PyObject *module)
8123/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008124#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008125{
Victor Stinner8c62be82010-05-06 00:08:46 +00008126 FILETIME create, exit, kernel, user;
8127 HANDLE hProc;
8128 hProc = GetCurrentProcess();
8129 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8130 /* The fields of a FILETIME structure are the hi and lo part
8131 of a 64-bit value expressed in 100 nanosecond units.
8132 1e7 is one second in such units; 1e-7 the inverse.
8133 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8134 */
Larry Hastings605a62d2012-06-24 04:33:36 -07008135 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00008136 (double)(user.dwHighDateTime*429.4967296 +
8137 user.dwLowDateTime*1e-7),
8138 (double)(kernel.dwHighDateTime*429.4967296 +
8139 kernel.dwLowDateTime*1e-7),
8140 (double)0,
8141 (double)0,
8142 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008143}
Larry Hastings2f936352014-08-05 14:04:04 +10008144#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008145{
Larry Hastings2f936352014-08-05 14:04:04 +10008146
8147
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008148 struct tms t;
8149 clock_t c;
8150 errno = 0;
8151 c = times(&t);
8152 if (c == (clock_t) -1)
8153 return posix_error();
8154 return build_times_result(
8155 (double)t.tms_utime / ticks_per_second,
8156 (double)t.tms_stime / ticks_per_second,
8157 (double)t.tms_cutime / ticks_per_second,
8158 (double)t.tms_cstime / ticks_per_second,
8159 (double)c / ticks_per_second);
8160}
Larry Hastings2f936352014-08-05 14:04:04 +10008161#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008162#endif /* HAVE_TIMES */
8163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008164
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008165#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008166/*[clinic input]
8167os.getsid
8168
8169 pid: pid_t
8170 /
8171
8172Call the system call getsid(pid) and return the result.
8173[clinic start generated code]*/
8174
Larry Hastings2f936352014-08-05 14:04:04 +10008175static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008176os_getsid_impl(PyObject *module, pid_t pid)
8177/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008178{
Victor Stinner8c62be82010-05-06 00:08:46 +00008179 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008180 sid = getsid(pid);
8181 if (sid < 0)
8182 return posix_error();
8183 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008184}
8185#endif /* HAVE_GETSID */
8186
8187
Guido van Rossumb6775db1994-08-01 11:34:53 +00008188#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008189/*[clinic input]
8190os.setsid
8191
8192Call the system call setsid().
8193[clinic start generated code]*/
8194
Larry Hastings2f936352014-08-05 14:04:04 +10008195static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008196os_setsid_impl(PyObject *module)
8197/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008198{
Victor Stinner8c62be82010-05-06 00:08:46 +00008199 if (setsid() < 0)
8200 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008201 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008202}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008203#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008204
Larry Hastings2f936352014-08-05 14:04:04 +10008205
Guido van Rossumb6775db1994-08-01 11:34:53 +00008206#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008207/*[clinic input]
8208os.setpgid
8209
8210 pid: pid_t
8211 pgrp: pid_t
8212 /
8213
8214Call the system call setpgid(pid, pgrp).
8215[clinic start generated code]*/
8216
Larry Hastings2f936352014-08-05 14:04:04 +10008217static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008218os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8219/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008220{
Victor Stinner8c62be82010-05-06 00:08:46 +00008221 if (setpgid(pid, pgrp) < 0)
8222 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008223 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008224}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008225#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008226
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008227
Guido van Rossumb6775db1994-08-01 11:34:53 +00008228#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008229/*[clinic input]
8230os.tcgetpgrp
8231
8232 fd: int
8233 /
8234
8235Return the process group associated with the terminal specified by fd.
8236[clinic start generated code]*/
8237
Larry Hastings2f936352014-08-05 14:04:04 +10008238static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008239os_tcgetpgrp_impl(PyObject *module, int fd)
8240/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008241{
8242 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008243 if (pgid < 0)
8244 return posix_error();
8245 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008246}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008247#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008249
Guido van Rossumb6775db1994-08-01 11:34:53 +00008250#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008251/*[clinic input]
8252os.tcsetpgrp
8253
8254 fd: int
8255 pgid: pid_t
8256 /
8257
8258Set the process group associated with the terminal specified by fd.
8259[clinic start generated code]*/
8260
Larry Hastings2f936352014-08-05 14:04:04 +10008261static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008262os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8263/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008264{
Victor Stinner8c62be82010-05-06 00:08:46 +00008265 if (tcsetpgrp(fd, pgid) < 0)
8266 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008267 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008268}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008269#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008270
Guido van Rossum687dd131993-05-17 08:34:16 +00008271/* Functions acting on file descriptors */
8272
Victor Stinnerdaf45552013-08-28 00:53:59 +02008273#ifdef O_CLOEXEC
8274extern int _Py_open_cloexec_works;
8275#endif
8276
Larry Hastings2f936352014-08-05 14:04:04 +10008277
8278/*[clinic input]
8279os.open -> int
8280 path: path_t
8281 flags: int
8282 mode: int = 0o777
8283 *
8284 dir_fd: dir_fd(requires='openat') = None
8285
8286# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8287
8288Open a file for low level IO. Returns a file descriptor (integer).
8289
8290If dir_fd is not None, it should be a file descriptor open to a directory,
8291 and path should be relative; path will then be relative to that directory.
8292dir_fd may not be implemented on your platform.
8293 If it is unavailable, using it will raise a NotImplementedError.
8294[clinic start generated code]*/
8295
Larry Hastings2f936352014-08-05 14:04:04 +10008296static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008297os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8298/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008299{
8300 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008301 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008302
Victor Stinnerdaf45552013-08-28 00:53:59 +02008303#ifdef O_CLOEXEC
8304 int *atomic_flag_works = &_Py_open_cloexec_works;
8305#elif !defined(MS_WINDOWS)
8306 int *atomic_flag_works = NULL;
8307#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008308
Victor Stinnerdaf45552013-08-28 00:53:59 +02008309#ifdef MS_WINDOWS
8310 flags |= O_NOINHERIT;
8311#elif defined(O_CLOEXEC)
8312 flags |= O_CLOEXEC;
8313#endif
8314
Steve Dowerb82e17e2019-05-23 08:45:22 -07008315 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
8316 return -1;
8317 }
8318
Steve Dower8fc89802015-04-12 00:26:27 -04008319 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008320 do {
8321 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008322#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008323 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008324#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008325#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008326 if (dir_fd != DEFAULT_DIR_FD)
8327 fd = openat(dir_fd, path->narrow, flags, mode);
8328 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008329#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008330 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008331#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008332 Py_END_ALLOW_THREADS
8333 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008334 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008335
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008336 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008337 if (!async_err)
8338 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008339 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008340 }
8341
Victor Stinnerdaf45552013-08-28 00:53:59 +02008342#ifndef MS_WINDOWS
8343 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8344 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008345 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008346 }
8347#endif
8348
Larry Hastings2f936352014-08-05 14:04:04 +10008349 return fd;
8350}
8351
8352
8353/*[clinic input]
8354os.close
8355
8356 fd: int
8357
8358Close a file descriptor.
8359[clinic start generated code]*/
8360
Barry Warsaw53699e91996-12-10 23:23:01 +00008361static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008362os_close_impl(PyObject *module, int fd)
8363/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008364{
Larry Hastings2f936352014-08-05 14:04:04 +10008365 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008366 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8367 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8368 * for more details.
8369 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008370 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008371 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008372 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008373 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008374 Py_END_ALLOW_THREADS
8375 if (res < 0)
8376 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008377 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008378}
8379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008380
Larry Hastings2f936352014-08-05 14:04:04 +10008381/*[clinic input]
8382os.closerange
8383
8384 fd_low: int
8385 fd_high: int
8386 /
8387
8388Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8389[clinic start generated code]*/
8390
Larry Hastings2f936352014-08-05 14:04:04 +10008391static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008392os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8393/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008394{
8395 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008396 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008397 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008398 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008399 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008400 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008401 Py_END_ALLOW_THREADS
8402 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008403}
8404
8405
Larry Hastings2f936352014-08-05 14:04:04 +10008406/*[clinic input]
8407os.dup -> int
8408
8409 fd: int
8410 /
8411
8412Return a duplicate of a file descriptor.
8413[clinic start generated code]*/
8414
Larry Hastings2f936352014-08-05 14:04:04 +10008415static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008416os_dup_impl(PyObject *module, int fd)
8417/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008418{
8419 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008420}
8421
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008422
Larry Hastings2f936352014-08-05 14:04:04 +10008423/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008424os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008425 fd: int
8426 fd2: int
8427 inheritable: bool=True
8428
8429Duplicate file descriptor.
8430[clinic start generated code]*/
8431
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008432static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008433os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008434/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008435{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008436 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008437#if defined(HAVE_DUP3) && \
8438 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8439 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008440 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008441#endif
8442
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008443 if (fd < 0 || fd2 < 0) {
8444 posix_error();
8445 return -1;
8446 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008447
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008448 /* dup2() can fail with EINTR if the target FD is already open, because it
8449 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8450 * upon close(), and therefore below.
8451 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008452#ifdef MS_WINDOWS
8453 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008454 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008455 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008456 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008457 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008458 if (res < 0) {
8459 posix_error();
8460 return -1;
8461 }
8462 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008463
8464 /* Character files like console cannot be make non-inheritable */
8465 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8466 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008467 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008468 }
8469
8470#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8471 Py_BEGIN_ALLOW_THREADS
8472 if (!inheritable)
8473 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8474 else
8475 res = dup2(fd, fd2);
8476 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008477 if (res < 0) {
8478 posix_error();
8479 return -1;
8480 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008481
8482#else
8483
8484#ifdef HAVE_DUP3
8485 if (!inheritable && dup3_works != 0) {
8486 Py_BEGIN_ALLOW_THREADS
8487 res = dup3(fd, fd2, O_CLOEXEC);
8488 Py_END_ALLOW_THREADS
8489 if (res < 0) {
8490 if (dup3_works == -1)
8491 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008492 if (dup3_works) {
8493 posix_error();
8494 return -1;
8495 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008496 }
8497 }
8498
8499 if (inheritable || dup3_works == 0)
8500 {
8501#endif
8502 Py_BEGIN_ALLOW_THREADS
8503 res = dup2(fd, fd2);
8504 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008505 if (res < 0) {
8506 posix_error();
8507 return -1;
8508 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008509
8510 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8511 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008512 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008513 }
8514#ifdef HAVE_DUP3
8515 }
8516#endif
8517
8518#endif
8519
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008520 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008521}
8522
Larry Hastings2f936352014-08-05 14:04:04 +10008523
Ross Lagerwall7807c352011-03-17 20:20:30 +02008524#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008525/*[clinic input]
8526os.lockf
8527
8528 fd: int
8529 An open file descriptor.
8530 command: int
8531 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8532 length: Py_off_t
8533 The number of bytes to lock, starting at the current position.
8534 /
8535
8536Apply, test or remove a POSIX lock on an open file descriptor.
8537
8538[clinic start generated code]*/
8539
Larry Hastings2f936352014-08-05 14:04:04 +10008540static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008541os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8542/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008543{
8544 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008545
8546 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008547 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008548 Py_END_ALLOW_THREADS
8549
8550 if (res < 0)
8551 return posix_error();
8552
8553 Py_RETURN_NONE;
8554}
Larry Hastings2f936352014-08-05 14:04:04 +10008555#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008556
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008557
Larry Hastings2f936352014-08-05 14:04:04 +10008558/*[clinic input]
8559os.lseek -> Py_off_t
8560
8561 fd: int
8562 position: Py_off_t
8563 how: int
8564 /
8565
8566Set the position of a file descriptor. Return the new position.
8567
8568Return the new cursor position in number of bytes
8569relative to the beginning of the file.
8570[clinic start generated code]*/
8571
Larry Hastings2f936352014-08-05 14:04:04 +10008572static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008573os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8574/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008575{
8576 Py_off_t result;
8577
Guido van Rossum687dd131993-05-17 08:34:16 +00008578#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008579 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8580 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008581 case 0: how = SEEK_SET; break;
8582 case 1: how = SEEK_CUR; break;
8583 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008584 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008585#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008586
Victor Stinner8c62be82010-05-06 00:08:46 +00008587 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008588 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008589#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008590 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008591#else
Larry Hastings2f936352014-08-05 14:04:04 +10008592 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008593#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008594 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008595 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008596 if (result < 0)
8597 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008598
Larry Hastings2f936352014-08-05 14:04:04 +10008599 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008600}
8601
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008602
Larry Hastings2f936352014-08-05 14:04:04 +10008603/*[clinic input]
8604os.read
8605 fd: int
8606 length: Py_ssize_t
8607 /
8608
8609Read from a file descriptor. Returns a bytes object.
8610[clinic start generated code]*/
8611
Larry Hastings2f936352014-08-05 14:04:04 +10008612static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008613os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8614/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008615{
Victor Stinner8c62be82010-05-06 00:08:46 +00008616 Py_ssize_t n;
8617 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008618
8619 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008620 errno = EINVAL;
8621 return posix_error();
8622 }
Larry Hastings2f936352014-08-05 14:04:04 +10008623
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008624 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008625
8626 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008627 if (buffer == NULL)
8628 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008629
Victor Stinner66aab0c2015-03-19 22:53:20 +01008630 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8631 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008632 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008633 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008634 }
Larry Hastings2f936352014-08-05 14:04:04 +10008635
8636 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008637 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008638
Victor Stinner8c62be82010-05-06 00:08:46 +00008639 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008640}
8641
Ross Lagerwall7807c352011-03-17 20:20:30 +02008642#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008643 || defined(__APPLE__))) \
8644 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8645 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8646static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008647iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008648{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008649 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008650
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008651 *iov = PyMem_New(struct iovec, cnt);
8652 if (*iov == NULL) {
8653 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008654 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008655 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008656
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008657 *buf = PyMem_New(Py_buffer, cnt);
8658 if (*buf == NULL) {
8659 PyMem_Del(*iov);
8660 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008661 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008662 }
8663
8664 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008665 PyObject *item = PySequence_GetItem(seq, i);
8666 if (item == NULL)
8667 goto fail;
8668 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8669 Py_DECREF(item);
8670 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008671 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008672 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008673 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008674 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008675 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008676 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008677
8678fail:
8679 PyMem_Del(*iov);
8680 for (j = 0; j < i; j++) {
8681 PyBuffer_Release(&(*buf)[j]);
8682 }
8683 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008684 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008685}
8686
8687static void
8688iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8689{
8690 int i;
8691 PyMem_Del(iov);
8692 for (i = 0; i < cnt; i++) {
8693 PyBuffer_Release(&buf[i]);
8694 }
8695 PyMem_Del(buf);
8696}
8697#endif
8698
Larry Hastings2f936352014-08-05 14:04:04 +10008699
Ross Lagerwall7807c352011-03-17 20:20:30 +02008700#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008701/*[clinic input]
8702os.readv -> Py_ssize_t
8703
8704 fd: int
8705 buffers: object
8706 /
8707
8708Read from a file descriptor fd into an iterable of buffers.
8709
8710The buffers should be mutable buffers accepting bytes.
8711readv will transfer data into each buffer until it is full
8712and then move on to the next buffer in the sequence to hold
8713the rest of the data.
8714
8715readv returns the total number of bytes read,
8716which may be less than the total capacity of all the buffers.
8717[clinic start generated code]*/
8718
Larry Hastings2f936352014-08-05 14:04:04 +10008719static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008720os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8721/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008722{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008723 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008724 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008725 struct iovec *iov;
8726 Py_buffer *buf;
8727
Larry Hastings2f936352014-08-05 14:04:04 +10008728 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008729 PyErr_SetString(PyExc_TypeError,
8730 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008731 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008732 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008733
Larry Hastings2f936352014-08-05 14:04:04 +10008734 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008735 if (cnt < 0)
8736 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008737
8738 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8739 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008740
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008741 do {
8742 Py_BEGIN_ALLOW_THREADS
8743 n = readv(fd, iov, cnt);
8744 Py_END_ALLOW_THREADS
8745 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008746
8747 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008748 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008749 if (!async_err)
8750 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008751 return -1;
8752 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008753
Larry Hastings2f936352014-08-05 14:04:04 +10008754 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008755}
Larry Hastings2f936352014-08-05 14:04:04 +10008756#endif /* HAVE_READV */
8757
Ross Lagerwall7807c352011-03-17 20:20:30 +02008758
8759#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008760/*[clinic input]
8761# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8762os.pread
8763
8764 fd: int
8765 length: int
8766 offset: Py_off_t
8767 /
8768
8769Read a number of bytes from a file descriptor starting at a particular offset.
8770
8771Read length bytes from file descriptor fd, starting at offset bytes from
8772the beginning of the file. The file offset remains unchanged.
8773[clinic start generated code]*/
8774
Larry Hastings2f936352014-08-05 14:04:04 +10008775static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008776os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8777/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008778{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008779 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008780 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008781 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008782
Larry Hastings2f936352014-08-05 14:04:04 +10008783 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008784 errno = EINVAL;
8785 return posix_error();
8786 }
Larry Hastings2f936352014-08-05 14:04:04 +10008787 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008788 if (buffer == NULL)
8789 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008790
8791 do {
8792 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008793 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008794 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008795 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008796 Py_END_ALLOW_THREADS
8797 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8798
Ross Lagerwall7807c352011-03-17 20:20:30 +02008799 if (n < 0) {
8800 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008801 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008802 }
Larry Hastings2f936352014-08-05 14:04:04 +10008803 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008804 _PyBytes_Resize(&buffer, n);
8805 return buffer;
8806}
Larry Hastings2f936352014-08-05 14:04:04 +10008807#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008808
Pablo Galindo4defba32018-01-27 16:16:37 +00008809#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8810/*[clinic input]
8811os.preadv -> Py_ssize_t
8812
8813 fd: int
8814 buffers: object
8815 offset: Py_off_t
8816 flags: int = 0
8817 /
8818
8819Reads from a file descriptor into a number of mutable bytes-like objects.
8820
8821Combines the functionality of readv() and pread(). As readv(), it will
8822transfer data into each buffer until it is full and then move on to the next
8823buffer in the sequence to hold the rest of the data. Its fourth argument,
8824specifies the file offset at which the input operation is to be performed. It
8825will return the total number of bytes read (which can be less than the total
8826capacity of all the objects).
8827
8828The flags argument contains a bitwise OR of zero or more of the following flags:
8829
8830- RWF_HIPRI
8831- RWF_NOWAIT
8832
8833Using non-zero flags requires Linux 4.6 or newer.
8834[clinic start generated code]*/
8835
8836static Py_ssize_t
8837os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8838 int flags)
8839/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8840{
8841 Py_ssize_t cnt, n;
8842 int async_err = 0;
8843 struct iovec *iov;
8844 Py_buffer *buf;
8845
8846 if (!PySequence_Check(buffers)) {
8847 PyErr_SetString(PyExc_TypeError,
8848 "preadv2() arg 2 must be a sequence");
8849 return -1;
8850 }
8851
8852 cnt = PySequence_Size(buffers);
8853 if (cnt < 0) {
8854 return -1;
8855 }
8856
8857#ifndef HAVE_PREADV2
8858 if(flags != 0) {
8859 argument_unavailable_error("preadv2", "flags");
8860 return -1;
8861 }
8862#endif
8863
8864 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8865 return -1;
8866 }
8867#ifdef HAVE_PREADV2
8868 do {
8869 Py_BEGIN_ALLOW_THREADS
8870 _Py_BEGIN_SUPPRESS_IPH
8871 n = preadv2(fd, iov, cnt, offset, flags);
8872 _Py_END_SUPPRESS_IPH
8873 Py_END_ALLOW_THREADS
8874 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8875#else
8876 do {
8877 Py_BEGIN_ALLOW_THREADS
8878 _Py_BEGIN_SUPPRESS_IPH
8879 n = preadv(fd, iov, cnt, offset);
8880 _Py_END_SUPPRESS_IPH
8881 Py_END_ALLOW_THREADS
8882 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8883#endif
8884
8885 iov_cleanup(iov, buf, cnt);
8886 if (n < 0) {
8887 if (!async_err) {
8888 posix_error();
8889 }
8890 return -1;
8891 }
8892
8893 return n;
8894}
8895#endif /* HAVE_PREADV */
8896
Larry Hastings2f936352014-08-05 14:04:04 +10008897
8898/*[clinic input]
8899os.write -> Py_ssize_t
8900
8901 fd: int
8902 data: Py_buffer
8903 /
8904
8905Write a bytes object to a file descriptor.
8906[clinic start generated code]*/
8907
Larry Hastings2f936352014-08-05 14:04:04 +10008908static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008909os_write_impl(PyObject *module, int fd, Py_buffer *data)
8910/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008911{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008912 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008913}
8914
8915#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008916PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008917"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008918sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008919 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008920Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008921
Larry Hastings2f936352014-08-05 14:04:04 +10008922/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008923static PyObject *
8924posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8925{
8926 int in, out;
8927 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008928 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008929 off_t offset;
8930
8931#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8932#ifndef __APPLE__
8933 Py_ssize_t len;
8934#endif
8935 PyObject *headers = NULL, *trailers = NULL;
8936 Py_buffer *hbuf, *tbuf;
8937 off_t sbytes;
8938 struct sf_hdtr sf;
8939 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008940 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008941 static char *keywords[] = {"out", "in",
8942 "offset", "count",
8943 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008944
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008945 sf.headers = NULL;
8946 sf.trailers = NULL;
8947
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008948#ifdef __APPLE__
8949 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008950 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008951#else
8952 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008953 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008954#endif
8955 &headers, &trailers, &flags))
8956 return NULL;
8957 if (headers != NULL) {
8958 if (!PySequence_Check(headers)) {
8959 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008960 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008961 return NULL;
8962 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008963 Py_ssize_t i = PySequence_Size(headers);
8964 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008965 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008966 if (i > INT_MAX) {
8967 PyErr_SetString(PyExc_OverflowError,
8968 "sendfile() header is too large");
8969 return NULL;
8970 }
8971 if (i > 0) {
8972 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008973 if (iov_setup(&(sf.headers), &hbuf,
8974 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008975 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008976#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008977 for (i = 0; i < sf.hdr_cnt; i++) {
8978 Py_ssize_t blen = sf.headers[i].iov_len;
8979# define OFF_T_MAX 0x7fffffffffffffff
8980 if (sbytes >= OFF_T_MAX - blen) {
8981 PyErr_SetString(PyExc_OverflowError,
8982 "sendfile() header is too large");
8983 return NULL;
8984 }
8985 sbytes += blen;
8986 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008987#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008988 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008989 }
8990 }
8991 if (trailers != NULL) {
8992 if (!PySequence_Check(trailers)) {
8993 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008994 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008995 return NULL;
8996 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008997 Py_ssize_t i = PySequence_Size(trailers);
8998 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008999 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009000 if (i > INT_MAX) {
9001 PyErr_SetString(PyExc_OverflowError,
9002 "sendfile() trailer is too large");
9003 return NULL;
9004 }
9005 if (i > 0) {
9006 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009007 if (iov_setup(&(sf.trailers), &tbuf,
9008 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009009 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009010 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009011 }
9012 }
9013
Steve Dower8fc89802015-04-12 00:26:27 -04009014 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009015 do {
9016 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009017#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009018 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009019#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009020 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009021#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009022 Py_END_ALLOW_THREADS
9023 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009024 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009025
9026 if (sf.headers != NULL)
9027 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9028 if (sf.trailers != NULL)
9029 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9030
9031 if (ret < 0) {
9032 if ((errno == EAGAIN) || (errno == EBUSY)) {
9033 if (sbytes != 0) {
9034 // some data has been sent
9035 goto done;
9036 }
9037 else {
9038 // no data has been sent; upper application is supposed
9039 // to retry on EAGAIN or EBUSY
9040 return posix_error();
9041 }
9042 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009043 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009044 }
9045 goto done;
9046
9047done:
9048 #if !defined(HAVE_LARGEFILE_SUPPORT)
9049 return Py_BuildValue("l", sbytes);
9050 #else
9051 return Py_BuildValue("L", sbytes);
9052 #endif
9053
9054#else
9055 Py_ssize_t count;
9056 PyObject *offobj;
9057 static char *keywords[] = {"out", "in",
9058 "offset", "count", NULL};
9059 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
9060 keywords, &out, &in, &offobj, &count))
9061 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009062#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009063 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009064 do {
9065 Py_BEGIN_ALLOW_THREADS
9066 ret = sendfile(out, in, NULL, count);
9067 Py_END_ALLOW_THREADS
9068 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009069 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009070 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009071 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009072 }
9073#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009074 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009075 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009076
9077 do {
9078 Py_BEGIN_ALLOW_THREADS
9079 ret = sendfile(out, in, &offset, count);
9080 Py_END_ALLOW_THREADS
9081 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009082 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009083 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009084 return Py_BuildValue("n", ret);
9085#endif
9086}
Larry Hastings2f936352014-08-05 14:04:04 +10009087#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009088
Larry Hastings2f936352014-08-05 14:04:04 +10009089
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009090#if defined(__APPLE__)
9091/*[clinic input]
9092os._fcopyfile
9093
9094 infd: int
9095 outfd: int
9096 flags: int
9097 /
9098
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009099Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009100[clinic start generated code]*/
9101
9102static PyObject *
9103os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009104/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009105{
9106 int ret;
9107
9108 Py_BEGIN_ALLOW_THREADS
9109 ret = fcopyfile(infd, outfd, NULL, flags);
9110 Py_END_ALLOW_THREADS
9111 if (ret < 0)
9112 return posix_error();
9113 Py_RETURN_NONE;
9114}
9115#endif
9116
9117
Larry Hastings2f936352014-08-05 14:04:04 +10009118/*[clinic input]
9119os.fstat
9120
9121 fd : int
9122
9123Perform a stat system call on the given file descriptor.
9124
9125Like stat(), but for an open file descriptor.
9126Equivalent to os.stat(fd).
9127[clinic start generated code]*/
9128
Larry Hastings2f936352014-08-05 14:04:04 +10009129static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009130os_fstat_impl(PyObject *module, int fd)
9131/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009132{
Victor Stinner8c62be82010-05-06 00:08:46 +00009133 STRUCT_STAT st;
9134 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009135 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009136
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009137 do {
9138 Py_BEGIN_ALLOW_THREADS
9139 res = FSTAT(fd, &st);
9140 Py_END_ALLOW_THREADS
9141 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009142 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009143#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009144 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009145#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009146 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009147#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009148 }
Tim Peters5aa91602002-01-30 05:46:57 +00009149
Victor Stinner4195b5c2012-02-08 23:03:19 +01009150 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009151}
9152
Larry Hastings2f936352014-08-05 14:04:04 +10009153
9154/*[clinic input]
9155os.isatty -> bool
9156 fd: int
9157 /
9158
9159Return True if the fd is connected to a terminal.
9160
9161Return True if the file descriptor is an open file descriptor
9162connected to the slave end of a terminal.
9163[clinic start generated code]*/
9164
Larry Hastings2f936352014-08-05 14:04:04 +10009165static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009166os_isatty_impl(PyObject *module, int fd)
9167/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009168{
Steve Dower8fc89802015-04-12 00:26:27 -04009169 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009170 _Py_BEGIN_SUPPRESS_IPH
9171 return_value = isatty(fd);
9172 _Py_END_SUPPRESS_IPH
9173 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009174}
9175
9176
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009177#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009178/*[clinic input]
9179os.pipe
9180
9181Create a pipe.
9182
9183Returns a tuple of two file descriptors:
9184 (read_fd, write_fd)
9185[clinic start generated code]*/
9186
Larry Hastings2f936352014-08-05 14:04:04 +10009187static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009188os_pipe_impl(PyObject *module)
9189/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009190{
Victor Stinner8c62be82010-05-06 00:08:46 +00009191 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009192#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009193 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009194 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009196#else
9197 int res;
9198#endif
9199
9200#ifdef MS_WINDOWS
9201 attr.nLength = sizeof(attr);
9202 attr.lpSecurityDescriptor = NULL;
9203 attr.bInheritHandle = FALSE;
9204
9205 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009206 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009207 ok = CreatePipe(&read, &write, &attr, 0);
9208 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009209 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9210 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009211 if (fds[0] == -1 || fds[1] == -1) {
9212 CloseHandle(read);
9213 CloseHandle(write);
9214 ok = 0;
9215 }
9216 }
Steve Dowerc3630612016-11-19 18:41:16 -08009217 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009218 Py_END_ALLOW_THREADS
9219
Victor Stinner8c62be82010-05-06 00:08:46 +00009220 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009221 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009222#else
9223
9224#ifdef HAVE_PIPE2
9225 Py_BEGIN_ALLOW_THREADS
9226 res = pipe2(fds, O_CLOEXEC);
9227 Py_END_ALLOW_THREADS
9228
9229 if (res != 0 && errno == ENOSYS)
9230 {
9231#endif
9232 Py_BEGIN_ALLOW_THREADS
9233 res = pipe(fds);
9234 Py_END_ALLOW_THREADS
9235
9236 if (res == 0) {
9237 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9238 close(fds[0]);
9239 close(fds[1]);
9240 return NULL;
9241 }
9242 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9243 close(fds[0]);
9244 close(fds[1]);
9245 return NULL;
9246 }
9247 }
9248#ifdef HAVE_PIPE2
9249 }
9250#endif
9251
9252 if (res != 0)
9253 return PyErr_SetFromErrno(PyExc_OSError);
9254#endif /* !MS_WINDOWS */
9255 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009256}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009257#endif /* HAVE_PIPE */
9258
Larry Hastings2f936352014-08-05 14:04:04 +10009259
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009260#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009261/*[clinic input]
9262os.pipe2
9263
9264 flags: int
9265 /
9266
9267Create a pipe with flags set atomically.
9268
9269Returns a tuple of two file descriptors:
9270 (read_fd, write_fd)
9271
9272flags can be constructed by ORing together one or more of these values:
9273O_NONBLOCK, O_CLOEXEC.
9274[clinic start generated code]*/
9275
Larry Hastings2f936352014-08-05 14:04:04 +10009276static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009277os_pipe2_impl(PyObject *module, int flags)
9278/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009279{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009280 int fds[2];
9281 int res;
9282
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009283 res = pipe2(fds, flags);
9284 if (res != 0)
9285 return posix_error();
9286 return Py_BuildValue("(ii)", fds[0], fds[1]);
9287}
9288#endif /* HAVE_PIPE2 */
9289
Larry Hastings2f936352014-08-05 14:04:04 +10009290
Ross Lagerwall7807c352011-03-17 20:20:30 +02009291#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009292/*[clinic input]
9293os.writev -> Py_ssize_t
9294 fd: int
9295 buffers: object
9296 /
9297
9298Iterate over buffers, and write the contents of each to a file descriptor.
9299
9300Returns the total number of bytes written.
9301buffers must be a sequence of bytes-like objects.
9302[clinic start generated code]*/
9303
Larry Hastings2f936352014-08-05 14:04:04 +10009304static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009305os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9306/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009307{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009308 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009309 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009310 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009311 struct iovec *iov;
9312 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009313
9314 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009315 PyErr_SetString(PyExc_TypeError,
9316 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009317 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009318 }
Larry Hastings2f936352014-08-05 14:04:04 +10009319 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009320 if (cnt < 0)
9321 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009322
Larry Hastings2f936352014-08-05 14:04:04 +10009323 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9324 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009325 }
9326
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009327 do {
9328 Py_BEGIN_ALLOW_THREADS
9329 result = writev(fd, iov, cnt);
9330 Py_END_ALLOW_THREADS
9331 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009332
9333 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009334 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009335 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009336
Georg Brandl306336b2012-06-24 12:55:33 +02009337 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009338}
Larry Hastings2f936352014-08-05 14:04:04 +10009339#endif /* HAVE_WRITEV */
9340
9341
9342#ifdef HAVE_PWRITE
9343/*[clinic input]
9344os.pwrite -> Py_ssize_t
9345
9346 fd: int
9347 buffer: Py_buffer
9348 offset: Py_off_t
9349 /
9350
9351Write bytes to a file descriptor starting at a particular offset.
9352
9353Write buffer to fd, starting at offset bytes from the beginning of
9354the file. Returns the number of bytes writte. Does not change the
9355current file offset.
9356[clinic start generated code]*/
9357
Larry Hastings2f936352014-08-05 14:04:04 +10009358static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009359os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9360/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009361{
9362 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009363 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009364
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009365 do {
9366 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009367 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009368 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009369 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009370 Py_END_ALLOW_THREADS
9371 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009372
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009373 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009374 posix_error();
9375 return size;
9376}
9377#endif /* HAVE_PWRITE */
9378
Pablo Galindo4defba32018-01-27 16:16:37 +00009379#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9380/*[clinic input]
9381os.pwritev -> Py_ssize_t
9382
9383 fd: int
9384 buffers: object
9385 offset: Py_off_t
9386 flags: int = 0
9387 /
9388
9389Writes the contents of bytes-like objects to a file descriptor at a given offset.
9390
9391Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9392of bytes-like objects. Buffers are processed in array order. Entire contents of first
9393buffer is written before proceeding to second, and so on. The operating system may
9394set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9395This function writes the contents of each object to the file descriptor and returns
9396the total number of bytes written.
9397
9398The flags argument contains a bitwise OR of zero or more of the following flags:
9399
9400- RWF_DSYNC
9401- RWF_SYNC
9402
9403Using non-zero flags requires Linux 4.7 or newer.
9404[clinic start generated code]*/
9405
9406static Py_ssize_t
9407os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9408 int flags)
9409/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9410{
9411 Py_ssize_t cnt;
9412 Py_ssize_t result;
9413 int async_err = 0;
9414 struct iovec *iov;
9415 Py_buffer *buf;
9416
9417 if (!PySequence_Check(buffers)) {
9418 PyErr_SetString(PyExc_TypeError,
9419 "pwritev() arg 2 must be a sequence");
9420 return -1;
9421 }
9422
9423 cnt = PySequence_Size(buffers);
9424 if (cnt < 0) {
9425 return -1;
9426 }
9427
9428#ifndef HAVE_PWRITEV2
9429 if(flags != 0) {
9430 argument_unavailable_error("pwritev2", "flags");
9431 return -1;
9432 }
9433#endif
9434
9435 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9436 return -1;
9437 }
9438#ifdef HAVE_PWRITEV2
9439 do {
9440 Py_BEGIN_ALLOW_THREADS
9441 _Py_BEGIN_SUPPRESS_IPH
9442 result = pwritev2(fd, iov, cnt, offset, flags);
9443 _Py_END_SUPPRESS_IPH
9444 Py_END_ALLOW_THREADS
9445 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9446#else
9447 do {
9448 Py_BEGIN_ALLOW_THREADS
9449 _Py_BEGIN_SUPPRESS_IPH
9450 result = pwritev(fd, iov, cnt, offset);
9451 _Py_END_SUPPRESS_IPH
9452 Py_END_ALLOW_THREADS
9453 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9454#endif
9455
9456 iov_cleanup(iov, buf, cnt);
9457 if (result < 0) {
9458 if (!async_err) {
9459 posix_error();
9460 }
9461 return -1;
9462 }
9463
9464 return result;
9465}
9466#endif /* HAVE_PWRITEV */
9467
Pablo Galindoaac4d032019-05-31 19:39:47 +01009468#ifdef HAVE_COPY_FILE_RANGE
9469/*[clinic input]
9470
9471os.copy_file_range
9472 src: int
9473 Source file descriptor.
9474 dst: int
9475 Destination file descriptor.
9476 count: Py_ssize_t
9477 Number of bytes to copy.
9478 offset_src: object = None
9479 Starting offset in src.
9480 offset_dst: object = None
9481 Starting offset in dst.
9482
9483Copy count bytes from one file descriptor to another.
9484
9485If offset_src is None, then src is read from the current position;
9486respectively for offset_dst.
9487[clinic start generated code]*/
9488
9489static PyObject *
9490os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
9491 PyObject *offset_src, PyObject *offset_dst)
9492/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
9493{
9494 off_t offset_src_val, offset_dst_val;
9495 off_t *p_offset_src = NULL;
9496 off_t *p_offset_dst = NULL;
9497 Py_ssize_t ret;
9498 int async_err = 0;
9499 /* The flags argument is provided to allow
9500 * for future extensions and currently must be to 0. */
9501 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +00009502
9503
Pablo Galindoaac4d032019-05-31 19:39:47 +01009504 if (count < 0) {
9505 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
9506 return NULL;
9507 }
9508
9509 if (offset_src != Py_None) {
9510 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
9511 return NULL;
9512 }
9513 p_offset_src = &offset_src_val;
9514 }
9515
9516 if (offset_dst != Py_None) {
9517 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
9518 return NULL;
9519 }
9520 p_offset_dst = &offset_dst_val;
9521 }
9522
9523 do {
9524 Py_BEGIN_ALLOW_THREADS
9525 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
9526 Py_END_ALLOW_THREADS
9527 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9528
9529 if (ret < 0) {
9530 return (!async_err) ? posix_error() : NULL;
9531 }
9532
9533 return PyLong_FromSsize_t(ret);
9534}
9535#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +10009536
9537#ifdef HAVE_MKFIFO
9538/*[clinic input]
9539os.mkfifo
9540
9541 path: path_t
9542 mode: int=0o666
9543 *
9544 dir_fd: dir_fd(requires='mkfifoat')=None
9545
9546Create a "fifo" (a POSIX named pipe).
9547
9548If dir_fd is not None, it should be a file descriptor open to a directory,
9549 and path should be relative; path will then be relative to that directory.
9550dir_fd may not be implemented on your platform.
9551 If it is unavailable, using it will raise a NotImplementedError.
9552[clinic start generated code]*/
9553
Larry Hastings2f936352014-08-05 14:04:04 +10009554static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009555os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9556/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009557{
9558 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009559 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009560
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009561 do {
9562 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009563#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009564 if (dir_fd != DEFAULT_DIR_FD)
9565 result = mkfifoat(dir_fd, path->narrow, mode);
9566 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009567#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009568 result = mkfifo(path->narrow, mode);
9569 Py_END_ALLOW_THREADS
9570 } while (result != 0 && errno == EINTR &&
9571 !(async_err = PyErr_CheckSignals()));
9572 if (result != 0)
9573 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009574
9575 Py_RETURN_NONE;
9576}
9577#endif /* HAVE_MKFIFO */
9578
9579
9580#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9581/*[clinic input]
9582os.mknod
9583
9584 path: path_t
9585 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009586 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009587 *
9588 dir_fd: dir_fd(requires='mknodat')=None
9589
9590Create a node in the file system.
9591
9592Create a node in the file system (file, device special file or named pipe)
9593at path. mode specifies both the permissions to use and the
9594type of node to be created, being combined (bitwise OR) with one of
9595S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9596device defines the newly created device special file (probably using
9597os.makedev()). Otherwise device is ignored.
9598
9599If dir_fd is not None, it should be a file descriptor open to a directory,
9600 and path should be relative; path will then be relative to that directory.
9601dir_fd may not be implemented on your platform.
9602 If it is unavailable, using it will raise a NotImplementedError.
9603[clinic start generated code]*/
9604
Larry Hastings2f936352014-08-05 14:04:04 +10009605static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009606os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009607 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009608/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009609{
9610 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009611 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009612
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009613 do {
9614 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009615#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009616 if (dir_fd != DEFAULT_DIR_FD)
9617 result = mknodat(dir_fd, path->narrow, mode, device);
9618 else
Larry Hastings2f936352014-08-05 14:04:04 +10009619#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009620 result = mknod(path->narrow, mode, device);
9621 Py_END_ALLOW_THREADS
9622 } while (result != 0 && errno == EINTR &&
9623 !(async_err = PyErr_CheckSignals()));
9624 if (result != 0)
9625 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009626
9627 Py_RETURN_NONE;
9628}
9629#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9630
9631
9632#ifdef HAVE_DEVICE_MACROS
9633/*[clinic input]
9634os.major -> unsigned_int
9635
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009636 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009637 /
9638
9639Extracts a device major number from a raw device number.
9640[clinic start generated code]*/
9641
Larry Hastings2f936352014-08-05 14:04:04 +10009642static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009643os_major_impl(PyObject *module, dev_t device)
9644/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009645{
9646 return major(device);
9647}
9648
9649
9650/*[clinic input]
9651os.minor -> unsigned_int
9652
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009653 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009654 /
9655
9656Extracts a device minor number from a raw device number.
9657[clinic start generated code]*/
9658
Larry Hastings2f936352014-08-05 14:04:04 +10009659static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009660os_minor_impl(PyObject *module, dev_t device)
9661/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009662{
9663 return minor(device);
9664}
9665
9666
9667/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009668os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009669
9670 major: int
9671 minor: int
9672 /
9673
9674Composes a raw device number from the major and minor device numbers.
9675[clinic start generated code]*/
9676
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009677static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009678os_makedev_impl(PyObject *module, int major, int minor)
9679/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009680{
9681 return makedev(major, minor);
9682}
9683#endif /* HAVE_DEVICE_MACROS */
9684
9685
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009686#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009687/*[clinic input]
9688os.ftruncate
9689
9690 fd: int
9691 length: Py_off_t
9692 /
9693
9694Truncate a file, specified by file descriptor, to a specific length.
9695[clinic start generated code]*/
9696
Larry Hastings2f936352014-08-05 14:04:04 +10009697static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009698os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9699/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009700{
9701 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009702 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009703
Steve Dowerb82e17e2019-05-23 08:45:22 -07009704 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
9705 return NULL;
9706 }
9707
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009708 do {
9709 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009710 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009711#ifdef MS_WINDOWS
9712 result = _chsize_s(fd, length);
9713#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009714 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009715#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009716 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009717 Py_END_ALLOW_THREADS
9718 } while (result != 0 && errno == EINTR &&
9719 !(async_err = PyErr_CheckSignals()));
9720 if (result != 0)
9721 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009722 Py_RETURN_NONE;
9723}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009724#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009725
9726
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009727#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009728/*[clinic input]
9729os.truncate
9730 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9731 length: Py_off_t
9732
9733Truncate a file, specified by path, to a specific length.
9734
9735On some platforms, path may also be specified as an open file descriptor.
9736 If this functionality is unavailable, using it raises an exception.
9737[clinic start generated code]*/
9738
Larry Hastings2f936352014-08-05 14:04:04 +10009739static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009740os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9741/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009742{
9743 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009744#ifdef MS_WINDOWS
9745 int fd;
9746#endif
9747
9748 if (path->fd != -1)
9749 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009750
Steve Dowerb82e17e2019-05-23 08:45:22 -07009751 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
9752 return NULL;
9753 }
9754
Larry Hastings2f936352014-08-05 14:04:04 +10009755 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009756 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009757#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009758 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009759 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009760 result = -1;
9761 else {
9762 result = _chsize_s(fd, length);
9763 close(fd);
9764 if (result < 0)
9765 errno = result;
9766 }
9767#else
9768 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009769#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009770 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009771 Py_END_ALLOW_THREADS
9772 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009773 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009774
9775 Py_RETURN_NONE;
9776}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009777#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009778
Ross Lagerwall7807c352011-03-17 20:20:30 +02009779
Victor Stinnerd6b17692014-09-30 12:20:05 +02009780/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9781 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9782 defined, which is the case in Python on AIX. AIX bug report:
9783 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9784#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9785# define POSIX_FADVISE_AIX_BUG
9786#endif
9787
Victor Stinnerec39e262014-09-30 12:35:58 +02009788
Victor Stinnerd6b17692014-09-30 12:20:05 +02009789#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009790/*[clinic input]
9791os.posix_fallocate
9792
9793 fd: int
9794 offset: Py_off_t
9795 length: Py_off_t
9796 /
9797
9798Ensure a file has allocated at least a particular number of bytes on disk.
9799
9800Ensure that the file specified by fd encompasses a range of bytes
9801starting at offset bytes from the beginning and continuing for length bytes.
9802[clinic start generated code]*/
9803
Larry Hastings2f936352014-08-05 14:04:04 +10009804static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009805os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009806 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009807/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009808{
9809 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009810 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009811
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009812 do {
9813 Py_BEGIN_ALLOW_THREADS
9814 result = posix_fallocate(fd, offset, length);
9815 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009816 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9817
9818 if (result == 0)
9819 Py_RETURN_NONE;
9820
9821 if (async_err)
9822 return NULL;
9823
9824 errno = result;
9825 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009826}
Victor Stinnerec39e262014-09-30 12:35:58 +02009827#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009828
Ross Lagerwall7807c352011-03-17 20:20:30 +02009829
Victor Stinnerd6b17692014-09-30 12:20:05 +02009830#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009831/*[clinic input]
9832os.posix_fadvise
9833
9834 fd: int
9835 offset: Py_off_t
9836 length: Py_off_t
9837 advice: int
9838 /
9839
9840Announce an intention to access data in a specific pattern.
9841
9842Announce an intention to access data in a specific pattern, thus allowing
9843the kernel to make optimizations.
9844The advice applies to the region of the file specified by fd starting at
9845offset and continuing for length bytes.
9846advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9847POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9848POSIX_FADV_DONTNEED.
9849[clinic start generated code]*/
9850
Larry Hastings2f936352014-08-05 14:04:04 +10009851static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009852os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009853 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009854/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009855{
9856 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009857 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009858
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009859 do {
9860 Py_BEGIN_ALLOW_THREADS
9861 result = posix_fadvise(fd, offset, length, advice);
9862 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009863 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9864
9865 if (result == 0)
9866 Py_RETURN_NONE;
9867
9868 if (async_err)
9869 return NULL;
9870
9871 errno = result;
9872 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009873}
Victor Stinnerec39e262014-09-30 12:35:58 +02009874#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009875
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009876#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009877
Fred Drake762e2061999-08-26 17:23:54 +00009878/* Save putenv() parameters as values here, so we can collect them when they
9879 * get re-set with another call for the same key. */
9880static PyObject *posix_putenv_garbage;
9881
Larry Hastings2f936352014-08-05 14:04:04 +10009882static void
9883posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009884{
Larry Hastings2f936352014-08-05 14:04:04 +10009885 /* Install the first arg and newstr in posix_putenv_garbage;
9886 * this will cause previous value to be collected. This has to
9887 * happen after the real putenv() call because the old value
9888 * was still accessible until then. */
9889 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9890 /* really not much we can do; just leak */
9891 PyErr_Clear();
9892 else
9893 Py_DECREF(value);
9894}
9895
9896
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009897#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009898/*[clinic input]
9899os.putenv
9900
9901 name: unicode
9902 value: unicode
9903 /
9904
9905Change or add an environment variable.
9906[clinic start generated code]*/
9907
Larry Hastings2f936352014-08-05 14:04:04 +10009908static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009909os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9910/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009911{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009912 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009913 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009914
Serhiy Storchaka77703942017-06-25 07:33:01 +03009915 /* Search from index 1 because on Windows starting '=' is allowed for
9916 defining hidden environment variables. */
9917 if (PyUnicode_GET_LENGTH(name) == 0 ||
9918 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9919 {
9920 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9921 return NULL;
9922 }
Larry Hastings2f936352014-08-05 14:04:04 +10009923 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9924 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009925 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009926 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009927
9928 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9929 if (env == NULL)
9930 goto error;
9931 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009932 PyErr_Format(PyExc_ValueError,
9933 "the environment variable is longer than %u characters",
9934 _MAX_ENV);
9935 goto error;
9936 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009937 if (wcslen(env) != (size_t)size) {
9938 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009939 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009940 }
9941
Larry Hastings2f936352014-08-05 14:04:04 +10009942 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009944 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009946
Larry Hastings2f936352014-08-05 14:04:04 +10009947 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009948 Py_RETURN_NONE;
9949
9950error:
Larry Hastings2f936352014-08-05 14:04:04 +10009951 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009952 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009953}
Larry Hastings2f936352014-08-05 14:04:04 +10009954#else /* MS_WINDOWS */
9955/*[clinic input]
9956os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009957
Larry Hastings2f936352014-08-05 14:04:04 +10009958 name: FSConverter
9959 value: FSConverter
9960 /
9961
9962Change or add an environment variable.
9963[clinic start generated code]*/
9964
Larry Hastings2f936352014-08-05 14:04:04 +10009965static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009966os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9967/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009968{
9969 PyObject *bytes = NULL;
9970 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009971 const char *name_string = PyBytes_AS_STRING(name);
9972 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009973
Serhiy Storchaka77703942017-06-25 07:33:01 +03009974 if (strchr(name_string, '=') != NULL) {
9975 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9976 return NULL;
9977 }
Larry Hastings2f936352014-08-05 14:04:04 +10009978 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9979 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009980 return NULL;
9981 }
9982
9983 env = PyBytes_AS_STRING(bytes);
9984 if (putenv(env)) {
9985 Py_DECREF(bytes);
9986 return posix_error();
9987 }
9988
9989 posix_putenv_garbage_setitem(name, bytes);
9990 Py_RETURN_NONE;
9991}
9992#endif /* MS_WINDOWS */
9993#endif /* HAVE_PUTENV */
9994
9995
9996#ifdef HAVE_UNSETENV
9997/*[clinic input]
9998os.unsetenv
9999 name: FSConverter
10000 /
10001
10002Delete an environment variable.
10003[clinic start generated code]*/
10004
Larry Hastings2f936352014-08-05 14:04:04 +100010005static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010006os_unsetenv_impl(PyObject *module, PyObject *name)
10007/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010008{
Victor Stinner984890f2011-11-24 13:53:38 +010010009#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +010010010 int err;
Victor Stinner984890f2011-11-24 13:53:38 +010010011#endif
Victor Stinner84ae1182010-05-06 22:05:07 +000010012
Victor Stinner984890f2011-11-24 13:53:38 +010010013#ifdef HAVE_BROKEN_UNSETENV
10014 unsetenv(PyBytes_AS_STRING(name));
10015#else
Victor Stinner65170952011-11-22 22:16:17 +010010016 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +100010017 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +010010018 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +010010019#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010020
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 /* Remove the key from posix_putenv_garbage;
10022 * this will cause it to be collected. This has to
10023 * happen after the real unsetenv() call because the
10024 * old value was still accessible until then.
10025 */
Victor Stinner65170952011-11-22 22:16:17 +010010026 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 /* really not much we can do; just leak */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +020010028 if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
10029 return NULL;
10030 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 PyErr_Clear();
10032 }
Victor Stinner84ae1182010-05-06 22:05:07 +000010033 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010034}
Larry Hastings2f936352014-08-05 14:04:04 +100010035#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +000010036
Larry Hastings2f936352014-08-05 14:04:04 +100010037
10038/*[clinic input]
10039os.strerror
10040
10041 code: int
10042 /
10043
10044Translate an error code to a message string.
10045[clinic start generated code]*/
10046
Larry Hastings2f936352014-08-05 14:04:04 +100010047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010048os_strerror_impl(PyObject *module, int code)
10049/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010050{
10051 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 if (message == NULL) {
10053 PyErr_SetString(PyExc_ValueError,
10054 "strerror() argument out of range");
10055 return NULL;
10056 }
Victor Stinner1b579672011-12-17 05:47:23 +010010057 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010058}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010059
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010060
Guido van Rossumc9641791998-08-04 15:26:23 +000010061#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010062#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010063/*[clinic input]
10064os.WCOREDUMP -> bool
10065
10066 status: int
10067 /
10068
10069Return True if the process returning status was dumped to a core file.
10070[clinic start generated code]*/
10071
Larry Hastings2f936352014-08-05 14:04:04 +100010072static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010073os_WCOREDUMP_impl(PyObject *module, int status)
10074/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010075{
10076 WAIT_TYPE wait_status;
10077 WAIT_STATUS_INT(wait_status) = status;
10078 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010079}
10080#endif /* WCOREDUMP */
10081
Larry Hastings2f936352014-08-05 14:04:04 +100010082
Fred Drake106c1a02002-04-23 15:58:02 +000010083#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010084/*[clinic input]
10085os.WIFCONTINUED -> bool
10086
10087 status: int
10088
10089Return True if a particular process was continued from a job control stop.
10090
10091Return True if the process returning status was continued from a
10092job control stop.
10093[clinic start generated code]*/
10094
Larry Hastings2f936352014-08-05 14:04:04 +100010095static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010096os_WIFCONTINUED_impl(PyObject *module, int status)
10097/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010098{
10099 WAIT_TYPE wait_status;
10100 WAIT_STATUS_INT(wait_status) = status;
10101 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010102}
10103#endif /* WIFCONTINUED */
10104
Larry Hastings2f936352014-08-05 14:04:04 +100010105
Guido van Rossumc9641791998-08-04 15:26:23 +000010106#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010107/*[clinic input]
10108os.WIFSTOPPED -> bool
10109
10110 status: int
10111
10112Return True if the process returning status was stopped.
10113[clinic start generated code]*/
10114
Larry Hastings2f936352014-08-05 14:04:04 +100010115static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010116os_WIFSTOPPED_impl(PyObject *module, int status)
10117/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010118{
10119 WAIT_TYPE wait_status;
10120 WAIT_STATUS_INT(wait_status) = status;
10121 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010122}
10123#endif /* WIFSTOPPED */
10124
Larry Hastings2f936352014-08-05 14:04:04 +100010125
Guido van Rossumc9641791998-08-04 15:26:23 +000010126#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010127/*[clinic input]
10128os.WIFSIGNALED -> bool
10129
10130 status: int
10131
10132Return True if the process returning status was terminated by a signal.
10133[clinic start generated code]*/
10134
Larry Hastings2f936352014-08-05 14:04:04 +100010135static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010136os_WIFSIGNALED_impl(PyObject *module, int status)
10137/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010138{
10139 WAIT_TYPE wait_status;
10140 WAIT_STATUS_INT(wait_status) = status;
10141 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010142}
10143#endif /* WIFSIGNALED */
10144
Larry Hastings2f936352014-08-05 14:04:04 +100010145
Guido van Rossumc9641791998-08-04 15:26:23 +000010146#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010147/*[clinic input]
10148os.WIFEXITED -> bool
10149
10150 status: int
10151
10152Return True if the process returning status exited via the exit() system call.
10153[clinic start generated code]*/
10154
Larry Hastings2f936352014-08-05 14:04:04 +100010155static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010156os_WIFEXITED_impl(PyObject *module, int status)
10157/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010158{
10159 WAIT_TYPE wait_status;
10160 WAIT_STATUS_INT(wait_status) = status;
10161 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010162}
10163#endif /* WIFEXITED */
10164
Larry Hastings2f936352014-08-05 14:04:04 +100010165
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010166#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010167/*[clinic input]
10168os.WEXITSTATUS -> int
10169
10170 status: int
10171
10172Return the process return code from status.
10173[clinic start generated code]*/
10174
Larry Hastings2f936352014-08-05 14:04:04 +100010175static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010176os_WEXITSTATUS_impl(PyObject *module, int status)
10177/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010178{
10179 WAIT_TYPE wait_status;
10180 WAIT_STATUS_INT(wait_status) = status;
10181 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010182}
10183#endif /* WEXITSTATUS */
10184
Larry Hastings2f936352014-08-05 14:04:04 +100010185
Guido van Rossumc9641791998-08-04 15:26:23 +000010186#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010187/*[clinic input]
10188os.WTERMSIG -> int
10189
10190 status: int
10191
10192Return the signal that terminated the process that provided the status value.
10193[clinic start generated code]*/
10194
Larry Hastings2f936352014-08-05 14:04:04 +100010195static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010196os_WTERMSIG_impl(PyObject *module, int status)
10197/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010198{
10199 WAIT_TYPE wait_status;
10200 WAIT_STATUS_INT(wait_status) = status;
10201 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010202}
10203#endif /* WTERMSIG */
10204
Larry Hastings2f936352014-08-05 14:04:04 +100010205
Guido van Rossumc9641791998-08-04 15:26:23 +000010206#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010207/*[clinic input]
10208os.WSTOPSIG -> int
10209
10210 status: int
10211
10212Return the signal that stopped the process that provided the status value.
10213[clinic start generated code]*/
10214
Larry Hastings2f936352014-08-05 14:04:04 +100010215static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010216os_WSTOPSIG_impl(PyObject *module, int status)
10217/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010218{
10219 WAIT_TYPE wait_status;
10220 WAIT_STATUS_INT(wait_status) = status;
10221 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010222}
10223#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010224#endif /* HAVE_SYS_WAIT_H */
10225
10226
Thomas Wouters477c8d52006-05-27 19:21:47 +000010227#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010228#ifdef _SCO_DS
10229/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10230 needed definitions in sys/statvfs.h */
10231#define _SVID3
10232#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010233#include <sys/statvfs.h>
10234
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010235static PyObject*
10236_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -080010237 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 if (v == NULL)
10239 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010240
10241#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10243 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10244 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10245 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10246 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10247 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10248 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10249 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10250 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10251 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010252#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10254 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10255 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010256 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010258 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010260 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010262 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010264 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010266 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10268 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010269#endif
Michael Felt502d5512018-01-05 13:01:58 +010010270/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10271 * (issue #32390). */
10272#if defined(_AIX) && defined(_ALL_SOURCE)
10273 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10274#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010275 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010276#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010277 if (PyErr_Occurred()) {
10278 Py_DECREF(v);
10279 return NULL;
10280 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010281
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010283}
10284
Larry Hastings2f936352014-08-05 14:04:04 +100010285
10286/*[clinic input]
10287os.fstatvfs
10288 fd: int
10289 /
10290
10291Perform an fstatvfs system call on the given fd.
10292
10293Equivalent to statvfs(fd).
10294[clinic start generated code]*/
10295
Larry Hastings2f936352014-08-05 14:04:04 +100010296static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010297os_fstatvfs_impl(PyObject *module, int fd)
10298/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010299{
10300 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010301 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010303
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010304 do {
10305 Py_BEGIN_ALLOW_THREADS
10306 result = fstatvfs(fd, &st);
10307 Py_END_ALLOW_THREADS
10308 } while (result != 0 && errno == EINTR &&
10309 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010310 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010311 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010312
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010314}
Larry Hastings2f936352014-08-05 14:04:04 +100010315#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010316
10317
Thomas Wouters477c8d52006-05-27 19:21:47 +000010318#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010319#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010320/*[clinic input]
10321os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010322
Larry Hastings2f936352014-08-05 14:04:04 +100010323 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10324
10325Perform a statvfs system call on the given path.
10326
10327path may always be specified as a string.
10328On some platforms, path may also be specified as an open file descriptor.
10329 If this functionality is unavailable, using it raises an exception.
10330[clinic start generated code]*/
10331
Larry Hastings2f936352014-08-05 14:04:04 +100010332static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010333os_statvfs_impl(PyObject *module, path_t *path)
10334/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010335{
10336 int result;
10337 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010338
10339 Py_BEGIN_ALLOW_THREADS
10340#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010341 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010342#ifdef __APPLE__
10343 /* handle weak-linking on Mac OS X 10.3 */
10344 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010345 fd_specified("statvfs", path->fd);
10346 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010347 }
10348#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010349 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010350 }
10351 else
10352#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010353 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010354 Py_END_ALLOW_THREADS
10355
10356 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010357 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010358 }
10359
Larry Hastings2f936352014-08-05 14:04:04 +100010360 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010361}
Larry Hastings2f936352014-08-05 14:04:04 +100010362#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10363
Guido van Rossum94f6f721999-01-06 18:42:14 +000010364
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010365#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010366/*[clinic input]
10367os._getdiskusage
10368
Steve Dower23ad6d02018-02-22 10:39:10 -080010369 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010370
10371Return disk usage statistics about the given path as a (total, free) tuple.
10372[clinic start generated code]*/
10373
Larry Hastings2f936352014-08-05 14:04:04 +100010374static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010375os__getdiskusage_impl(PyObject *module, path_t *path)
10376/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010377{
10378 BOOL retval;
10379 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010380 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010381
10382 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010383 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010384 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010385 if (retval == 0) {
10386 if (GetLastError() == ERROR_DIRECTORY) {
10387 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010388
Joe Pamerc8c02492018-09-25 10:57:36 -040010389 dir_path = PyMem_New(wchar_t, path->length + 1);
10390 if (dir_path == NULL) {
10391 return PyErr_NoMemory();
10392 }
10393
10394 wcscpy_s(dir_path, path->length + 1, path->wide);
10395
10396 if (_dirnameW(dir_path) != -1) {
10397 Py_BEGIN_ALLOW_THREADS
10398 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10399 Py_END_ALLOW_THREADS
10400 }
10401 /* Record the last error in case it's modified by PyMem_Free. */
10402 err = GetLastError();
10403 PyMem_Free(dir_path);
10404 if (retval) {
10405 goto success;
10406 }
10407 }
10408 return PyErr_SetFromWindowsErr(err);
10409 }
10410
10411success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010412 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10413}
Larry Hastings2f936352014-08-05 14:04:04 +100010414#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010415
10416
Fred Drakec9680921999-12-13 16:37:25 +000010417/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10418 * It maps strings representing configuration variable names to
10419 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010420 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010421 * rarely-used constants. There are three separate tables that use
10422 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010423 *
10424 * This code is always included, even if none of the interfaces that
10425 * need it are included. The #if hackery needed to avoid it would be
10426 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010427 */
10428struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010429 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010430 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010431};
10432
Fred Drake12c6e2d1999-12-14 21:25:03 +000010433static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010434conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010435 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010436{
Christian Heimes217cfd12007-12-02 14:31:20 +000010437 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010438 int value = _PyLong_AsInt(arg);
10439 if (value == -1 && PyErr_Occurred())
10440 return 0;
10441 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010442 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010443 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010444 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010445 /* look up the value in the table using a binary search */
10446 size_t lo = 0;
10447 size_t mid;
10448 size_t hi = tablesize;
10449 int cmp;
10450 const char *confname;
10451 if (!PyUnicode_Check(arg)) {
10452 PyErr_SetString(PyExc_TypeError,
10453 "configuration names must be strings or integers");
10454 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010455 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010456 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010457 if (confname == NULL)
10458 return 0;
10459 while (lo < hi) {
10460 mid = (lo + hi) / 2;
10461 cmp = strcmp(confname, table[mid].name);
10462 if (cmp < 0)
10463 hi = mid;
10464 else if (cmp > 0)
10465 lo = mid + 1;
10466 else {
10467 *valuep = table[mid].value;
10468 return 1;
10469 }
10470 }
10471 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10472 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010474}
10475
10476
10477#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10478static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010479#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010480 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010481#endif
10482#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010483 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010484#endif
Fred Drakec9680921999-12-13 16:37:25 +000010485#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010487#endif
10488#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010489 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010490#endif
10491#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010492 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010493#endif
10494#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010495 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010496#endif
10497#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010498 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010499#endif
10500#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010501 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010502#endif
10503#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010504 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010505#endif
10506#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010507 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010508#endif
10509#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010510 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010511#endif
10512#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010513 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010514#endif
10515#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010516 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010517#endif
10518#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010519 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010520#endif
10521#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010523#endif
10524#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010526#endif
10527#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010529#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010530#ifdef _PC_ACL_ENABLED
10531 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10532#endif
10533#ifdef _PC_MIN_HOLE_SIZE
10534 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10535#endif
10536#ifdef _PC_ALLOC_SIZE_MIN
10537 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10538#endif
10539#ifdef _PC_REC_INCR_XFER_SIZE
10540 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10541#endif
10542#ifdef _PC_REC_MAX_XFER_SIZE
10543 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10544#endif
10545#ifdef _PC_REC_MIN_XFER_SIZE
10546 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10547#endif
10548#ifdef _PC_REC_XFER_ALIGN
10549 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10550#endif
10551#ifdef _PC_SYMLINK_MAX
10552 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10553#endif
10554#ifdef _PC_XATTR_ENABLED
10555 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10556#endif
10557#ifdef _PC_XATTR_EXISTS
10558 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10559#endif
10560#ifdef _PC_TIMESTAMP_RESOLUTION
10561 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10562#endif
Fred Drakec9680921999-12-13 16:37:25 +000010563};
10564
Fred Drakec9680921999-12-13 16:37:25 +000010565static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010566conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010567{
10568 return conv_confname(arg, valuep, posix_constants_pathconf,
10569 sizeof(posix_constants_pathconf)
10570 / sizeof(struct constdef));
10571}
10572#endif
10573
Larry Hastings2f936352014-08-05 14:04:04 +100010574
Fred Drakec9680921999-12-13 16:37:25 +000010575#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010576/*[clinic input]
10577os.fpathconf -> long
10578
10579 fd: int
10580 name: path_confname
10581 /
10582
10583Return the configuration limit name for the file descriptor fd.
10584
10585If there is no limit, return -1.
10586[clinic start generated code]*/
10587
Larry Hastings2f936352014-08-05 14:04:04 +100010588static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010589os_fpathconf_impl(PyObject *module, int fd, int name)
10590/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010591{
10592 long limit;
10593
10594 errno = 0;
10595 limit = fpathconf(fd, name);
10596 if (limit == -1 && errno != 0)
10597 posix_error();
10598
10599 return limit;
10600}
10601#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010602
10603
10604#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010605/*[clinic input]
10606os.pathconf -> long
10607 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10608 name: path_confname
10609
10610Return the configuration limit name for the file or directory path.
10611
10612If there is no limit, return -1.
10613On some platforms, path may also be specified as an open file descriptor.
10614 If this functionality is unavailable, using it raises an exception.
10615[clinic start generated code]*/
10616
Larry Hastings2f936352014-08-05 14:04:04 +100010617static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010618os_pathconf_impl(PyObject *module, path_t *path, int name)
10619/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010620{
Victor Stinner8c62be82010-05-06 00:08:46 +000010621 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010622
Victor Stinner8c62be82010-05-06 00:08:46 +000010623 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010624#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010625 if (path->fd != -1)
10626 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010627 else
10628#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010629 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010630 if (limit == -1 && errno != 0) {
10631 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010632 /* could be a path or name problem */
10633 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010634 else
Larry Hastings2f936352014-08-05 14:04:04 +100010635 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010636 }
Larry Hastings2f936352014-08-05 14:04:04 +100010637
10638 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010639}
Larry Hastings2f936352014-08-05 14:04:04 +100010640#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010641
10642#ifdef HAVE_CONFSTR
10643static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010644#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010645 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010646#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010647#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010649#endif
10650#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010651 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010652#endif
Fred Draked86ed291999-12-15 15:34:33 +000010653#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010655#endif
10656#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010657 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010658#endif
10659#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010660 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010661#endif
10662#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010664#endif
Fred Drakec9680921999-12-13 16:37:25 +000010665#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010667#endif
10668#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010670#endif
10671#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010673#endif
10674#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010676#endif
10677#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010679#endif
10680#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010682#endif
10683#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010685#endif
10686#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010688#endif
Fred Draked86ed291999-12-15 15:34:33 +000010689#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010691#endif
Fred Drakec9680921999-12-13 16:37:25 +000010692#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010694#endif
Fred Draked86ed291999-12-15 15:34:33 +000010695#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010697#endif
10698#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010700#endif
10701#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010703#endif
10704#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010706#endif
Fred Drakec9680921999-12-13 16:37:25 +000010707#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010709#endif
10710#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010712#endif
10713#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010715#endif
10716#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010718#endif
10719#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010721#endif
10722#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010724#endif
10725#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010727#endif
10728#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010730#endif
10731#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010732 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010733#endif
10734#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010736#endif
10737#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010739#endif
10740#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010741 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010742#endif
10743#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010745#endif
10746#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010748#endif
10749#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010750 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010751#endif
10752#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010753 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010754#endif
Fred Draked86ed291999-12-15 15:34:33 +000010755#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010756 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010757#endif
10758#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010759 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010760#endif
10761#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010762 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010763#endif
10764#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010766#endif
10767#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010768 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010769#endif
10770#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010771 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010772#endif
10773#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010774 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010775#endif
10776#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010777 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010778#endif
10779#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010780 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010781#endif
10782#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010783 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010784#endif
10785#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010786 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010787#endif
10788#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010789 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010790#endif
10791#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010792 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010793#endif
Fred Drakec9680921999-12-13 16:37:25 +000010794};
10795
10796static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010797conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010798{
10799 return conv_confname(arg, valuep, posix_constants_confstr,
10800 sizeof(posix_constants_confstr)
10801 / sizeof(struct constdef));
10802}
10803
Larry Hastings2f936352014-08-05 14:04:04 +100010804
10805/*[clinic input]
10806os.confstr
10807
10808 name: confstr_confname
10809 /
10810
10811Return a string-valued system configuration variable.
10812[clinic start generated code]*/
10813
Larry Hastings2f936352014-08-05 14:04:04 +100010814static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010815os_confstr_impl(PyObject *module, int name)
10816/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010817{
10818 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010819 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010820 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010821
Victor Stinnercb043522010-09-10 23:49:04 +000010822 errno = 0;
10823 len = confstr(name, buffer, sizeof(buffer));
10824 if (len == 0) {
10825 if (errno) {
10826 posix_error();
10827 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010828 }
10829 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010830 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010831 }
10832 }
Victor Stinnercb043522010-09-10 23:49:04 +000010833
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010834 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010835 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010836 char *buf = PyMem_Malloc(len);
10837 if (buf == NULL)
10838 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010839 len2 = confstr(name, buf, len);
10840 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010841 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010842 PyMem_Free(buf);
10843 }
10844 else
10845 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010846 return result;
10847}
Larry Hastings2f936352014-08-05 14:04:04 +100010848#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010849
10850
10851#ifdef HAVE_SYSCONF
10852static struct constdef posix_constants_sysconf[] = {
10853#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010855#endif
10856#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010857 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010858#endif
10859#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010860 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010861#endif
10862#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010863 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010864#endif
10865#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010866 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010867#endif
10868#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010869 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010870#endif
10871#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010873#endif
10874#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010875 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010876#endif
10877#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010878 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010879#endif
10880#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010881 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010882#endif
Fred Draked86ed291999-12-15 15:34:33 +000010883#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010884 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010885#endif
10886#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010887 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010888#endif
Fred Drakec9680921999-12-13 16:37:25 +000010889#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010890 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010891#endif
Fred Drakec9680921999-12-13 16:37:25 +000010892#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010893 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010894#endif
10895#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010896 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010897#endif
10898#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010899 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010900#endif
10901#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010902 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010903#endif
10904#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010906#endif
Fred Draked86ed291999-12-15 15:34:33 +000010907#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010908 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010909#endif
Fred Drakec9680921999-12-13 16:37:25 +000010910#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010911 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010912#endif
10913#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010914 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010915#endif
10916#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010917 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010918#endif
10919#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010920 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010921#endif
10922#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010923 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010924#endif
Fred Draked86ed291999-12-15 15:34:33 +000010925#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010926 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010927#endif
Fred Drakec9680921999-12-13 16:37:25 +000010928#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010929 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010930#endif
10931#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010932 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010933#endif
10934#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010936#endif
10937#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010939#endif
10940#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010942#endif
10943#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010945#endif
10946#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010947 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010948#endif
10949#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010950 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010951#endif
10952#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010953 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010954#endif
10955#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010957#endif
10958#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010960#endif
10961#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010962 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010963#endif
10964#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010965 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010966#endif
10967#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010968 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010969#endif
10970#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010972#endif
10973#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010975#endif
10976#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010977 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010978#endif
10979#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010981#endif
10982#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010984#endif
10985#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010986 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010987#endif
10988#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010989 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010990#endif
10991#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010992 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010993#endif
10994#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010996#endif
Fred Draked86ed291999-12-15 15:34:33 +000010997#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010998 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010999#endif
Fred Drakec9680921999-12-13 16:37:25 +000011000#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011001 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011002#endif
11003#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011005#endif
11006#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011007 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011008#endif
Fred Draked86ed291999-12-15 15:34:33 +000011009#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011011#endif
Fred Drakec9680921999-12-13 16:37:25 +000011012#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011013 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011014#endif
Fred Draked86ed291999-12-15 15:34:33 +000011015#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011016 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011017#endif
11018#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011019 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011020#endif
Fred Drakec9680921999-12-13 16:37:25 +000011021#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011023#endif
11024#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011025 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011026#endif
11027#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011028 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011029#endif
11030#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011031 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011032#endif
Fred Draked86ed291999-12-15 15:34:33 +000011033#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011034 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011035#endif
Fred Drakec9680921999-12-13 16:37:25 +000011036#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011037 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011038#endif
11039#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011040 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011041#endif
11042#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011043 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011044#endif
11045#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011046 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011047#endif
11048#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011049 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011050#endif
11051#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011052 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011053#endif
11054#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011055 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011056#endif
Fred Draked86ed291999-12-15 15:34:33 +000011057#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011058 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011059#endif
Fred Drakec9680921999-12-13 16:37:25 +000011060#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011061 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011062#endif
11063#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011065#endif
Fred Draked86ed291999-12-15 15:34:33 +000011066#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011068#endif
Fred Drakec9680921999-12-13 16:37:25 +000011069#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011070 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011071#endif
11072#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011073 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011074#endif
11075#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011076 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011077#endif
11078#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011079 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011080#endif
11081#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011082 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011083#endif
11084#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011086#endif
11087#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011088 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011089#endif
11090#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011091 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011092#endif
11093#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011094 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011095#endif
Fred Draked86ed291999-12-15 15:34:33 +000011096#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011097 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011098#endif
11099#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011100 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011101#endif
Fred Drakec9680921999-12-13 16:37:25 +000011102#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011103 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011104#endif
11105#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011106 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011107#endif
11108#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011110#endif
11111#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011112 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011113#endif
11114#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011115 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011116#endif
11117#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011118 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011119#endif
11120#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011121 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011122#endif
11123#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011124 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011125#endif
11126#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011127 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011128#endif
11129#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011130 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011131#endif
11132#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011133 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011134#endif
11135#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011136 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011137#endif
11138#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011139 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011140#endif
11141#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011142 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011143#endif
11144#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011145 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011146#endif
11147#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011149#endif
11150#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011151 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011152#endif
11153#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011155#endif
11156#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011158#endif
11159#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011161#endif
11162#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011164#endif
11165#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011167#endif
11168#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011170#endif
11171#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011173#endif
11174#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011175 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011176#endif
11177#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011178 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011179#endif
11180#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011181 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011182#endif
11183#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011184 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011185#endif
11186#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011187 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011188#endif
11189#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011190 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011191#endif
11192#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011193 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011194#endif
11195#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011196 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011197#endif
11198#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011199 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011200#endif
11201#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011202 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011203#endif
11204#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011205 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011206#endif
Fred Draked86ed291999-12-15 15:34:33 +000011207#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011208 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011209#endif
Fred Drakec9680921999-12-13 16:37:25 +000011210#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011211 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011212#endif
11213#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011215#endif
11216#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011218#endif
11219#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011221#endif
11222#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011223 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011224#endif
11225#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011227#endif
11228#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011230#endif
11231#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011233#endif
11234#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011235 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011236#endif
11237#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011239#endif
11240#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011242#endif
11243#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011245#endif
11246#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011248#endif
11249#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011250 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011251#endif
11252#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011254#endif
11255#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011257#endif
11258#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011260#endif
11261#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011263#endif
11264#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011266#endif
11267#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011268 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011269#endif
11270#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011272#endif
11273#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011274 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011275#endif
11276#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011278#endif
11279#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011281#endif
11282#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011284#endif
11285#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011287#endif
11288#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011290#endif
11291#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011293#endif
11294#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011295 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011296#endif
11297#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011299#endif
11300#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011302#endif
11303#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011305#endif
11306#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011308#endif
11309#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011311#endif
11312#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011314#endif
11315#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011317#endif
11318#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011320#endif
11321#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011323#endif
11324#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011326#endif
11327#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011328 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011329#endif
11330#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011331 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011332#endif
11333#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011334 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011335#endif
11336#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011338#endif
11339#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011340 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011341#endif
11342#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011343 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011344#endif
11345};
11346
11347static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011348conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011349{
11350 return conv_confname(arg, valuep, posix_constants_sysconf,
11351 sizeof(posix_constants_sysconf)
11352 / sizeof(struct constdef));
11353}
11354
Larry Hastings2f936352014-08-05 14:04:04 +100011355
11356/*[clinic input]
11357os.sysconf -> long
11358 name: sysconf_confname
11359 /
11360
11361Return an integer-valued system configuration variable.
11362[clinic start generated code]*/
11363
Larry Hastings2f936352014-08-05 14:04:04 +100011364static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011365os_sysconf_impl(PyObject *module, int name)
11366/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011367{
11368 long value;
11369
11370 errno = 0;
11371 value = sysconf(name);
11372 if (value == -1 && errno != 0)
11373 posix_error();
11374 return value;
11375}
11376#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011377
11378
Fred Drakebec628d1999-12-15 18:31:10 +000011379/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011380 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011381 * the exported dictionaries that are used to publish information about the
11382 * names available on the host platform.
11383 *
11384 * Sorting the table at runtime ensures that the table is properly ordered
11385 * when used, even for platforms we're not able to test on. It also makes
11386 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011387 */
Fred Drakebec628d1999-12-15 18:31:10 +000011388
11389static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011390cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011391{
11392 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011394 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011395 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011396
11397 return strcmp(c1->name, c2->name);
11398}
11399
11400static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011401setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011402 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011403{
Fred Drakebec628d1999-12-15 18:31:10 +000011404 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011405 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011406
11407 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11408 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011409 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011410 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011411
Barry Warsaw3155db32000-04-13 15:20:40 +000011412 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011413 PyObject *o = PyLong_FromLong(table[i].value);
11414 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11415 Py_XDECREF(o);
11416 Py_DECREF(d);
11417 return -1;
11418 }
11419 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011420 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011421 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011422}
11423
Fred Drakebec628d1999-12-15 18:31:10 +000011424/* Return -1 on failure, 0 on success. */
11425static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011426setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011427{
11428#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011429 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011430 sizeof(posix_constants_pathconf)
11431 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011432 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011433 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011434#endif
11435#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011436 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011437 sizeof(posix_constants_confstr)
11438 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011439 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011440 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011441#endif
11442#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011443 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011444 sizeof(posix_constants_sysconf)
11445 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011446 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011447 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011448#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011449 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011450}
Fred Draked86ed291999-12-15 15:34:33 +000011451
11452
Larry Hastings2f936352014-08-05 14:04:04 +100011453/*[clinic input]
11454os.abort
11455
11456Abort the interpreter immediately.
11457
11458This function 'dumps core' or otherwise fails in the hardest way possible
11459on the hosting operating system. This function never returns.
11460[clinic start generated code]*/
11461
Larry Hastings2f936352014-08-05 14:04:04 +100011462static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011463os_abort_impl(PyObject *module)
11464/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011465{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011466 abort();
11467 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011468#ifndef __clang__
11469 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11470 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11471 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011472 Py_FatalError("abort() called from Python code didn't abort!");
11473 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011474#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011475}
Fred Drakebec628d1999-12-15 18:31:10 +000011476
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011477#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011478/* Grab ShellExecute dynamically from shell32 */
11479static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011480static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11481 LPCWSTR, INT);
11482static int
11483check_ShellExecute()
11484{
11485 HINSTANCE hShell32;
11486
11487 /* only recheck */
11488 if (-1 == has_ShellExecute) {
11489 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011490 /* Security note: this call is not vulnerable to "DLL hijacking".
11491 SHELL32 is part of "KnownDLLs" and so Windows always load
11492 the system SHELL32.DLL, even if there is another SHELL32.DLL
11493 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011494 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011495 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011496 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11497 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011498 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011499 } else {
11500 has_ShellExecute = 0;
11501 }
Tony Roberts4860f012019-02-02 18:16:42 +010011502 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011503 }
11504 return has_ShellExecute;
11505}
11506
11507
Steve Dowercc16be82016-09-08 10:35:16 -070011508/*[clinic input]
11509os.startfile
11510 filepath: path_t
11511 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011512
Steve Dowercc16be82016-09-08 10:35:16 -070011513startfile(filepath [, operation])
11514
11515Start a file with its associated application.
11516
11517When "operation" is not specified or "open", this acts like
11518double-clicking the file in Explorer, or giving the file name as an
11519argument to the DOS "start" command: the file is opened with whatever
11520application (if any) its extension is associated.
11521When another "operation" is given, it specifies what should be done with
11522the file. A typical operation is "print".
11523
11524startfile returns as soon as the associated application is launched.
11525There is no option to wait for the application to close, and no way
11526to retrieve the application's exit status.
11527
11528The filepath is relative to the current directory. If you want to use
11529an absolute path, make sure the first character is not a slash ("/");
11530the underlying Win32 ShellExecute function doesn't work if it is.
11531[clinic start generated code]*/
11532
11533static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011534os_startfile_impl(PyObject *module, path_t *filepath,
11535 const Py_UNICODE *operation)
11536/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011537{
11538 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011539
11540 if(!check_ShellExecute()) {
11541 /* If the OS doesn't have ShellExecute, return a
11542 NotImplementedError. */
11543 return PyErr_Format(PyExc_NotImplementedError,
11544 "startfile not available on this platform");
11545 }
11546
Victor Stinner8c62be82010-05-06 00:08:46 +000011547 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011548 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011549 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011550 Py_END_ALLOW_THREADS
11551
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011553 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011554 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 }
Steve Dowercc16be82016-09-08 10:35:16 -070011556 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011557}
Larry Hastings2f936352014-08-05 14:04:04 +100011558#endif /* MS_WINDOWS */
11559
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011560
Martin v. Löwis438b5342002-12-27 10:16:42 +000011561#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011562/*[clinic input]
11563os.getloadavg
11564
11565Return average recent system load information.
11566
11567Return the number of processes in the system run queue averaged over
11568the last 1, 5, and 15 minutes as a tuple of three floats.
11569Raises OSError if the load average was unobtainable.
11570[clinic start generated code]*/
11571
Larry Hastings2f936352014-08-05 14:04:04 +100011572static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011573os_getloadavg_impl(PyObject *module)
11574/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011575{
11576 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011577 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011578 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11579 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011580 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011581 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011582}
Larry Hastings2f936352014-08-05 14:04:04 +100011583#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011584
Larry Hastings2f936352014-08-05 14:04:04 +100011585
11586/*[clinic input]
11587os.device_encoding
11588 fd: int
11589
11590Return a string describing the encoding of a terminal's file descriptor.
11591
11592The file descriptor must be attached to a terminal.
11593If the device is not a terminal, return None.
11594[clinic start generated code]*/
11595
Larry Hastings2f936352014-08-05 14:04:04 +100011596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011597os_device_encoding_impl(PyObject *module, int fd)
11598/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011599{
Brett Cannonefb00c02012-02-29 18:31:31 -050011600 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011601}
11602
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011603
Larry Hastings2f936352014-08-05 14:04:04 +100011604#ifdef HAVE_SETRESUID
11605/*[clinic input]
11606os.setresuid
11607
11608 ruid: uid_t
11609 euid: uid_t
11610 suid: uid_t
11611 /
11612
11613Set the current process's real, effective, and saved user ids.
11614[clinic start generated code]*/
11615
Larry Hastings2f936352014-08-05 14:04:04 +100011616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011617os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11618/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011619{
Victor Stinner8c62be82010-05-06 00:08:46 +000011620 if (setresuid(ruid, euid, suid) < 0)
11621 return posix_error();
11622 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011623}
Larry Hastings2f936352014-08-05 14:04:04 +100011624#endif /* HAVE_SETRESUID */
11625
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011626
11627#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011628/*[clinic input]
11629os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011630
Larry Hastings2f936352014-08-05 14:04:04 +100011631 rgid: gid_t
11632 egid: gid_t
11633 sgid: gid_t
11634 /
11635
11636Set the current process's real, effective, and saved group ids.
11637[clinic start generated code]*/
11638
Larry Hastings2f936352014-08-05 14:04:04 +100011639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011640os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11641/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011642{
Victor Stinner8c62be82010-05-06 00:08:46 +000011643 if (setresgid(rgid, egid, sgid) < 0)
11644 return posix_error();
11645 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011646}
Larry Hastings2f936352014-08-05 14:04:04 +100011647#endif /* HAVE_SETRESGID */
11648
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011649
11650#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011651/*[clinic input]
11652os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011653
Larry Hastings2f936352014-08-05 14:04:04 +100011654Return a tuple of the current process's real, effective, and saved user ids.
11655[clinic start generated code]*/
11656
Larry Hastings2f936352014-08-05 14:04:04 +100011657static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011658os_getresuid_impl(PyObject *module)
11659/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011660{
Victor Stinner8c62be82010-05-06 00:08:46 +000011661 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011662 if (getresuid(&ruid, &euid, &suid) < 0)
11663 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011664 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11665 _PyLong_FromUid(euid),
11666 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011667}
Larry Hastings2f936352014-08-05 14:04:04 +100011668#endif /* HAVE_GETRESUID */
11669
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011670
11671#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011672/*[clinic input]
11673os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011674
Larry Hastings2f936352014-08-05 14:04:04 +100011675Return a tuple of the current process's real, effective, and saved group ids.
11676[clinic start generated code]*/
11677
Larry Hastings2f936352014-08-05 14:04:04 +100011678static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011679os_getresgid_impl(PyObject *module)
11680/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011681{
11682 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011683 if (getresgid(&rgid, &egid, &sgid) < 0)
11684 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011685 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11686 _PyLong_FromGid(egid),
11687 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011688}
Larry Hastings2f936352014-08-05 14:04:04 +100011689#endif /* HAVE_GETRESGID */
11690
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011691
Benjamin Peterson9428d532011-09-14 11:45:52 -040011692#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011693/*[clinic input]
11694os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011695
Larry Hastings2f936352014-08-05 14:04:04 +100011696 path: path_t(allow_fd=True)
11697 attribute: path_t
11698 *
11699 follow_symlinks: bool = True
11700
11701Return the value of extended attribute attribute on path.
11702
BNMetricsb9427072018-11-02 15:20:19 +000011703path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011704If follow_symlinks is False, and the last element of the path is a symbolic
11705 link, getxattr will examine the symbolic link itself instead of the file
11706 the link points to.
11707
11708[clinic start generated code]*/
11709
Larry Hastings2f936352014-08-05 14:04:04 +100011710static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011711os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011712 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011713/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011714{
11715 Py_ssize_t i;
11716 PyObject *buffer = NULL;
11717
11718 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11719 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011720
Larry Hastings9cf065c2012-06-22 16:30:09 -070011721 for (i = 0; ; i++) {
11722 void *ptr;
11723 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011724 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011725 Py_ssize_t buffer_size = buffer_sizes[i];
11726 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011727 path_error(path);
11728 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011729 }
11730 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11731 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011732 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011733 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011734
Larry Hastings9cf065c2012-06-22 16:30:09 -070011735 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011736 if (path->fd >= 0)
11737 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011738 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011739 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011740 else
Larry Hastings2f936352014-08-05 14:04:04 +100011741 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011742 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011743
Larry Hastings9cf065c2012-06-22 16:30:09 -070011744 if (result < 0) {
11745 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011746 if (errno == ERANGE)
11747 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011748 path_error(path);
11749 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011750 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011751
Larry Hastings9cf065c2012-06-22 16:30:09 -070011752 if (result != buffer_size) {
11753 /* Can only shrink. */
11754 _PyBytes_Resize(&buffer, result);
11755 }
11756 break;
11757 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011758
Larry Hastings9cf065c2012-06-22 16:30:09 -070011759 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011760}
11761
Larry Hastings2f936352014-08-05 14:04:04 +100011762
11763/*[clinic input]
11764os.setxattr
11765
11766 path: path_t(allow_fd=True)
11767 attribute: path_t
11768 value: Py_buffer
11769 flags: int = 0
11770 *
11771 follow_symlinks: bool = True
11772
11773Set extended attribute attribute on path to value.
11774
BNMetricsb9427072018-11-02 15:20:19 +000011775path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011776If follow_symlinks is False, and the last element of the path is a symbolic
11777 link, setxattr will modify the symbolic link itself instead of the file
11778 the link points to.
11779
11780[clinic start generated code]*/
11781
Benjamin Peterson799bd802011-08-31 22:15:17 -040011782static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011783os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011784 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011785/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011786{
Larry Hastings2f936352014-08-05 14:04:04 +100011787 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011788
Larry Hastings2f936352014-08-05 14:04:04 +100011789 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011790 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011791
Benjamin Peterson799bd802011-08-31 22:15:17 -040011792 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011793 if (path->fd > -1)
11794 result = fsetxattr(path->fd, attribute->narrow,
11795 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011796 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011797 result = setxattr(path->narrow, attribute->narrow,
11798 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011799 else
Larry Hastings2f936352014-08-05 14:04:04 +100011800 result = lsetxattr(path->narrow, attribute->narrow,
11801 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011802 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011803
Larry Hastings9cf065c2012-06-22 16:30:09 -070011804 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011805 path_error(path);
11806 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011807 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011808
Larry Hastings2f936352014-08-05 14:04:04 +100011809 Py_RETURN_NONE;
11810}
11811
11812
11813/*[clinic input]
11814os.removexattr
11815
11816 path: path_t(allow_fd=True)
11817 attribute: path_t
11818 *
11819 follow_symlinks: bool = True
11820
11821Remove extended attribute attribute on path.
11822
BNMetricsb9427072018-11-02 15:20:19 +000011823path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011824If follow_symlinks is False, and the last element of the path is a symbolic
11825 link, removexattr will modify the symbolic link itself instead of the file
11826 the link points to.
11827
11828[clinic start generated code]*/
11829
Larry Hastings2f936352014-08-05 14:04:04 +100011830static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011831os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011832 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011833/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011834{
11835 ssize_t result;
11836
11837 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11838 return NULL;
11839
11840 Py_BEGIN_ALLOW_THREADS;
11841 if (path->fd > -1)
11842 result = fremovexattr(path->fd, attribute->narrow);
11843 else if (follow_symlinks)
11844 result = removexattr(path->narrow, attribute->narrow);
11845 else
11846 result = lremovexattr(path->narrow, attribute->narrow);
11847 Py_END_ALLOW_THREADS;
11848
11849 if (result) {
11850 return path_error(path);
11851 }
11852
11853 Py_RETURN_NONE;
11854}
11855
11856
11857/*[clinic input]
11858os.listxattr
11859
11860 path: path_t(allow_fd=True, nullable=True) = None
11861 *
11862 follow_symlinks: bool = True
11863
11864Return a list of extended attributes on path.
11865
BNMetricsb9427072018-11-02 15:20:19 +000011866path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011867if path is None, listxattr will examine the current directory.
11868If follow_symlinks is False, and the last element of the path is a symbolic
11869 link, listxattr will examine the symbolic link itself instead of the file
11870 the link points to.
11871[clinic start generated code]*/
11872
Larry Hastings2f936352014-08-05 14:04:04 +100011873static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011874os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011875/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011876{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011877 Py_ssize_t i;
11878 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011879 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011880 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011881
Larry Hastings2f936352014-08-05 14:04:04 +100011882 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011883 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011884
Larry Hastings2f936352014-08-05 14:04:04 +100011885 name = path->narrow ? path->narrow : ".";
11886
Larry Hastings9cf065c2012-06-22 16:30:09 -070011887 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011888 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011889 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011890 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011891 Py_ssize_t buffer_size = buffer_sizes[i];
11892 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011893 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011894 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011895 break;
11896 }
11897 buffer = PyMem_MALLOC(buffer_size);
11898 if (!buffer) {
11899 PyErr_NoMemory();
11900 break;
11901 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011902
Larry Hastings9cf065c2012-06-22 16:30:09 -070011903 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011904 if (path->fd > -1)
11905 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011906 else if (follow_symlinks)
11907 length = listxattr(name, buffer, buffer_size);
11908 else
11909 length = llistxattr(name, buffer, buffer_size);
11910 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011911
Larry Hastings9cf065c2012-06-22 16:30:09 -070011912 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011913 if (errno == ERANGE) {
11914 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011915 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011916 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011917 }
Larry Hastings2f936352014-08-05 14:04:04 +100011918 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011919 break;
11920 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011921
Larry Hastings9cf065c2012-06-22 16:30:09 -070011922 result = PyList_New(0);
11923 if (!result) {
11924 goto exit;
11925 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011926
Larry Hastings9cf065c2012-06-22 16:30:09 -070011927 end = buffer + length;
11928 for (trace = start = buffer; trace != end; trace++) {
11929 if (!*trace) {
11930 int error;
11931 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11932 trace - start);
11933 if (!attribute) {
11934 Py_DECREF(result);
11935 result = NULL;
11936 goto exit;
11937 }
11938 error = PyList_Append(result, attribute);
11939 Py_DECREF(attribute);
11940 if (error) {
11941 Py_DECREF(result);
11942 result = NULL;
11943 goto exit;
11944 }
11945 start = trace + 1;
11946 }
11947 }
11948 break;
11949 }
11950exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011951 if (buffer)
11952 PyMem_FREE(buffer);
11953 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011954}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011955#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011956
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011957
Larry Hastings2f936352014-08-05 14:04:04 +100011958/*[clinic input]
11959os.urandom
11960
11961 size: Py_ssize_t
11962 /
11963
11964Return a bytes object containing random bytes suitable for cryptographic use.
11965[clinic start generated code]*/
11966
Larry Hastings2f936352014-08-05 14:04:04 +100011967static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011968os_urandom_impl(PyObject *module, Py_ssize_t size)
11969/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011970{
11971 PyObject *bytes;
11972 int result;
11973
Georg Brandl2fb477c2012-02-21 00:33:36 +010011974 if (size < 0)
11975 return PyErr_Format(PyExc_ValueError,
11976 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011977 bytes = PyBytes_FromStringAndSize(NULL, size);
11978 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011979 return NULL;
11980
Victor Stinnere66987e2016-09-06 16:33:52 -070011981 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011982 if (result == -1) {
11983 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011984 return NULL;
11985 }
Larry Hastings2f936352014-08-05 14:04:04 +100011986 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011987}
11988
Zackery Spytz43fdbd22019-05-29 13:57:07 -060011989#ifdef HAVE_MEMFD_CREATE
11990/*[clinic input]
11991os.memfd_create
11992
11993 name: FSConverter
11994 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
11995
11996[clinic start generated code]*/
11997
11998static PyObject *
11999os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12000/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12001{
12002 int fd;
12003 const char *bytes = PyBytes_AS_STRING(name);
12004 Py_BEGIN_ALLOW_THREADS
12005 fd = memfd_create(bytes, flags);
12006 Py_END_ALLOW_THREADS
12007 if (fd == -1) {
12008 return PyErr_SetFromErrno(PyExc_OSError);
12009 }
12010 return PyLong_FromLong(fd);
12011}
12012#endif
12013
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012014/* Terminal size querying */
12015
Eddie Elizondo474eedf2018-11-13 04:09:31 -080012016static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012017
12018PyDoc_STRVAR(TerminalSize_docstring,
12019 "A tuple of (columns, lines) for holding terminal window size");
12020
12021static PyStructSequence_Field TerminalSize_fields[] = {
12022 {"columns", "width of the terminal window in characters"},
12023 {"lines", "height of the terminal window in characters"},
12024 {NULL, NULL}
12025};
12026
12027static PyStructSequence_Desc TerminalSize_desc = {
12028 "os.terminal_size",
12029 TerminalSize_docstring,
12030 TerminalSize_fields,
12031 2,
12032};
12033
12034#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100012035/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012036PyDoc_STRVAR(termsize__doc__,
12037 "Return the size of the terminal window as (columns, lines).\n" \
12038 "\n" \
12039 "The optional argument fd (default standard output) specifies\n" \
12040 "which file descriptor should be queried.\n" \
12041 "\n" \
12042 "If the file descriptor is not connected to a terminal, an OSError\n" \
12043 "is thrown.\n" \
12044 "\n" \
12045 "This function will only be defined if an implementation is\n" \
12046 "available for this system.\n" \
12047 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080012048 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012049 "normally be used, os.get_terminal_size is the low-level implementation.");
12050
12051static PyObject*
12052get_terminal_size(PyObject *self, PyObject *args)
12053{
12054 int columns, lines;
12055 PyObject *termsize;
12056
12057 int fd = fileno(stdout);
12058 /* Under some conditions stdout may not be connected and
12059 * fileno(stdout) may point to an invalid file descriptor. For example
12060 * GUI apps don't have valid standard streams by default.
12061 *
12062 * If this happens, and the optional fd argument is not present,
12063 * the ioctl below will fail returning EBADF. This is what we want.
12064 */
12065
12066 if (!PyArg_ParseTuple(args, "|i", &fd))
12067 return NULL;
12068
12069#ifdef TERMSIZE_USE_IOCTL
12070 {
12071 struct winsize w;
12072 if (ioctl(fd, TIOCGWINSZ, &w))
12073 return PyErr_SetFromErrno(PyExc_OSError);
12074 columns = w.ws_col;
12075 lines = w.ws_row;
12076 }
12077#endif /* TERMSIZE_USE_IOCTL */
12078
12079#ifdef TERMSIZE_USE_CONIO
12080 {
12081 DWORD nhandle;
12082 HANDLE handle;
12083 CONSOLE_SCREEN_BUFFER_INFO csbi;
12084 switch (fd) {
12085 case 0: nhandle = STD_INPUT_HANDLE;
12086 break;
12087 case 1: nhandle = STD_OUTPUT_HANDLE;
12088 break;
12089 case 2: nhandle = STD_ERROR_HANDLE;
12090 break;
12091 default:
12092 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12093 }
12094 handle = GetStdHandle(nhandle);
12095 if (handle == NULL)
12096 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12097 if (handle == INVALID_HANDLE_VALUE)
12098 return PyErr_SetFromWindowsErr(0);
12099
12100 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12101 return PyErr_SetFromWindowsErr(0);
12102
12103 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12104 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12105 }
12106#endif /* TERMSIZE_USE_CONIO */
12107
Eddie Elizondo474eedf2018-11-13 04:09:31 -080012108 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012109 if (termsize == NULL)
12110 return NULL;
12111 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12112 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12113 if (PyErr_Occurred()) {
12114 Py_DECREF(termsize);
12115 return NULL;
12116 }
12117 return termsize;
12118}
12119#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12120
Larry Hastings2f936352014-08-05 14:04:04 +100012121
12122/*[clinic input]
12123os.cpu_count
12124
Charles-François Natali80d62e62015-08-13 20:37:08 +010012125Return the number of CPUs in the system; return None if indeterminable.
12126
12127This number is not equivalent to the number of CPUs the current process can
12128use. The number of usable CPUs can be obtained with
12129``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012130[clinic start generated code]*/
12131
Larry Hastings2f936352014-08-05 14:04:04 +100012132static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012133os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012134/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012135{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012136 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012137#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012138 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
12139 Need to fallback to Vista behavior if this call isn't present */
12140 HINSTANCE hKernel32;
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012141 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
Tony Roberts4860f012019-02-02 18:16:42 +010012142 Py_BEGIN_ALLOW_THREADS
12143 hKernel32 = GetModuleHandleW(L"KERNEL32");
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012144 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
12145 "GetMaximumProcessorCount");
Tony Roberts4860f012019-02-02 18:16:42 +010012146 Py_END_ALLOW_THREADS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012147 if (_GetMaximumProcessorCount != NULL) {
12148 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
12149 }
12150 else {
12151 SYSTEM_INFO sysinfo;
12152 GetSystemInfo(&sysinfo);
12153 ncpu = sysinfo.dwNumberOfProcessors;
12154 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012155#elif defined(__hpux)
12156 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12157#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12158 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012159#elif defined(__DragonFly__) || \
12160 defined(__OpenBSD__) || \
12161 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012162 defined(__NetBSD__) || \
12163 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012164 int mib[2];
12165 size_t len = sizeof(ncpu);
12166 mib[0] = CTL_HW;
12167 mib[1] = HW_NCPU;
12168 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12169 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012170#endif
12171 if (ncpu >= 1)
12172 return PyLong_FromLong(ncpu);
12173 else
12174 Py_RETURN_NONE;
12175}
12176
Victor Stinnerdaf45552013-08-28 00:53:59 +020012177
Larry Hastings2f936352014-08-05 14:04:04 +100012178/*[clinic input]
12179os.get_inheritable -> bool
12180
12181 fd: int
12182 /
12183
12184Get the close-on-exe flag of the specified file descriptor.
12185[clinic start generated code]*/
12186
Larry Hastings2f936352014-08-05 14:04:04 +100012187static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012188os_get_inheritable_impl(PyObject *module, int fd)
12189/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012190{
Steve Dower8fc89802015-04-12 00:26:27 -040012191 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012192 _Py_BEGIN_SUPPRESS_IPH
12193 return_value = _Py_get_inheritable(fd);
12194 _Py_END_SUPPRESS_IPH
12195 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012196}
12197
12198
12199/*[clinic input]
12200os.set_inheritable
12201 fd: int
12202 inheritable: int
12203 /
12204
12205Set the inheritable flag of the specified file descriptor.
12206[clinic start generated code]*/
12207
Larry Hastings2f936352014-08-05 14:04:04 +100012208static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012209os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12210/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012211{
Steve Dower8fc89802015-04-12 00:26:27 -040012212 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012213
Steve Dower8fc89802015-04-12 00:26:27 -040012214 _Py_BEGIN_SUPPRESS_IPH
12215 result = _Py_set_inheritable(fd, inheritable, NULL);
12216 _Py_END_SUPPRESS_IPH
12217 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012218 return NULL;
12219 Py_RETURN_NONE;
12220}
12221
12222
12223#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012224/*[clinic input]
12225os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012226 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012227 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012228
Larry Hastings2f936352014-08-05 14:04:04 +100012229Get the close-on-exe flag of the specified file descriptor.
12230[clinic start generated code]*/
12231
Larry Hastings2f936352014-08-05 14:04:04 +100012232static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012233os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012234/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012235{
12236 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012237
12238 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12239 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012240 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012241 }
12242
Larry Hastings2f936352014-08-05 14:04:04 +100012243 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012244}
12245
Victor Stinnerdaf45552013-08-28 00:53:59 +020012246
Larry Hastings2f936352014-08-05 14:04:04 +100012247/*[clinic input]
12248os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012249 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012250 inheritable: bool
12251 /
12252
12253Set the inheritable flag of the specified handle.
12254[clinic start generated code]*/
12255
Larry Hastings2f936352014-08-05 14:04:04 +100012256static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012257os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012258 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012259/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012260{
12261 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012262 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12263 PyErr_SetFromWindowsErr(0);
12264 return NULL;
12265 }
12266 Py_RETURN_NONE;
12267}
Larry Hastings2f936352014-08-05 14:04:04 +100012268#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012269
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012270#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012271/*[clinic input]
12272os.get_blocking -> bool
12273 fd: int
12274 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012275
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012276Get the blocking mode of the file descriptor.
12277
12278Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12279[clinic start generated code]*/
12280
12281static int
12282os_get_blocking_impl(PyObject *module, int fd)
12283/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012284{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012285 int blocking;
12286
Steve Dower8fc89802015-04-12 00:26:27 -040012287 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012288 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012289 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012290 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012291}
12292
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012293/*[clinic input]
12294os.set_blocking
12295 fd: int
12296 blocking: bool(accept={int})
12297 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012298
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012299Set the blocking mode of the specified file descriptor.
12300
12301Set the O_NONBLOCK flag if blocking is False,
12302clear the O_NONBLOCK flag otherwise.
12303[clinic start generated code]*/
12304
12305static PyObject *
12306os_set_blocking_impl(PyObject *module, int fd, int blocking)
12307/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012308{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012309 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012310
Steve Dower8fc89802015-04-12 00:26:27 -040012311 _Py_BEGIN_SUPPRESS_IPH
12312 result = _Py_set_blocking(fd, blocking);
12313 _Py_END_SUPPRESS_IPH
12314 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012315 return NULL;
12316 Py_RETURN_NONE;
12317}
12318#endif /* !MS_WINDOWS */
12319
12320
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012321/*[clinic input]
12322class os.DirEntry "DirEntry *" "&DirEntryType"
12323[clinic start generated code]*/
12324/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012325
12326typedef struct {
12327 PyObject_HEAD
12328 PyObject *name;
12329 PyObject *path;
12330 PyObject *stat;
12331 PyObject *lstat;
12332#ifdef MS_WINDOWS
12333 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012334 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012335 int got_file_index;
12336#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012337#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012338 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012339#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012340 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012341 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012342#endif
12343} DirEntry;
12344
12345static void
12346DirEntry_dealloc(DirEntry *entry)
12347{
12348 Py_XDECREF(entry->name);
12349 Py_XDECREF(entry->path);
12350 Py_XDECREF(entry->stat);
12351 Py_XDECREF(entry->lstat);
12352 Py_TYPE(entry)->tp_free((PyObject *)entry);
12353}
12354
12355/* Forward reference */
12356static int
12357DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12358
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012359/*[clinic input]
12360os.DirEntry.is_symlink -> bool
12361
12362Return True if the entry is a symbolic link; cached per entry.
12363[clinic start generated code]*/
12364
Victor Stinner6036e442015-03-08 01:58:04 +010012365static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012366os_DirEntry_is_symlink_impl(DirEntry *self)
12367/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012368{
12369#ifdef MS_WINDOWS
12370 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012371#elif defined(HAVE_DIRENT_D_TYPE)
12372 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012373 if (self->d_type != DT_UNKNOWN)
12374 return self->d_type == DT_LNK;
12375 else
12376 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012377#else
12378 /* POSIX without d_type */
12379 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012380#endif
12381}
12382
12383static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012384DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12385{
12386 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012387 STRUCT_STAT st;
12388 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012389
12390#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012391 if (!PyUnicode_FSDecoder(self->path, &ub))
12392 return NULL;
12393 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012394#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012395 if (!PyUnicode_FSConverter(self->path, &ub))
12396 return NULL;
12397 const char *path = PyBytes_AS_STRING(ub);
12398 if (self->dir_fd != DEFAULT_DIR_FD) {
12399#ifdef HAVE_FSTATAT
12400 result = fstatat(self->dir_fd, path, &st,
12401 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12402#else
12403 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12404 return NULL;
12405#endif /* HAVE_FSTATAT */
12406 }
12407 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012408#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012409 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012410 if (follow_symlinks)
12411 result = STAT(path, &st);
12412 else
12413 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012414 }
12415 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012416
12417 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012418 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012419
12420 return _pystat_fromstructstat(&st);
12421}
12422
12423static PyObject *
12424DirEntry_get_lstat(DirEntry *self)
12425{
12426 if (!self->lstat) {
12427#ifdef MS_WINDOWS
12428 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12429#else /* POSIX */
12430 self->lstat = DirEntry_fetch_stat(self, 0);
12431#endif
12432 }
12433 Py_XINCREF(self->lstat);
12434 return self->lstat;
12435}
12436
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012437/*[clinic input]
12438os.DirEntry.stat
12439 *
12440 follow_symlinks: bool = True
12441
12442Return stat_result object for the entry; cached per entry.
12443[clinic start generated code]*/
12444
Victor Stinner6036e442015-03-08 01:58:04 +010012445static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012446os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12447/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012448{
12449 if (!follow_symlinks)
12450 return DirEntry_get_lstat(self);
12451
12452 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012453 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012454 if (result == -1)
12455 return NULL;
12456 else if (result)
12457 self->stat = DirEntry_fetch_stat(self, 1);
12458 else
12459 self->stat = DirEntry_get_lstat(self);
12460 }
12461
12462 Py_XINCREF(self->stat);
12463 return self->stat;
12464}
12465
Victor Stinner6036e442015-03-08 01:58:04 +010012466/* Set exception and return -1 on error, 0 for False, 1 for True */
12467static int
12468DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12469{
12470 PyObject *stat = NULL;
12471 PyObject *st_mode = NULL;
12472 long mode;
12473 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012474#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012475 int is_symlink;
12476 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012477#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012478#ifdef MS_WINDOWS
12479 unsigned long dir_bits;
12480#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012481 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012482
12483#ifdef MS_WINDOWS
12484 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12485 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012486#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012487 is_symlink = self->d_type == DT_LNK;
12488 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12489#endif
12490
Victor Stinner35a97c02015-03-08 02:59:09 +010012491#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012492 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012493#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012494 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012495 if (!stat) {
12496 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12497 /* If file doesn't exist (anymore), then return False
12498 (i.e., say it's not a file/directory) */
12499 PyErr_Clear();
12500 return 0;
12501 }
12502 goto error;
12503 }
12504 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12505 if (!st_mode)
12506 goto error;
12507
12508 mode = PyLong_AsLong(st_mode);
12509 if (mode == -1 && PyErr_Occurred())
12510 goto error;
12511 Py_CLEAR(st_mode);
12512 Py_CLEAR(stat);
12513 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012514#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012515 }
12516 else if (is_symlink) {
12517 assert(mode_bits != S_IFLNK);
12518 result = 0;
12519 }
12520 else {
12521 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12522#ifdef MS_WINDOWS
12523 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12524 if (mode_bits == S_IFDIR)
12525 result = dir_bits != 0;
12526 else
12527 result = dir_bits == 0;
12528#else /* POSIX */
12529 if (mode_bits == S_IFDIR)
12530 result = self->d_type == DT_DIR;
12531 else
12532 result = self->d_type == DT_REG;
12533#endif
12534 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012535#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012536
12537 return result;
12538
12539error:
12540 Py_XDECREF(st_mode);
12541 Py_XDECREF(stat);
12542 return -1;
12543}
12544
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012545/*[clinic input]
12546os.DirEntry.is_dir -> bool
12547 *
12548 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012549
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012550Return True if the entry is a directory; cached per entry.
12551[clinic start generated code]*/
12552
12553static int
12554os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12555/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12556{
12557 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012558}
12559
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012560/*[clinic input]
12561os.DirEntry.is_file -> bool
12562 *
12563 follow_symlinks: bool = True
12564
12565Return True if the entry is a file; cached per entry.
12566[clinic start generated code]*/
12567
12568static int
12569os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12570/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012571{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012572 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012573}
12574
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012575/*[clinic input]
12576os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012577
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012578Return inode of the entry; cached per entry.
12579[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012580
12581static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012582os_DirEntry_inode_impl(DirEntry *self)
12583/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012584{
12585#ifdef MS_WINDOWS
12586 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012587 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012588 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012589 STRUCT_STAT stat;
12590 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012591
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012592 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012593 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012594 path = PyUnicode_AsUnicode(unicode);
12595 result = LSTAT(path, &stat);
12596 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012597
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012598 if (result != 0)
12599 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012600
12601 self->win32_file_index = stat.st_ino;
12602 self->got_file_index = 1;
12603 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012604 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12605 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012606#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012607 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12608 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012609#endif
12610}
12611
12612static PyObject *
12613DirEntry_repr(DirEntry *self)
12614{
12615 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12616}
12617
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012618/*[clinic input]
12619os.DirEntry.__fspath__
12620
12621Returns the path for the entry.
12622[clinic start generated code]*/
12623
Brett Cannon96881cd2016-06-10 14:37:21 -070012624static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012625os_DirEntry___fspath___impl(DirEntry *self)
12626/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012627{
12628 Py_INCREF(self->path);
12629 return self->path;
12630}
12631
Victor Stinner6036e442015-03-08 01:58:04 +010012632static PyMemberDef DirEntry_members[] = {
12633 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12634 "the entry's base filename, relative to scandir() \"path\" argument"},
12635 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12636 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12637 {NULL}
12638};
12639
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012640#include "clinic/posixmodule.c.h"
12641
Victor Stinner6036e442015-03-08 01:58:04 +010012642static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012643 OS_DIRENTRY_IS_DIR_METHODDEF
12644 OS_DIRENTRY_IS_FILE_METHODDEF
12645 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12646 OS_DIRENTRY_STAT_METHODDEF
12647 OS_DIRENTRY_INODE_METHODDEF
12648 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012649 {NULL}
12650};
12651
Benjamin Peterson5646de42015-04-12 17:56:34 -040012652static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012653 PyVarObject_HEAD_INIT(NULL, 0)
12654 MODNAME ".DirEntry", /* tp_name */
12655 sizeof(DirEntry), /* tp_basicsize */
12656 0, /* tp_itemsize */
12657 /* methods */
12658 (destructor)DirEntry_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020012659 0, /* tp_vectorcall_offset */
Victor Stinner6036e442015-03-08 01:58:04 +010012660 0, /* tp_getattr */
12661 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020012662 0, /* tp_as_async */
Victor Stinner6036e442015-03-08 01:58:04 +010012663 (reprfunc)DirEntry_repr, /* tp_repr */
12664 0, /* tp_as_number */
12665 0, /* tp_as_sequence */
12666 0, /* tp_as_mapping */
12667 0, /* tp_hash */
12668 0, /* tp_call */
12669 0, /* tp_str */
12670 0, /* tp_getattro */
12671 0, /* tp_setattro */
12672 0, /* tp_as_buffer */
12673 Py_TPFLAGS_DEFAULT, /* tp_flags */
12674 0, /* tp_doc */
12675 0, /* tp_traverse */
12676 0, /* tp_clear */
12677 0, /* tp_richcompare */
12678 0, /* tp_weaklistoffset */
12679 0, /* tp_iter */
12680 0, /* tp_iternext */
12681 DirEntry_methods, /* tp_methods */
12682 DirEntry_members, /* tp_members */
12683};
12684
12685#ifdef MS_WINDOWS
12686
12687static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012688join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012689{
12690 Py_ssize_t path_len;
12691 Py_ssize_t size;
12692 wchar_t *result;
12693 wchar_t ch;
12694
12695 if (!path_wide) { /* Default arg: "." */
12696 path_wide = L".";
12697 path_len = 1;
12698 }
12699 else {
12700 path_len = wcslen(path_wide);
12701 }
12702
12703 /* The +1's are for the path separator and the NUL */
12704 size = path_len + 1 + wcslen(filename) + 1;
12705 result = PyMem_New(wchar_t, size);
12706 if (!result) {
12707 PyErr_NoMemory();
12708 return NULL;
12709 }
12710 wcscpy(result, path_wide);
12711 if (path_len > 0) {
12712 ch = result[path_len - 1];
12713 if (ch != SEP && ch != ALTSEP && ch != L':')
12714 result[path_len++] = SEP;
12715 wcscpy(result + path_len, filename);
12716 }
12717 return result;
12718}
12719
12720static PyObject *
12721DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12722{
12723 DirEntry *entry;
12724 BY_HANDLE_FILE_INFORMATION file_info;
12725 ULONG reparse_tag;
12726 wchar_t *joined_path;
12727
12728 entry = PyObject_New(DirEntry, &DirEntryType);
12729 if (!entry)
12730 return NULL;
12731 entry->name = NULL;
12732 entry->path = NULL;
12733 entry->stat = NULL;
12734 entry->lstat = NULL;
12735 entry->got_file_index = 0;
12736
12737 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12738 if (!entry->name)
12739 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012740 if (path->narrow) {
12741 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12742 if (!entry->name)
12743 goto error;
12744 }
Victor Stinner6036e442015-03-08 01:58:04 +010012745
12746 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12747 if (!joined_path)
12748 goto error;
12749
12750 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12751 PyMem_Free(joined_path);
12752 if (!entry->path)
12753 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012754 if (path->narrow) {
12755 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12756 if (!entry->path)
12757 goto error;
12758 }
Victor Stinner6036e442015-03-08 01:58:04 +010012759
Steve Dowercc16be82016-09-08 10:35:16 -070012760 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012761 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12762
12763 return (PyObject *)entry;
12764
12765error:
12766 Py_DECREF(entry);
12767 return NULL;
12768}
12769
12770#else /* POSIX */
12771
12772static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012773join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012774{
12775 Py_ssize_t path_len;
12776 Py_ssize_t size;
12777 char *result;
12778
12779 if (!path_narrow) { /* Default arg: "." */
12780 path_narrow = ".";
12781 path_len = 1;
12782 }
12783 else {
12784 path_len = strlen(path_narrow);
12785 }
12786
12787 if (filename_len == -1)
12788 filename_len = strlen(filename);
12789
12790 /* The +1's are for the path separator and the NUL */
12791 size = path_len + 1 + filename_len + 1;
12792 result = PyMem_New(char, size);
12793 if (!result) {
12794 PyErr_NoMemory();
12795 return NULL;
12796 }
12797 strcpy(result, path_narrow);
12798 if (path_len > 0 && result[path_len - 1] != '/')
12799 result[path_len++] = '/';
12800 strcpy(result + path_len, filename);
12801 return result;
12802}
12803
12804static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012805DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012806 ino_t d_ino
12807#ifdef HAVE_DIRENT_D_TYPE
12808 , unsigned char d_type
12809#endif
12810 )
Victor Stinner6036e442015-03-08 01:58:04 +010012811{
12812 DirEntry *entry;
12813 char *joined_path;
12814
12815 entry = PyObject_New(DirEntry, &DirEntryType);
12816 if (!entry)
12817 return NULL;
12818 entry->name = NULL;
12819 entry->path = NULL;
12820 entry->stat = NULL;
12821 entry->lstat = NULL;
12822
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012823 if (path->fd != -1) {
12824 entry->dir_fd = path->fd;
12825 joined_path = NULL;
12826 }
12827 else {
12828 entry->dir_fd = DEFAULT_DIR_FD;
12829 joined_path = join_path_filename(path->narrow, name, name_len);
12830 if (!joined_path)
12831 goto error;
12832 }
Victor Stinner6036e442015-03-08 01:58:04 +010012833
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012834 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012835 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012836 if (joined_path)
12837 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012838 }
12839 else {
12840 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012841 if (joined_path)
12842 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012843 }
12844 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012845 if (!entry->name)
12846 goto error;
12847
12848 if (path->fd != -1) {
12849 entry->path = entry->name;
12850 Py_INCREF(entry->path);
12851 }
12852 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012853 goto error;
12854
Victor Stinner35a97c02015-03-08 02:59:09 +010012855#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012856 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012857#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012858 entry->d_ino = d_ino;
12859
12860 return (PyObject *)entry;
12861
12862error:
12863 Py_XDECREF(entry);
12864 return NULL;
12865}
12866
12867#endif
12868
12869
12870typedef struct {
12871 PyObject_HEAD
12872 path_t path;
12873#ifdef MS_WINDOWS
12874 HANDLE handle;
12875 WIN32_FIND_DATAW file_data;
12876 int first_time;
12877#else /* POSIX */
12878 DIR *dirp;
12879#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012880#ifdef HAVE_FDOPENDIR
12881 int fd;
12882#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012883} ScandirIterator;
12884
12885#ifdef MS_WINDOWS
12886
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012887static int
12888ScandirIterator_is_closed(ScandirIterator *iterator)
12889{
12890 return iterator->handle == INVALID_HANDLE_VALUE;
12891}
12892
Victor Stinner6036e442015-03-08 01:58:04 +010012893static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012894ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012895{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012896 HANDLE handle = iterator->handle;
12897
12898 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012899 return;
12900
Victor Stinner6036e442015-03-08 01:58:04 +010012901 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012902 Py_BEGIN_ALLOW_THREADS
12903 FindClose(handle);
12904 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012905}
12906
12907static PyObject *
12908ScandirIterator_iternext(ScandirIterator *iterator)
12909{
12910 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12911 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012912 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012913
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012914 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012915 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012916 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012917
12918 while (1) {
12919 if (!iterator->first_time) {
12920 Py_BEGIN_ALLOW_THREADS
12921 success = FindNextFileW(iterator->handle, file_data);
12922 Py_END_ALLOW_THREADS
12923 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012924 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012925 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012926 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012927 break;
12928 }
12929 }
12930 iterator->first_time = 0;
12931
12932 /* Skip over . and .. */
12933 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012934 wcscmp(file_data->cFileName, L"..") != 0) {
12935 entry = DirEntry_from_find_data(&iterator->path, file_data);
12936 if (!entry)
12937 break;
12938 return entry;
12939 }
Victor Stinner6036e442015-03-08 01:58:04 +010012940
12941 /* Loop till we get a non-dot directory or finish iterating */
12942 }
12943
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012944 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012945 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012946 return NULL;
12947}
12948
12949#else /* POSIX */
12950
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012951static int
12952ScandirIterator_is_closed(ScandirIterator *iterator)
12953{
12954 return !iterator->dirp;
12955}
12956
Victor Stinner6036e442015-03-08 01:58:04 +010012957static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012958ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012959{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012960 DIR *dirp = iterator->dirp;
12961
12962 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012963 return;
12964
Victor Stinner6036e442015-03-08 01:58:04 +010012965 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012966 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012967#ifdef HAVE_FDOPENDIR
12968 if (iterator->path.fd != -1)
12969 rewinddir(dirp);
12970#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012971 closedir(dirp);
12972 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012973 return;
12974}
12975
12976static PyObject *
12977ScandirIterator_iternext(ScandirIterator *iterator)
12978{
12979 struct dirent *direntp;
12980 Py_ssize_t name_len;
12981 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012982 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012983
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012984 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012985 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012986 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012987
12988 while (1) {
12989 errno = 0;
12990 Py_BEGIN_ALLOW_THREADS
12991 direntp = readdir(iterator->dirp);
12992 Py_END_ALLOW_THREADS
12993
12994 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012995 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012996 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012997 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012998 break;
12999 }
13000
13001 /* Skip over . and .. */
13002 name_len = NAMLEN(direntp);
13003 is_dot = direntp->d_name[0] == '.' &&
13004 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
13005 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013006 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010013007 name_len, direntp->d_ino
13008#ifdef HAVE_DIRENT_D_TYPE
13009 , direntp->d_type
13010#endif
13011 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013012 if (!entry)
13013 break;
13014 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013015 }
13016
13017 /* Loop till we get a non-dot directory or finish iterating */
13018 }
13019
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013020 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013021 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013022 return NULL;
13023}
13024
13025#endif
13026
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013027static PyObject *
13028ScandirIterator_close(ScandirIterator *self, PyObject *args)
13029{
13030 ScandirIterator_closedir(self);
13031 Py_RETURN_NONE;
13032}
13033
13034static PyObject *
13035ScandirIterator_enter(PyObject *self, PyObject *args)
13036{
13037 Py_INCREF(self);
13038 return self;
13039}
13040
13041static PyObject *
13042ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13043{
13044 ScandirIterator_closedir(self);
13045 Py_RETURN_NONE;
13046}
13047
Victor Stinner6036e442015-03-08 01:58:04 +010013048static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013049ScandirIterator_finalize(ScandirIterator *iterator)
13050{
13051 PyObject *error_type, *error_value, *error_traceback;
13052
13053 /* Save the current exception, if any. */
13054 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13055
13056 if (!ScandirIterator_is_closed(iterator)) {
13057 ScandirIterator_closedir(iterator);
13058
13059 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13060 "unclosed scandir iterator %R", iterator)) {
13061 /* Spurious errors can appear at shutdown */
13062 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13063 PyErr_WriteUnraisable((PyObject *) iterator);
13064 }
13065 }
13066 }
13067
Victor Stinner7bfa4092016-03-23 00:43:54 +010013068 path_cleanup(&iterator->path);
13069
13070 /* Restore the saved exception. */
13071 PyErr_Restore(error_type, error_value, error_traceback);
13072}
13073
13074static void
Victor Stinner6036e442015-03-08 01:58:04 +010013075ScandirIterator_dealloc(ScandirIterator *iterator)
13076{
Victor Stinner7bfa4092016-03-23 00:43:54 +010013077 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13078 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013079
Victor Stinner6036e442015-03-08 01:58:04 +010013080 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
13081}
13082
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013083static PyMethodDef ScandirIterator_methods[] = {
13084 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13085 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13086 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13087 {NULL}
13088};
13089
Benjamin Peterson5646de42015-04-12 17:56:34 -040013090static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010013091 PyVarObject_HEAD_INIT(NULL, 0)
13092 MODNAME ".ScandirIterator", /* tp_name */
13093 sizeof(ScandirIterator), /* tp_basicsize */
13094 0, /* tp_itemsize */
13095 /* methods */
13096 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020013097 0, /* tp_vectorcall_offset */
Victor Stinner6036e442015-03-08 01:58:04 +010013098 0, /* tp_getattr */
13099 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020013100 0, /* tp_as_async */
Victor Stinner6036e442015-03-08 01:58:04 +010013101 0, /* tp_repr */
13102 0, /* tp_as_number */
13103 0, /* tp_as_sequence */
13104 0, /* tp_as_mapping */
13105 0, /* tp_hash */
13106 0, /* tp_call */
13107 0, /* tp_str */
13108 0, /* tp_getattro */
13109 0, /* tp_setattro */
13110 0, /* tp_as_buffer */
Antoine Pitrouada319b2019-05-29 22:12:38 +020013111 Py_TPFLAGS_DEFAULT, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010013112 0, /* tp_doc */
13113 0, /* tp_traverse */
13114 0, /* tp_clear */
13115 0, /* tp_richcompare */
13116 0, /* tp_weaklistoffset */
13117 PyObject_SelfIter, /* tp_iter */
13118 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013119 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010013120 0, /* tp_members */
13121 0, /* tp_getset */
13122 0, /* tp_base */
13123 0, /* tp_dict */
13124 0, /* tp_descr_get */
13125 0, /* tp_descr_set */
13126 0, /* tp_dictoffset */
13127 0, /* tp_init */
13128 0, /* tp_alloc */
13129 0, /* tp_new */
13130 0, /* tp_free */
13131 0, /* tp_is_gc */
13132 0, /* tp_bases */
13133 0, /* tp_mro */
13134 0, /* tp_cache */
13135 0, /* tp_subclasses */
13136 0, /* tp_weaklist */
13137 0, /* tp_del */
13138 0, /* tp_version_tag */
13139 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010013140};
13141
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013142/*[clinic input]
13143os.scandir
13144
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013145 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013146
13147Return an iterator of DirEntry objects for given path.
13148
BNMetricsb9427072018-11-02 15:20:19 +000013149path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013150is bytes, the names of yielded DirEntry objects will also be bytes; in
13151all other circumstances they will be str.
13152
13153If path is None, uses the path='.'.
13154[clinic start generated code]*/
13155
Victor Stinner6036e442015-03-08 01:58:04 +010013156static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013157os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013158/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013159{
13160 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013161#ifdef MS_WINDOWS
13162 wchar_t *path_strW;
13163#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013164 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013165#ifdef HAVE_FDOPENDIR
13166 int fd = -1;
13167#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013168#endif
13169
Miss Islington (bot)8763d432019-06-24 09:09:47 -070013170 if (PySys_Audit("os.scandir", "O",
13171 path->object ? path->object : Py_None) < 0) {
13172 return NULL;
13173 }
13174
Victor Stinner6036e442015-03-08 01:58:04 +010013175 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
13176 if (!iterator)
13177 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013178
13179#ifdef MS_WINDOWS
13180 iterator->handle = INVALID_HANDLE_VALUE;
13181#else
13182 iterator->dirp = NULL;
13183#endif
13184
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013185 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013186 /* Move the ownership to iterator->path */
13187 path->object = NULL;
13188 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013189
13190#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013191 iterator->first_time = 1;
13192
13193 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13194 if (!path_strW)
13195 goto error;
13196
13197 Py_BEGIN_ALLOW_THREADS
13198 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13199 Py_END_ALLOW_THREADS
13200
13201 PyMem_Free(path_strW);
13202
13203 if (iterator->handle == INVALID_HANDLE_VALUE) {
13204 path_error(&iterator->path);
13205 goto error;
13206 }
13207#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013208 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013209#ifdef HAVE_FDOPENDIR
13210 if (path->fd != -1) {
13211 /* closedir() closes the FD, so we duplicate it */
13212 fd = _Py_dup(path->fd);
13213 if (fd == -1)
13214 goto error;
13215
13216 Py_BEGIN_ALLOW_THREADS
13217 iterator->dirp = fdopendir(fd);
13218 Py_END_ALLOW_THREADS
13219 }
13220 else
13221#endif
13222 {
13223 if (iterator->path.narrow)
13224 path_str = iterator->path.narrow;
13225 else
13226 path_str = ".";
13227
13228 Py_BEGIN_ALLOW_THREADS
13229 iterator->dirp = opendir(path_str);
13230 Py_END_ALLOW_THREADS
13231 }
Victor Stinner6036e442015-03-08 01:58:04 +010013232
13233 if (!iterator->dirp) {
13234 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013235#ifdef HAVE_FDOPENDIR
13236 if (fd != -1) {
13237 Py_BEGIN_ALLOW_THREADS
13238 close(fd);
13239 Py_END_ALLOW_THREADS
13240 }
13241#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013242 goto error;
13243 }
13244#endif
13245
13246 return (PyObject *)iterator;
13247
13248error:
13249 Py_DECREF(iterator);
13250 return NULL;
13251}
13252
Ethan Furman410ef8e2016-06-04 12:06:26 -070013253/*
13254 Return the file system path representation of the object.
13255
13256 If the object is str or bytes, then allow it to pass through with
13257 an incremented refcount. If the object defines __fspath__(), then
13258 return the result of that method. All other types raise a TypeError.
13259*/
13260PyObject *
13261PyOS_FSPath(PyObject *path)
13262{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013263 /* For error message reasons, this function is manually inlined in
13264 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013265 _Py_IDENTIFIER(__fspath__);
13266 PyObject *func = NULL;
13267 PyObject *path_repr = NULL;
13268
13269 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13270 Py_INCREF(path);
13271 return path;
13272 }
13273
13274 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13275 if (NULL == func) {
13276 return PyErr_Format(PyExc_TypeError,
13277 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013278 "not %.200s",
13279 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013280 }
13281
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013282 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013283 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013284 if (NULL == path_repr) {
13285 return NULL;
13286 }
13287
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013288 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13289 PyErr_Format(PyExc_TypeError,
13290 "expected %.200s.__fspath__() to return str or bytes, "
13291 "not %.200s", Py_TYPE(path)->tp_name,
13292 Py_TYPE(path_repr)->tp_name);
13293 Py_DECREF(path_repr);
13294 return NULL;
13295 }
13296
Ethan Furman410ef8e2016-06-04 12:06:26 -070013297 return path_repr;
13298}
13299
13300/*[clinic input]
13301os.fspath
13302
13303 path: object
13304
13305Return the file system path representation of the object.
13306
Brett Cannonb4f43e92016-06-09 14:32:08 -070013307If the object is str or bytes, then allow it to pass through as-is. If the
13308object defines __fspath__(), then return the result of that method. All other
13309types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013310[clinic start generated code]*/
13311
13312static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013313os_fspath_impl(PyObject *module, PyObject *path)
13314/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013315{
13316 return PyOS_FSPath(path);
13317}
Victor Stinner6036e442015-03-08 01:58:04 +010013318
Victor Stinner9b1f4742016-09-06 16:18:52 -070013319#ifdef HAVE_GETRANDOM_SYSCALL
13320/*[clinic input]
13321os.getrandom
13322
13323 size: Py_ssize_t
13324 flags: int=0
13325
13326Obtain a series of random bytes.
13327[clinic start generated code]*/
13328
13329static PyObject *
13330os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13331/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13332{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013333 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013334 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013335
13336 if (size < 0) {
13337 errno = EINVAL;
13338 return posix_error();
13339 }
13340
Victor Stinnerec2319c2016-09-20 23:00:59 +020013341 bytes = PyBytes_FromStringAndSize(NULL, size);
13342 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013343 PyErr_NoMemory();
13344 return NULL;
13345 }
13346
13347 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013348 n = syscall(SYS_getrandom,
13349 PyBytes_AS_STRING(bytes),
13350 PyBytes_GET_SIZE(bytes),
13351 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013352 if (n < 0 && errno == EINTR) {
13353 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013354 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013355 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013356
13357 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013358 continue;
13359 }
13360 break;
13361 }
13362
13363 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013364 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013365 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013366 }
13367
Victor Stinnerec2319c2016-09-20 23:00:59 +020013368 if (n != size) {
13369 _PyBytes_Resize(&bytes, n);
13370 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013371
13372 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013373
13374error:
13375 Py_DECREF(bytes);
13376 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013377}
13378#endif /* HAVE_GETRANDOM_SYSCALL */
13379
Steve Dower2438cdf2019-03-29 16:37:16 -070013380#ifdef MS_WINDOWS
13381/* bpo-36085: Helper functions for managing DLL search directories
13382 * on win32
13383 */
13384
13385typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13386typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13387
13388/*[clinic input]
13389os._add_dll_directory
13390
13391 path: path_t
13392
13393Add a path to the DLL search path.
13394
13395This search path is used when resolving dependencies for imported
13396extension modules (the module itself is resolved through sys.path),
13397and also by ctypes.
13398
13399Returns an opaque value that may be passed to os.remove_dll_directory
13400to remove this directory from the search path.
13401[clinic start generated code]*/
13402
13403static PyObject *
13404os__add_dll_directory_impl(PyObject *module, path_t *path)
13405/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13406{
13407 HMODULE hKernel32;
13408 PAddDllDirectory AddDllDirectory;
13409 DLL_DIRECTORY_COOKIE cookie = 0;
13410 DWORD err = 0;
13411
13412 /* For Windows 7, we have to load this. As this will be a fairly
13413 infrequent operation, just do it each time. Kernel32 is always
13414 loaded. */
13415 Py_BEGIN_ALLOW_THREADS
13416 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13417 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13418 hKernel32, "AddDllDirectory")) ||
13419 !(cookie = (*AddDllDirectory)(path->wide))) {
13420 err = GetLastError();
13421 }
13422 Py_END_ALLOW_THREADS
13423
13424 if (err) {
13425 return win32_error_object_err("add_dll_directory",
13426 path->object, err);
13427 }
13428
13429 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13430}
13431
13432/*[clinic input]
13433os._remove_dll_directory
13434
13435 cookie: object
13436
13437Removes a path from the DLL search path.
13438
13439The parameter is an opaque value that was returned from
13440os.add_dll_directory. You can only remove directories that you added
13441yourself.
13442[clinic start generated code]*/
13443
13444static PyObject *
13445os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13446/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13447{
13448 HMODULE hKernel32;
13449 PRemoveDllDirectory RemoveDllDirectory;
13450 DLL_DIRECTORY_COOKIE cookieValue;
13451 DWORD err = 0;
13452
13453 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13454 PyErr_SetString(PyExc_TypeError,
13455 "Provided cookie was not returned from os.add_dll_directory");
13456 return NULL;
13457 }
13458
13459 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13460 cookie, "DLL directory cookie");
13461
13462 /* For Windows 7, we have to load this. As this will be a fairly
13463 infrequent operation, just do it each time. Kernel32 is always
13464 loaded. */
13465 Py_BEGIN_ALLOW_THREADS
13466 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13467 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13468 hKernel32, "RemoveDllDirectory")) ||
13469 !(*RemoveDllDirectory)(cookieValue)) {
13470 err = GetLastError();
13471 }
13472 Py_END_ALLOW_THREADS
13473
13474 if (err) {
13475 return win32_error_object_err("remove_dll_directory",
13476 NULL, err);
13477 }
13478
13479 if (PyCapsule_SetName(cookie, NULL)) {
13480 return NULL;
13481 }
13482
13483 Py_RETURN_NONE;
13484}
13485
13486#endif
Larry Hastings31826802013-10-19 00:09:25 -070013487
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013488static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013489
13490 OS_STAT_METHODDEF
13491 OS_ACCESS_METHODDEF
13492 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013493 OS_CHDIR_METHODDEF
13494 OS_CHFLAGS_METHODDEF
13495 OS_CHMOD_METHODDEF
13496 OS_FCHMOD_METHODDEF
13497 OS_LCHMOD_METHODDEF
13498 OS_CHOWN_METHODDEF
13499 OS_FCHOWN_METHODDEF
13500 OS_LCHOWN_METHODDEF
13501 OS_LCHFLAGS_METHODDEF
13502 OS_CHROOT_METHODDEF
13503 OS_CTERMID_METHODDEF
13504 OS_GETCWD_METHODDEF
13505 OS_GETCWDB_METHODDEF
13506 OS_LINK_METHODDEF
13507 OS_LISTDIR_METHODDEF
13508 OS_LSTAT_METHODDEF
13509 OS_MKDIR_METHODDEF
13510 OS_NICE_METHODDEF
13511 OS_GETPRIORITY_METHODDEF
13512 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013513 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013514 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013515 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010013516 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013517 OS_RENAME_METHODDEF
13518 OS_REPLACE_METHODDEF
13519 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013520 OS_SYMLINK_METHODDEF
13521 OS_SYSTEM_METHODDEF
13522 OS_UMASK_METHODDEF
13523 OS_UNAME_METHODDEF
13524 OS_UNLINK_METHODDEF
13525 OS_REMOVE_METHODDEF
13526 OS_UTIME_METHODDEF
13527 OS_TIMES_METHODDEF
13528 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013529 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013530 OS_EXECV_METHODDEF
13531 OS_EXECVE_METHODDEF
13532 OS_SPAWNV_METHODDEF
13533 OS_SPAWNVE_METHODDEF
13534 OS_FORK1_METHODDEF
13535 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013536 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013537 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13538 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13539 OS_SCHED_GETPARAM_METHODDEF
13540 OS_SCHED_GETSCHEDULER_METHODDEF
13541 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13542 OS_SCHED_SETPARAM_METHODDEF
13543 OS_SCHED_SETSCHEDULER_METHODDEF
13544 OS_SCHED_YIELD_METHODDEF
13545 OS_SCHED_SETAFFINITY_METHODDEF
13546 OS_SCHED_GETAFFINITY_METHODDEF
13547 OS_OPENPTY_METHODDEF
13548 OS_FORKPTY_METHODDEF
13549 OS_GETEGID_METHODDEF
13550 OS_GETEUID_METHODDEF
13551 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013552#ifdef HAVE_GETGROUPLIST
13553 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13554#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013555 OS_GETGROUPS_METHODDEF
13556 OS_GETPID_METHODDEF
13557 OS_GETPGRP_METHODDEF
13558 OS_GETPPID_METHODDEF
13559 OS_GETUID_METHODDEF
13560 OS_GETLOGIN_METHODDEF
13561 OS_KILL_METHODDEF
13562 OS_KILLPG_METHODDEF
13563 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013564#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013565 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013566#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013567 OS_SETUID_METHODDEF
13568 OS_SETEUID_METHODDEF
13569 OS_SETREUID_METHODDEF
13570 OS_SETGID_METHODDEF
13571 OS_SETEGID_METHODDEF
13572 OS_SETREGID_METHODDEF
13573 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013574#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013575 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013576#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013577 OS_GETPGID_METHODDEF
13578 OS_SETPGRP_METHODDEF
13579 OS_WAIT_METHODDEF
13580 OS_WAIT3_METHODDEF
13581 OS_WAIT4_METHODDEF
13582 OS_WAITID_METHODDEF
13583 OS_WAITPID_METHODDEF
13584 OS_GETSID_METHODDEF
13585 OS_SETSID_METHODDEF
13586 OS_SETPGID_METHODDEF
13587 OS_TCGETPGRP_METHODDEF
13588 OS_TCSETPGRP_METHODDEF
13589 OS_OPEN_METHODDEF
13590 OS_CLOSE_METHODDEF
13591 OS_CLOSERANGE_METHODDEF
13592 OS_DEVICE_ENCODING_METHODDEF
13593 OS_DUP_METHODDEF
13594 OS_DUP2_METHODDEF
13595 OS_LOCKF_METHODDEF
13596 OS_LSEEK_METHODDEF
13597 OS_READ_METHODDEF
13598 OS_READV_METHODDEF
13599 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013600 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013601 OS_WRITE_METHODDEF
13602 OS_WRITEV_METHODDEF
13603 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013604 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013605#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013606 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013607 posix_sendfile__doc__},
13608#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013609 OS_FSTAT_METHODDEF
13610 OS_ISATTY_METHODDEF
13611 OS_PIPE_METHODDEF
13612 OS_PIPE2_METHODDEF
13613 OS_MKFIFO_METHODDEF
13614 OS_MKNOD_METHODDEF
13615 OS_MAJOR_METHODDEF
13616 OS_MINOR_METHODDEF
13617 OS_MAKEDEV_METHODDEF
13618 OS_FTRUNCATE_METHODDEF
13619 OS_TRUNCATE_METHODDEF
13620 OS_POSIX_FALLOCATE_METHODDEF
13621 OS_POSIX_FADVISE_METHODDEF
13622 OS_PUTENV_METHODDEF
13623 OS_UNSETENV_METHODDEF
13624 OS_STRERROR_METHODDEF
13625 OS_FCHDIR_METHODDEF
13626 OS_FSYNC_METHODDEF
13627 OS_SYNC_METHODDEF
13628 OS_FDATASYNC_METHODDEF
13629 OS_WCOREDUMP_METHODDEF
13630 OS_WIFCONTINUED_METHODDEF
13631 OS_WIFSTOPPED_METHODDEF
13632 OS_WIFSIGNALED_METHODDEF
13633 OS_WIFEXITED_METHODDEF
13634 OS_WEXITSTATUS_METHODDEF
13635 OS_WTERMSIG_METHODDEF
13636 OS_WSTOPSIG_METHODDEF
13637 OS_FSTATVFS_METHODDEF
13638 OS_STATVFS_METHODDEF
13639 OS_CONFSTR_METHODDEF
13640 OS_SYSCONF_METHODDEF
13641 OS_FPATHCONF_METHODDEF
13642 OS_PATHCONF_METHODDEF
13643 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013644 OS__GETFULLPATHNAME_METHODDEF
13645 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013646 OS__GETDISKUSAGE_METHODDEF
13647 OS__GETFINALPATHNAME_METHODDEF
13648 OS__GETVOLUMEPATHNAME_METHODDEF
13649 OS_GETLOADAVG_METHODDEF
13650 OS_URANDOM_METHODDEF
13651 OS_SETRESUID_METHODDEF
13652 OS_SETRESGID_METHODDEF
13653 OS_GETRESUID_METHODDEF
13654 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013655
Larry Hastings2f936352014-08-05 14:04:04 +100013656 OS_GETXATTR_METHODDEF
13657 OS_SETXATTR_METHODDEF
13658 OS_REMOVEXATTR_METHODDEF
13659 OS_LISTXATTR_METHODDEF
13660
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013661#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13662 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13663#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013664 OS_CPU_COUNT_METHODDEF
13665 OS_GET_INHERITABLE_METHODDEF
13666 OS_SET_INHERITABLE_METHODDEF
13667 OS_GET_HANDLE_INHERITABLE_METHODDEF
13668 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013669#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013670 OS_GET_BLOCKING_METHODDEF
13671 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013672#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013673 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013674 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013675 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060013676 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070013677#ifdef MS_WINDOWS
13678 OS__ADD_DLL_DIRECTORY_METHODDEF
13679 OS__REMOVE_DLL_DIRECTORY_METHODDEF
13680#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013681 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013682};
13683
Barry Warsaw4a342091996-12-19 23:50:02 +000013684static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013685all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013686{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013687#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013688 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013689#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013690#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013691 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013692#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013693#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013694 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013695#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013696#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013697 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013698#endif
Fred Drakec9680921999-12-13 16:37:25 +000013699#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013700 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013701#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013702#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013703 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013704#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013705#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013706 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013707#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013708#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013709 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013710#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013711#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013712 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013713#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013714#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013715 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013716#endif
13717#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013718 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013719#endif
13720#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013721 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013722#endif
13723#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013724 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013725#endif
13726#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013727 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013728#endif
13729#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013730 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013731#endif
13732#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013733 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013734#endif
13735#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013736 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013737#endif
13738#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013739 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013740#endif
13741#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013742 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013743#endif
13744#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013745 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013746#endif
13747#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013748 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013749#endif
13750#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013751 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013752#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013753#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013754 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013755#endif
13756#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013757 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013758#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013759#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013760 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013761#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013762#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013763 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013764#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013765#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013766#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013767 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013768#endif
13769#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013770 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013771#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013772#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013773#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013774 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013775#endif
13776#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013777 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013778#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013779#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013780 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013781#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013782#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013783 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013784#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013785#ifdef O_TMPFILE
13786 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13787#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013788#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013789 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013790#endif
13791#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013792 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013793#endif
13794#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013795 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013796#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013797#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013798 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013799#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013800#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013801 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013802#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013803
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013804
Jesus Cea94363612012-06-22 18:32:07 +020013805#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013806 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013807#endif
13808#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013809 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013810#endif
13811
Tim Peters5aa91602002-01-30 05:46:57 +000013812/* MS Windows */
13813#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013814 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013815 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013816#endif
13817#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013818 /* Optimize for short life (keep in memory). */
13819 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013820 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013821#endif
13822#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013823 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013824 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013825#endif
13826#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013827 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013828 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013829#endif
13830#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013831 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013832 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013833#endif
13834
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013835/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013836#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013837 /* Send a SIGIO signal whenever input or output
13838 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013839 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013840#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013841#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013842 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013843 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013844#endif
13845#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013846 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013847 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013848#endif
13849#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013850 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013851 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013852#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013853#ifdef O_NOLINKS
13854 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013855 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013856#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013857#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013858 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013859 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013860#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013861
Victor Stinner8c62be82010-05-06 00:08:46 +000013862 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013863#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013864 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013865#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013866#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013867 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013868#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013869#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013870 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013871#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013872#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013873 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013874#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013875#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013876 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013877#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013878#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013879 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013880#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013881#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013882 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013883#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013884#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013885 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013886#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013887#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013888 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013889#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013890#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013891 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013892#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013893#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013894 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013895#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013896#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013897 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013898#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013899#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013900 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013901#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013902#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013903 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013904#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013905#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013906 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013907#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013908#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013909 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013910#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013911#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013912 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013913#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013914
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013915 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013916#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013917 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013918#endif /* ST_RDONLY */
13919#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013920 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013921#endif /* ST_NOSUID */
13922
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013923 /* GNU extensions */
13924#ifdef ST_NODEV
13925 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13926#endif /* ST_NODEV */
13927#ifdef ST_NOEXEC
13928 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13929#endif /* ST_NOEXEC */
13930#ifdef ST_SYNCHRONOUS
13931 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13932#endif /* ST_SYNCHRONOUS */
13933#ifdef ST_MANDLOCK
13934 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13935#endif /* ST_MANDLOCK */
13936#ifdef ST_WRITE
13937 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13938#endif /* ST_WRITE */
13939#ifdef ST_APPEND
13940 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13941#endif /* ST_APPEND */
13942#ifdef ST_NOATIME
13943 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13944#endif /* ST_NOATIME */
13945#ifdef ST_NODIRATIME
13946 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13947#endif /* ST_NODIRATIME */
13948#ifdef ST_RELATIME
13949 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13950#endif /* ST_RELATIME */
13951
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013952 /* FreeBSD sendfile() constants */
13953#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013954 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013955#endif
13956#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013957 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013958#endif
13959#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013960 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013961#endif
13962
Ross Lagerwall7807c352011-03-17 20:20:30 +020013963 /* constants for posix_fadvise */
13964#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013965 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013966#endif
13967#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013968 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013969#endif
13970#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013971 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013972#endif
13973#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013974 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013975#endif
13976#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013977 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013978#endif
13979#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013980 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013981#endif
13982
13983 /* constants for waitid */
13984#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013985 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13986 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13987 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013988#endif
13989#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013990 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013991#endif
13992#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013993 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013994#endif
13995#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013996 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013997#endif
13998#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013999 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014000#endif
14001#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014002 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014003#endif
14004#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014005 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014006#endif
14007#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014008 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014009#endif
14010
14011 /* constants for lockf */
14012#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014013 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014014#endif
14015#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014016 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014017#endif
14018#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014019 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014020#endif
14021#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014022 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014023#endif
14024
Pablo Galindo4defba32018-01-27 16:16:37 +000014025#ifdef RWF_DSYNC
14026 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14027#endif
14028#ifdef RWF_HIPRI
14029 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14030#endif
14031#ifdef RWF_SYNC
14032 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14033#endif
14034#ifdef RWF_NOWAIT
14035 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14036#endif
14037
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014038/* constants for posix_spawn */
14039#ifdef HAVE_POSIX_SPAWN
14040 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14041 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14042 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14043#endif
14044
pxinwrf2d7ac72019-05-21 18:46:37 +080014045#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014046 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14047 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014048 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014049#endif
14050#ifdef HAVE_SPAWNV
14051 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014052 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014053#endif
14054
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014055#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014056#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014057 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014058#endif
14059#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014060 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014061#endif
14062#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014063 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014064#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014065#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014066 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014067#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014068#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014069 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014070#endif
14071#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014072 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014073#endif
14074#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014075 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014076#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014077#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014078 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014079#endif
14080#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014081 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014082#endif
14083#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014084 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014085#endif
14086#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014087 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014088#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014089#endif
14090
Benjamin Peterson9428d532011-09-14 11:45:52 -040014091#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014092 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
14093 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
14094 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040014095#endif
14096
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014097#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014098 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014099#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014100#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014101 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014102#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014103#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014104 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014105#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014106#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014107 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014108#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014109#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014110 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014111#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014112#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014113 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014114#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014115#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014116 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014117#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010014118#if HAVE_DECL_RTLD_MEMBER
14119 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
14120#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020014121
Victor Stinner9b1f4742016-09-06 16:18:52 -070014122#ifdef HAVE_GETRANDOM_SYSCALL
14123 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
14124 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
14125#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014126#ifdef HAVE_MEMFD_CREATE
14127 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
14128 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
14129#ifdef MFD_HUGETLB
14130 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014131#endif
14132#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014133 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014134#endif
14135#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014136 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014137#endif
14138#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014139 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014140#endif
14141#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014142 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014143#endif
14144#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014145 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014146#endif
14147#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014148 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014149#endif
14150#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014151 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014152#endif
14153#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014154 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014155#endif
14156#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014157 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014158#endif
14159#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014160 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014161#endif
14162#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014163 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014164#endif
14165#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014166 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014167#endif
14168#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014169 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014170#endif
14171#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014172 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
14173#endif
14174#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070014175
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014176#if defined(__APPLE__)
14177 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
14178#endif
14179
Steve Dower2438cdf2019-03-29 16:37:16 -070014180#ifdef MS_WINDOWS
14181 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
14182 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
14183 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
14184 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
14185 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
14186#endif
14187
Victor Stinner8c62be82010-05-06 00:08:46 +000014188 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000014189}
14190
14191
Martin v. Löwis1a214512008-06-11 05:26:20 +000014192static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000014193 PyModuleDef_HEAD_INIT,
14194 MODNAME,
14195 posix__doc__,
14196 -1,
14197 posix_methods,
14198 NULL,
14199 NULL,
14200 NULL,
14201 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000014202};
14203
14204
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014205static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014206
14207#ifdef HAVE_FACCESSAT
14208 "HAVE_FACCESSAT",
14209#endif
14210
14211#ifdef HAVE_FCHDIR
14212 "HAVE_FCHDIR",
14213#endif
14214
14215#ifdef HAVE_FCHMOD
14216 "HAVE_FCHMOD",
14217#endif
14218
14219#ifdef HAVE_FCHMODAT
14220 "HAVE_FCHMODAT",
14221#endif
14222
14223#ifdef HAVE_FCHOWN
14224 "HAVE_FCHOWN",
14225#endif
14226
Larry Hastings00964ed2013-08-12 13:49:30 -040014227#ifdef HAVE_FCHOWNAT
14228 "HAVE_FCHOWNAT",
14229#endif
14230
Larry Hastings9cf065c2012-06-22 16:30:09 -070014231#ifdef HAVE_FEXECVE
14232 "HAVE_FEXECVE",
14233#endif
14234
14235#ifdef HAVE_FDOPENDIR
14236 "HAVE_FDOPENDIR",
14237#endif
14238
Georg Brandl306336b2012-06-24 12:55:33 +020014239#ifdef HAVE_FPATHCONF
14240 "HAVE_FPATHCONF",
14241#endif
14242
Larry Hastings9cf065c2012-06-22 16:30:09 -070014243#ifdef HAVE_FSTATAT
14244 "HAVE_FSTATAT",
14245#endif
14246
14247#ifdef HAVE_FSTATVFS
14248 "HAVE_FSTATVFS",
14249#endif
14250
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014251#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014252 "HAVE_FTRUNCATE",
14253#endif
14254
Larry Hastings9cf065c2012-06-22 16:30:09 -070014255#ifdef HAVE_FUTIMENS
14256 "HAVE_FUTIMENS",
14257#endif
14258
14259#ifdef HAVE_FUTIMES
14260 "HAVE_FUTIMES",
14261#endif
14262
14263#ifdef HAVE_FUTIMESAT
14264 "HAVE_FUTIMESAT",
14265#endif
14266
14267#ifdef HAVE_LINKAT
14268 "HAVE_LINKAT",
14269#endif
14270
14271#ifdef HAVE_LCHFLAGS
14272 "HAVE_LCHFLAGS",
14273#endif
14274
14275#ifdef HAVE_LCHMOD
14276 "HAVE_LCHMOD",
14277#endif
14278
14279#ifdef HAVE_LCHOWN
14280 "HAVE_LCHOWN",
14281#endif
14282
14283#ifdef HAVE_LSTAT
14284 "HAVE_LSTAT",
14285#endif
14286
14287#ifdef HAVE_LUTIMES
14288 "HAVE_LUTIMES",
14289#endif
14290
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014291#ifdef HAVE_MEMFD_CREATE
14292 "HAVE_MEMFD_CREATE",
14293#endif
14294
Larry Hastings9cf065c2012-06-22 16:30:09 -070014295#ifdef HAVE_MKDIRAT
14296 "HAVE_MKDIRAT",
14297#endif
14298
14299#ifdef HAVE_MKFIFOAT
14300 "HAVE_MKFIFOAT",
14301#endif
14302
14303#ifdef HAVE_MKNODAT
14304 "HAVE_MKNODAT",
14305#endif
14306
14307#ifdef HAVE_OPENAT
14308 "HAVE_OPENAT",
14309#endif
14310
14311#ifdef HAVE_READLINKAT
14312 "HAVE_READLINKAT",
14313#endif
14314
14315#ifdef HAVE_RENAMEAT
14316 "HAVE_RENAMEAT",
14317#endif
14318
14319#ifdef HAVE_SYMLINKAT
14320 "HAVE_SYMLINKAT",
14321#endif
14322
14323#ifdef HAVE_UNLINKAT
14324 "HAVE_UNLINKAT",
14325#endif
14326
14327#ifdef HAVE_UTIMENSAT
14328 "HAVE_UTIMENSAT",
14329#endif
14330
14331#ifdef MS_WINDOWS
14332 "MS_WINDOWS",
14333#endif
14334
14335 NULL
14336};
14337
14338
Mark Hammondfe51c6d2002-08-02 02:27:13 +000014339PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000014340INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014341{
Victor Stinner8c62be82010-05-06 00:08:46 +000014342 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014343 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014344 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000014345
Victor Stinner8c62be82010-05-06 00:08:46 +000014346 m = PyModule_Create(&posixmodule);
14347 if (m == NULL)
14348 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000014349
Victor Stinner8c62be82010-05-06 00:08:46 +000014350 /* Initialize environ dictionary */
14351 v = convertenviron();
14352 Py_XINCREF(v);
14353 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
14354 return NULL;
14355 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014356
Victor Stinner8c62be82010-05-06 00:08:46 +000014357 if (all_ins(m))
14358 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000014359
Victor Stinner8c62be82010-05-06 00:08:46 +000014360 if (setup_confname_tables(m))
14361 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000014362
Victor Stinner8c62be82010-05-06 00:08:46 +000014363 Py_INCREF(PyExc_OSError);
14364 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014365
Guido van Rossumb3d39562000-01-31 18:41:26 +000014366#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000014367 if (posix_putenv_garbage == NULL)
14368 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000014369#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000014370
Victor Stinner8c62be82010-05-06 00:08:46 +000014371 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020014372#if defined(HAVE_WAITID) && !defined(__APPLE__)
14373 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014374 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
14375 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014376 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014377 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014378#endif
14379
Christian Heimes25827622013-10-12 01:27:08 +020014380 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000014381 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14382 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14383 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014384 StatResultType = PyStructSequence_NewType(&stat_result_desc);
14385 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014386 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014387 }
14388 structseq_new = StatResultType->tp_new;
14389 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014390
Christian Heimes25827622013-10-12 01:27:08 +020014391 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014392 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
14393 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014394 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014395 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014396#ifdef NEED_TICKS_PER_SECOND
14397# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000014398 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014399# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000014400 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014401# else
Victor Stinner8c62be82010-05-06 00:08:46 +000014402 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014403# endif
14404#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014405
William Orr81574b82018-10-01 22:19:56 -070014406#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014407 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014408 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
14409 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014410 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014411 }
14412 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014413#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014414
14415 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014416 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
14417 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014418 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014419 }
Victor Stinner6036e442015-03-08 01:58:04 +010014420
14421 /* initialize scandir types */
14422 if (PyType_Ready(&ScandirIteratorType) < 0)
14423 return NULL;
14424 if (PyType_Ready(&DirEntryType) < 0)
14425 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014426 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014427#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014428 Py_INCREF((PyObject*) WaitidResultType);
14429 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020014430#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014431 Py_INCREF((PyObject*) StatResultType);
14432 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
14433 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000014434 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014435 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014436
14437#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014438 Py_INCREF(SchedParamType);
14439 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014440#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014441
Larry Hastings605a62d2012-06-24 04:33:36 -070014442 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014443 TimesResultType = PyStructSequence_NewType(&times_result_desc);
14444 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014445 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014446 }
14447 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014448
14449 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014450 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
14451 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014452 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014453 }
14454 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014455
Thomas Wouters477c8d52006-05-27 19:21:47 +000014456#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014457 /*
14458 * Step 2 of weak-linking support on Mac OS X.
14459 *
14460 * The code below removes functions that are not available on the
14461 * currently active platform.
14462 *
14463 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014464 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014465 * OSX 10.4.
14466 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014467#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014468 if (fstatvfs == NULL) {
14469 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14470 return NULL;
14471 }
14472 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014473#endif /* HAVE_FSTATVFS */
14474
14475#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014476 if (statvfs == NULL) {
14477 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14478 return NULL;
14479 }
14480 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014481#endif /* HAVE_STATVFS */
14482
14483# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014484 if (lchown == NULL) {
14485 if (PyObject_DelAttrString(m, "lchown") == -1) {
14486 return NULL;
14487 }
14488 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014489#endif /* HAVE_LCHOWN */
14490
14491
14492#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014493
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014494 Py_INCREF(TerminalSizeType);
14495 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014496
Larry Hastings6fe20b32012-04-19 15:07:49 -070014497 billion = PyLong_FromLong(1000000000);
14498 if (!billion)
14499 return NULL;
14500
Larry Hastings9cf065c2012-06-22 16:30:09 -070014501 /* suppress "function not used" warnings */
14502 {
14503 int ignored;
14504 fd_specified("", -1);
14505 follow_symlinks_specified("", 1);
14506 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14507 dir_fd_converter(Py_None, &ignored);
14508 dir_fd_unavailable(Py_None, &ignored);
14509 }
14510
14511 /*
14512 * provide list of locally available functions
14513 * so os.py can populate support_* lists
14514 */
14515 list = PyList_New(0);
14516 if (!list)
14517 return NULL;
14518 for (trace = have_functions; *trace; trace++) {
14519 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14520 if (!unicode)
14521 return NULL;
14522 if (PyList_Append(list, unicode))
14523 return NULL;
14524 Py_DECREF(unicode);
14525 }
14526 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014527
14528 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014529 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014530
14531 initialized = 1;
14532
Victor Stinner8c62be82010-05-06 00:08:46 +000014533 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014534}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014535
14536#ifdef __cplusplus
14537}
14538#endif