blob: 7a471801db39439fffddc142db33ed985e2843ec [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{
3761#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3762 return _listdir_windows_no_opendir(path, NULL);
3763#else
3764 return _posix_listdir(path, NULL);
3765#endif
3766}
3767
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003768#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003769/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003770/*[clinic input]
3771os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003772
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003773 path: path_t
3774 /
3775
3776[clinic start generated code]*/
3777
3778static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003779os__getfullpathname_impl(PyObject *module, path_t *path)
3780/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003781{
Steve Dowercc16be82016-09-08 10:35:16 -07003782 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3783 wchar_t *wtemp;
3784 DWORD result;
3785 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003786
Steve Dowercc16be82016-09-08 10:35:16 -07003787 result = GetFullPathNameW(path->wide,
3788 Py_ARRAY_LENGTH(woutbuf),
3789 woutbuf, &wtemp);
3790 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3791 woutbufp = PyMem_New(wchar_t, result);
3792 if (!woutbufp)
3793 return PyErr_NoMemory();
3794 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003795 }
Steve Dowercc16be82016-09-08 10:35:16 -07003796 if (result) {
3797 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3798 if (path->narrow)
3799 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3800 } else
3801 v = win32_error_object("GetFullPathNameW", path->object);
3802 if (woutbufp != woutbuf)
3803 PyMem_Free(woutbufp);
3804 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003805}
Brian Curtind40e6f72010-07-08 21:39:08 +00003806
Brian Curtind25aef52011-06-13 15:16:04 -05003807
Larry Hastings2f936352014-08-05 14:04:04 +10003808/*[clinic input]
3809os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003810
Steve Dower23ad6d02018-02-22 10:39:10 -08003811 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003812 /
3813
3814A helper function for samepath on windows.
3815[clinic start generated code]*/
3816
Larry Hastings2f936352014-08-05 14:04:04 +10003817static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003818os__getfinalpathname_impl(PyObject *module, path_t *path)
3819/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003820{
3821 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003822 wchar_t buf[MAXPATHLEN], *target_path = buf;
3823 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003824 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003825 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003826
Steve Dower23ad6d02018-02-22 10:39:10 -08003827 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003828 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003829 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003830 0, /* desired access */
3831 0, /* share mode */
3832 NULL, /* security attributes */
3833 OPEN_EXISTING,
3834 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3835 FILE_FLAG_BACKUP_SEMANTICS,
3836 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003837 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003838
Steve Dower23ad6d02018-02-22 10:39:10 -08003839 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003840 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003841 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003842
3843 /* We have a good handle to the target, use it to determine the
3844 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003845 while (1) {
3846 Py_BEGIN_ALLOW_THREADS
3847 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3848 buf_size, VOLUME_NAME_DOS);
3849 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003850
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003851 if (!result_length) {
3852 result = win32_error_object("GetFinalPathNameByHandleW",
3853 path->object);
3854 goto cleanup;
3855 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003856
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003857 if (result_length < buf_size) {
3858 break;
3859 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003860
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003861 wchar_t *tmp;
3862 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3863 result_length * sizeof(*tmp));
3864 if (!tmp) {
3865 result = PyErr_NoMemory();
3866 goto cleanup;
3867 }
3868
3869 buf_size = result_length;
3870 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003871 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003872
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003873 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003874 if (path->narrow)
3875 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003876
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003877cleanup:
3878 if (target_path != buf) {
3879 PyMem_Free(target_path);
3880 }
3881 CloseHandle(hFile);
3882 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003883}
Brian Curtin62857742010-09-06 17:07:27 +00003884
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003885/*[clinic input]
3886os._isdir
3887
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003888 path as arg: object
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003889 /
3890
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003891Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003892[clinic start generated code]*/
3893
Brian Curtin9c669cc2011-06-08 18:17:18 -05003894static PyObject *
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003895os__isdir(PyObject *module, PyObject *arg)
3896/*[clinic end generated code: output=404f334d85d4bf25 input=36cb6785874d479e]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003897{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003898 DWORD attributes;
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003899 path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0);
3900
3901 if (!path_converter(arg, &path)) {
3902 if (PyErr_ExceptionMatches(PyExc_ValueError)) {
3903 PyErr_Clear();
3904 Py_RETURN_FALSE;
3905 }
3906 return NULL;
3907 }
Brian Curtin9c669cc2011-06-08 18:17:18 -05003908
Steve Dowerb22a6772016-07-17 20:49:38 -07003909 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003910 attributes = GetFileAttributesW(path.wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003911 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003912
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003913 path_cleanup(&path);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003914 if (attributes == INVALID_FILE_ATTRIBUTES)
3915 Py_RETURN_FALSE;
3916
Brian Curtin9c669cc2011-06-08 18:17:18 -05003917 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3918 Py_RETURN_TRUE;
3919 else
3920 Py_RETURN_FALSE;
3921}
Tim Golden6b528062013-08-01 12:44:00 +01003922
Tim Golden6b528062013-08-01 12:44:00 +01003923
Larry Hastings2f936352014-08-05 14:04:04 +10003924/*[clinic input]
3925os._getvolumepathname
3926
Steve Dower23ad6d02018-02-22 10:39:10 -08003927 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003928
3929A helper function for ismount on Win32.
3930[clinic start generated code]*/
3931
Larry Hastings2f936352014-08-05 14:04:04 +10003932static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003933os__getvolumepathname_impl(PyObject *module, path_t *path)
3934/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003935{
3936 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003937 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003938 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003939 BOOL ret;
3940
Tim Golden6b528062013-08-01 12:44:00 +01003941 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003942 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003943
Victor Stinner850a18e2017-10-24 16:53:32 -07003944 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003945 PyErr_SetString(PyExc_OverflowError, "path too long");
3946 return NULL;
3947 }
3948
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003949 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003950 if (mountpath == NULL)
3951 return PyErr_NoMemory();
3952
3953 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003954 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003955 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003956 Py_END_ALLOW_THREADS
3957
3958 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003959 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003960 goto exit;
3961 }
3962 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003963 if (path->narrow)
3964 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003965
3966exit:
3967 PyMem_Free(mountpath);
3968 return result;
3969}
Tim Golden6b528062013-08-01 12:44:00 +01003970
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003971#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003972
Larry Hastings2f936352014-08-05 14:04:04 +10003973
3974/*[clinic input]
3975os.mkdir
3976
3977 path : path_t
3978
3979 mode: int = 0o777
3980
3981 *
3982
3983 dir_fd : dir_fd(requires='mkdirat') = None
3984
3985# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3986
3987Create a directory.
3988
3989If dir_fd is not None, it should be a file descriptor open to a directory,
3990 and path should be relative; path will then be relative to that directory.
3991dir_fd may not be implemented on your platform.
3992 If it is unavailable, using it will raise a NotImplementedError.
3993
3994The mode argument is ignored on Windows.
3995[clinic start generated code]*/
3996
Larry Hastings2f936352014-08-05 14:04:04 +10003997static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003998os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3999/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004000{
4001 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004002
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004003#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004004 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004005 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004006 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004007
Larry Hastings2f936352014-08-05 14:04:04 +10004008 if (!result)
4009 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004010#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004011 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004012#if HAVE_MKDIRAT
4013 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004014 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004015 else
4016#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004017#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004018 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004019#else
Larry Hastings2f936352014-08-05 14:04:04 +10004020 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004021#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004022 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004023 if (result < 0)
4024 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004025#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004026 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004027}
4028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004029
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004030/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4031#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004032#include <sys/resource.h>
4033#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004034
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004035
4036#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004037/*[clinic input]
4038os.nice
4039
4040 increment: int
4041 /
4042
4043Add increment to the priority of process and return the new priority.
4044[clinic start generated code]*/
4045
Larry Hastings2f936352014-08-05 14:04:04 +10004046static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004047os_nice_impl(PyObject *module, int increment)
4048/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004049{
4050 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004051
Victor Stinner8c62be82010-05-06 00:08:46 +00004052 /* There are two flavours of 'nice': one that returns the new
4053 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004054 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004055 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004056
Victor Stinner8c62be82010-05-06 00:08:46 +00004057 If we are of the nice family that returns the new priority, we
4058 need to clear errno before the call, and check if errno is filled
4059 before calling posix_error() on a returnvalue of -1, because the
4060 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004061
Victor Stinner8c62be82010-05-06 00:08:46 +00004062 errno = 0;
4063 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004064#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004065 if (value == 0)
4066 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004067#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 if (value == -1 && errno != 0)
4069 /* either nice() or getpriority() returned an error */
4070 return posix_error();
4071 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004072}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004073#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004074
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004075
4076#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004077/*[clinic input]
4078os.getpriority
4079
4080 which: int
4081 who: int
4082
4083Return program scheduling priority.
4084[clinic start generated code]*/
4085
Larry Hastings2f936352014-08-05 14:04:04 +10004086static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004087os_getpriority_impl(PyObject *module, int which, int who)
4088/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004089{
4090 int retval;
4091
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004092 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004093 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004094 if (errno != 0)
4095 return posix_error();
4096 return PyLong_FromLong((long)retval);
4097}
4098#endif /* HAVE_GETPRIORITY */
4099
4100
4101#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004102/*[clinic input]
4103os.setpriority
4104
4105 which: int
4106 who: int
4107 priority: int
4108
4109Set program scheduling priority.
4110[clinic start generated code]*/
4111
Larry Hastings2f936352014-08-05 14:04:04 +10004112static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004113os_setpriority_impl(PyObject *module, int which, int who, int priority)
4114/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004115{
4116 int retval;
4117
4118 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004119 if (retval == -1)
4120 return posix_error();
4121 Py_RETURN_NONE;
4122}
4123#endif /* HAVE_SETPRIORITY */
4124
4125
Barry Warsaw53699e91996-12-10 23:23:01 +00004126static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004127internal_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 +00004128{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004129 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004130 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004131
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004132#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004133 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004134 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004135#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004136 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004137#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004138
Larry Hastings9cf065c2012-06-22 16:30:09 -07004139 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4140 (dst_dir_fd != DEFAULT_DIR_FD);
4141#ifndef HAVE_RENAMEAT
4142 if (dir_fd_specified) {
4143 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004144 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004145 }
4146#endif
4147
Larry Hastings9cf065c2012-06-22 16:30:09 -07004148#ifdef MS_WINDOWS
4149 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004150 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004151 Py_END_ALLOW_THREADS
4152
Larry Hastings2f936352014-08-05 14:04:04 +10004153 if (!result)
4154 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004155
4156#else
Steve Dowercc16be82016-09-08 10:35:16 -07004157 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4158 PyErr_Format(PyExc_ValueError,
4159 "%s: src and dst must be the same type", function_name);
4160 return NULL;
4161 }
4162
Larry Hastings9cf065c2012-06-22 16:30:09 -07004163 Py_BEGIN_ALLOW_THREADS
4164#ifdef HAVE_RENAMEAT
4165 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004166 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004167 else
4168#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004169 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004170 Py_END_ALLOW_THREADS
4171
Larry Hastings2f936352014-08-05 14:04:04 +10004172 if (result)
4173 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004174#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004175 Py_RETURN_NONE;
4176}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004177
Larry Hastings2f936352014-08-05 14:04:04 +10004178
4179/*[clinic input]
4180os.rename
4181
4182 src : path_t
4183 dst : path_t
4184 *
4185 src_dir_fd : dir_fd = None
4186 dst_dir_fd : dir_fd = None
4187
4188Rename a file or directory.
4189
4190If either src_dir_fd or dst_dir_fd is not None, it should be a file
4191 descriptor open to a directory, and the respective path string (src or dst)
4192 should be relative; the path will then be relative to that directory.
4193src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4194 If they are unavailable, using them will raise a NotImplementedError.
4195[clinic start generated code]*/
4196
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004197static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004198os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004199 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004200/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004201{
Larry Hastings2f936352014-08-05 14:04:04 +10004202 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004203}
4204
Larry Hastings2f936352014-08-05 14:04:04 +10004205
4206/*[clinic input]
4207os.replace = os.rename
4208
4209Rename a file or directory, overwriting the destination.
4210
4211If either src_dir_fd or dst_dir_fd is not None, it should be a file
4212 descriptor open to a directory, and the respective path string (src or dst)
4213 should be relative; the path will then be relative to that directory.
4214src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004215 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004216[clinic start generated code]*/
4217
Larry Hastings2f936352014-08-05 14:04:04 +10004218static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004219os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4220 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004221/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004222{
4223 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4224}
4225
4226
4227/*[clinic input]
4228os.rmdir
4229
4230 path: path_t
4231 *
4232 dir_fd: dir_fd(requires='unlinkat') = None
4233
4234Remove a directory.
4235
4236If dir_fd is not None, it should be a file descriptor open to a directory,
4237 and path should be relative; path will then be relative to that directory.
4238dir_fd may not be implemented on your platform.
4239 If it is unavailable, using it will raise a NotImplementedError.
4240[clinic start generated code]*/
4241
Larry Hastings2f936352014-08-05 14:04:04 +10004242static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004243os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4244/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004245{
4246 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004247
4248 Py_BEGIN_ALLOW_THREADS
4249#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004250 /* Windows, success=1, UNIX, success=0 */
4251 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004252#else
4253#ifdef HAVE_UNLINKAT
4254 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004255 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004256 else
4257#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004258 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004259#endif
4260 Py_END_ALLOW_THREADS
4261
Larry Hastings2f936352014-08-05 14:04:04 +10004262 if (result)
4263 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004264
Larry Hastings2f936352014-08-05 14:04:04 +10004265 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004266}
4267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004268
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004269#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004270#ifdef MS_WINDOWS
4271/*[clinic input]
4272os.system -> long
4273
4274 command: Py_UNICODE
4275
4276Execute the command in a subshell.
4277[clinic start generated code]*/
4278
Larry Hastings2f936352014-08-05 14:04:04 +10004279static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004280os_system_impl(PyObject *module, const Py_UNICODE *command)
4281/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004282{
4283 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004284
4285 if (PySys_Audit("system", "(u)", command) < 0) {
4286 return -1;
4287 }
4288
Victor Stinner8c62be82010-05-06 00:08:46 +00004289 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004290 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004291 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004292 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004293 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004294 return result;
4295}
4296#else /* MS_WINDOWS */
4297/*[clinic input]
4298os.system -> long
4299
4300 command: FSConverter
4301
4302Execute the command in a subshell.
4303[clinic start generated code]*/
4304
Larry Hastings2f936352014-08-05 14:04:04 +10004305static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004306os_system_impl(PyObject *module, PyObject *command)
4307/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004308{
4309 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004310 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004311
4312 if (PySys_Audit("system", "(O)", command) < 0) {
4313 return -1;
4314 }
4315
Larry Hastings2f936352014-08-05 14:04:04 +10004316 Py_BEGIN_ALLOW_THREADS
4317 result = system(bytes);
4318 Py_END_ALLOW_THREADS
4319 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004320}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004321#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004322#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004323
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004324
Larry Hastings2f936352014-08-05 14:04:04 +10004325/*[clinic input]
4326os.umask
4327
4328 mask: int
4329 /
4330
4331Set the current numeric umask and return the previous umask.
4332[clinic start generated code]*/
4333
Larry Hastings2f936352014-08-05 14:04:04 +10004334static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004335os_umask_impl(PyObject *module, int mask)
4336/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004337{
4338 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004339 if (i < 0)
4340 return posix_error();
4341 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004342}
4343
Brian Curtind40e6f72010-07-08 21:39:08 +00004344#ifdef MS_WINDOWS
4345
4346/* override the default DeleteFileW behavior so that directory
4347symlinks can be removed with this function, the same as with
4348Unix symlinks */
4349BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4350{
4351 WIN32_FILE_ATTRIBUTE_DATA info;
4352 WIN32_FIND_DATAW find_data;
4353 HANDLE find_data_handle;
4354 int is_directory = 0;
4355 int is_link = 0;
4356
4357 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4358 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004359
Brian Curtind40e6f72010-07-08 21:39:08 +00004360 /* Get WIN32_FIND_DATA structure for the path to determine if
4361 it is a symlink */
4362 if(is_directory &&
4363 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4364 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4365
4366 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004367 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4368 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4369 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4370 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004371 FindClose(find_data_handle);
4372 }
4373 }
4374 }
4375
4376 if (is_directory && is_link)
4377 return RemoveDirectoryW(lpFileName);
4378
4379 return DeleteFileW(lpFileName);
4380}
4381#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004382
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004383
Larry Hastings2f936352014-08-05 14:04:04 +10004384/*[clinic input]
4385os.unlink
4386
4387 path: path_t
4388 *
4389 dir_fd: dir_fd(requires='unlinkat')=None
4390
4391Remove a file (same as remove()).
4392
4393If dir_fd is not None, it should be a file descriptor open to a directory,
4394 and path should be relative; path will then be relative to that directory.
4395dir_fd may not be implemented on your platform.
4396 If it is unavailable, using it will raise a NotImplementedError.
4397
4398[clinic start generated code]*/
4399
Larry Hastings2f936352014-08-05 14:04:04 +10004400static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004401os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4402/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004403{
4404 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004405
4406 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004407 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004408#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004409 /* Windows, success=1, UNIX, success=0 */
4410 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004411#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004412#ifdef HAVE_UNLINKAT
4413 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004414 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004415 else
4416#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004417 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004418#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004419 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004420 Py_END_ALLOW_THREADS
4421
Larry Hastings2f936352014-08-05 14:04:04 +10004422 if (result)
4423 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004424
Larry Hastings2f936352014-08-05 14:04:04 +10004425 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004426}
4427
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004428
Larry Hastings2f936352014-08-05 14:04:04 +10004429/*[clinic input]
4430os.remove = os.unlink
4431
4432Remove a file (same as unlink()).
4433
4434If dir_fd is not None, it should be a file descriptor open to a directory,
4435 and path should be relative; path will then be relative to that directory.
4436dir_fd may not be implemented on your platform.
4437 If it is unavailable, using it will raise a NotImplementedError.
4438[clinic start generated code]*/
4439
Larry Hastings2f936352014-08-05 14:04:04 +10004440static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004441os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4442/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004443{
4444 return os_unlink_impl(module, path, dir_fd);
4445}
4446
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004447
Larry Hastings605a62d2012-06-24 04:33:36 -07004448static PyStructSequence_Field uname_result_fields[] = {
4449 {"sysname", "operating system name"},
4450 {"nodename", "name of machine on network (implementation-defined)"},
4451 {"release", "operating system release"},
4452 {"version", "operating system version"},
4453 {"machine", "hardware identifier"},
4454 {NULL}
4455};
4456
4457PyDoc_STRVAR(uname_result__doc__,
4458"uname_result: Result from os.uname().\n\n\
4459This object may be accessed either as a tuple of\n\
4460 (sysname, nodename, release, version, machine),\n\
4461or via the attributes sysname, nodename, release, version, and machine.\n\
4462\n\
4463See os.uname for more information.");
4464
4465static PyStructSequence_Desc uname_result_desc = {
4466 "uname_result", /* name */
4467 uname_result__doc__, /* doc */
4468 uname_result_fields,
4469 5
4470};
4471
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004472static PyTypeObject* UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07004473
4474
4475#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004476/*[clinic input]
4477os.uname
4478
4479Return an object identifying the current operating system.
4480
4481The object behaves like a named tuple with the following fields:
4482 (sysname, nodename, release, version, machine)
4483
4484[clinic start generated code]*/
4485
Larry Hastings2f936352014-08-05 14:04:04 +10004486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004487os_uname_impl(PyObject *module)
4488/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004489{
Victor Stinner8c62be82010-05-06 00:08:46 +00004490 struct utsname u;
4491 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004492 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004493
Victor Stinner8c62be82010-05-06 00:08:46 +00004494 Py_BEGIN_ALLOW_THREADS
4495 res = uname(&u);
4496 Py_END_ALLOW_THREADS
4497 if (res < 0)
4498 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004499
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004500 value = PyStructSequence_New(UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004501 if (value == NULL)
4502 return NULL;
4503
4504#define SET(i, field) \
4505 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004506 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004507 if (!o) { \
4508 Py_DECREF(value); \
4509 return NULL; \
4510 } \
4511 PyStructSequence_SET_ITEM(value, i, o); \
4512 } \
4513
4514 SET(0, u.sysname);
4515 SET(1, u.nodename);
4516 SET(2, u.release);
4517 SET(3, u.version);
4518 SET(4, u.machine);
4519
4520#undef SET
4521
4522 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004523}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004524#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004525
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004526
Larry Hastings9cf065c2012-06-22 16:30:09 -07004527
4528typedef struct {
4529 int now;
4530 time_t atime_s;
4531 long atime_ns;
4532 time_t mtime_s;
4533 long mtime_ns;
4534} utime_t;
4535
4536/*
Victor Stinner484df002014-10-09 13:52:31 +02004537 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538 * they also intentionally leak the declaration of a pointer named "time"
4539 */
4540#define UTIME_TO_TIMESPEC \
4541 struct timespec ts[2]; \
4542 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004543 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004544 time = NULL; \
4545 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004546 ts[0].tv_sec = ut->atime_s; \
4547 ts[0].tv_nsec = ut->atime_ns; \
4548 ts[1].tv_sec = ut->mtime_s; \
4549 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004550 time = ts; \
4551 } \
4552
4553#define UTIME_TO_TIMEVAL \
4554 struct timeval tv[2]; \
4555 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004556 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004557 time = NULL; \
4558 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004559 tv[0].tv_sec = ut->atime_s; \
4560 tv[0].tv_usec = ut->atime_ns / 1000; \
4561 tv[1].tv_sec = ut->mtime_s; \
4562 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004563 time = tv; \
4564 } \
4565
4566#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004567 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004568 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004569 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004570 time = NULL; \
4571 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004572 u.actime = ut->atime_s; \
4573 u.modtime = ut->mtime_s; \
4574 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004575 }
4576
4577#define UTIME_TO_TIME_T \
4578 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004579 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004580 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004581 time = NULL; \
4582 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004583 timet[0] = ut->atime_s; \
4584 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004585 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586 } \
4587
4588
Victor Stinner528a9ab2015-09-03 21:30:26 +02004589#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590
4591static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004592utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004593{
4594#ifdef HAVE_UTIMENSAT
4595 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4596 UTIME_TO_TIMESPEC;
4597 return utimensat(dir_fd, path, time, flags);
4598#elif defined(HAVE_FUTIMESAT)
4599 UTIME_TO_TIMEVAL;
4600 /*
4601 * follow_symlinks will never be false here;
4602 * we only allow !follow_symlinks and dir_fd together
4603 * if we have utimensat()
4604 */
4605 assert(follow_symlinks);
4606 return futimesat(dir_fd, path, time);
4607#endif
4608}
4609
Larry Hastings2f936352014-08-05 14:04:04 +10004610 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4611#else
4612 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004613#endif
4614
Victor Stinner528a9ab2015-09-03 21:30:26 +02004615#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004616
4617static int
Victor Stinner484df002014-10-09 13:52:31 +02004618utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004619{
4620#ifdef HAVE_FUTIMENS
4621 UTIME_TO_TIMESPEC;
4622 return futimens(fd, time);
4623#else
4624 UTIME_TO_TIMEVAL;
4625 return futimes(fd, time);
4626#endif
4627}
4628
Larry Hastings2f936352014-08-05 14:04:04 +10004629 #define PATH_UTIME_HAVE_FD 1
4630#else
4631 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004632#endif
4633
Victor Stinner5ebae872015-09-22 01:29:33 +02004634#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4635# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4636#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004637
Victor Stinner4552ced2015-09-21 22:37:15 +02004638#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004639
4640static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004641utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004642{
4643#ifdef HAVE_UTIMENSAT
4644 UTIME_TO_TIMESPEC;
4645 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4646#else
4647 UTIME_TO_TIMEVAL;
4648 return lutimes(path, time);
4649#endif
4650}
4651
4652#endif
4653
4654#ifndef MS_WINDOWS
4655
4656static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004657utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004658{
4659#ifdef HAVE_UTIMENSAT
4660 UTIME_TO_TIMESPEC;
4661 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4662#elif defined(HAVE_UTIMES)
4663 UTIME_TO_TIMEVAL;
4664 return utimes(path, time);
4665#elif defined(HAVE_UTIME_H)
4666 UTIME_TO_UTIMBUF;
4667 return utime(path, time);
4668#else
4669 UTIME_TO_TIME_T;
4670 return utime(path, time);
4671#endif
4672}
4673
4674#endif
4675
Larry Hastings76ad59b2012-05-03 00:30:07 -07004676static int
4677split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4678{
4679 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004680 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004681 divmod = PyNumber_Divmod(py_long, billion);
4682 if (!divmod)
4683 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004684 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4685 PyErr_Format(PyExc_TypeError,
4686 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4687 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4688 goto exit;
4689 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004690 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4691 if ((*s == -1) && PyErr_Occurred())
4692 goto exit;
4693 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004694 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004695 goto exit;
4696
4697 result = 1;
4698exit:
4699 Py_XDECREF(divmod);
4700 return result;
4701}
4702
Larry Hastings2f936352014-08-05 14:04:04 +10004703
4704/*[clinic input]
4705os.utime
4706
4707 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4708 times: object = NULL
4709 *
4710 ns: object = NULL
4711 dir_fd: dir_fd(requires='futimensat') = None
4712 follow_symlinks: bool=True
4713
Martin Panter0ff89092015-09-09 01:56:53 +00004714# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004715
4716Set the access and modified time of path.
4717
4718path may always be specified as a string.
4719On some platforms, path may also be specified as an open file descriptor.
4720 If this functionality is unavailable, using it raises an exception.
4721
4722If times is not None, it must be a tuple (atime, mtime);
4723 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004724If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004725 atime_ns and mtime_ns should be expressed as integer nanoseconds
4726 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004727If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004728Specifying tuples for both times and ns is an error.
4729
4730If dir_fd is not None, it should be a file descriptor open to a directory,
4731 and path should be relative; path will then be relative to that directory.
4732If follow_symlinks is False, and the last element of the path is a symbolic
4733 link, utime will modify the symbolic link itself instead of the file the
4734 link points to.
4735It is an error to use dir_fd or follow_symlinks when specifying path
4736 as an open file descriptor.
4737dir_fd and follow_symlinks may not be available on your platform.
4738 If they are unavailable, using them will raise a NotImplementedError.
4739
4740[clinic start generated code]*/
4741
Larry Hastings2f936352014-08-05 14:04:04 +10004742static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004743os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4744 int dir_fd, int follow_symlinks)
4745/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004746{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747#ifdef MS_WINDOWS
4748 HANDLE hFile;
4749 FILETIME atime, mtime;
4750#else
4751 int result;
4752#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004753
Larry Hastings2f936352014-08-05 14:04:04 +10004754 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004755
Christian Heimesb3c87242013-08-01 00:08:16 +02004756 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004757
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 if (times && (times != Py_None) && ns) {
4759 PyErr_SetString(PyExc_ValueError,
4760 "utime: you may specify either 'times'"
4761 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004762 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004763 }
4764
4765 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004766 time_t a_sec, m_sec;
4767 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004768 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769 PyErr_SetString(PyExc_TypeError,
4770 "utime: 'times' must be either"
4771 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004772 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004773 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004774 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004775 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004776 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004777 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004778 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004779 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004780 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004781 utime.atime_s = a_sec;
4782 utime.atime_ns = a_nsec;
4783 utime.mtime_s = m_sec;
4784 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004785 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004786 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004787 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004788 PyErr_SetString(PyExc_TypeError,
4789 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004790 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004791 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004792 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004793 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004794 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004795 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004796 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004797 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004798 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004799 }
4800 else {
4801 /* times and ns are both None/unspecified. use "now". */
4802 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004803 }
4804
Victor Stinner4552ced2015-09-21 22:37:15 +02004805#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004806 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004807 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004808#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004809
Larry Hastings2f936352014-08-05 14:04:04 +10004810 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4811 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4812 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004813 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004814
Larry Hastings9cf065c2012-06-22 16:30:09 -07004815#if !defined(HAVE_UTIMENSAT)
4816 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004817 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004818 "utime: cannot use dir_fd and follow_symlinks "
4819 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004820 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004821 }
4822#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004823
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004824#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004825 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004826 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4827 NULL, OPEN_EXISTING,
4828 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004829 Py_END_ALLOW_THREADS
4830 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004831 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004832 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004833 }
4834
Larry Hastings9cf065c2012-06-22 16:30:09 -07004835 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004836 GetSystemTimeAsFileTime(&mtime);
4837 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004838 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004839 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004840 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4841 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 }
4843 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4844 /* Avoid putting the file name into the error here,
4845 as that may confuse the user into believing that
4846 something is wrong with the file, when it also
4847 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004848 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004849 CloseHandle(hFile);
4850 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004851 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004852 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004853#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004854 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004855
Victor Stinner4552ced2015-09-21 22:37:15 +02004856#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004857 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004858 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004859 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004860#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004861
Victor Stinner528a9ab2015-09-03 21:30:26 +02004862#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004863 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004864 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004865 else
4866#endif
4867
Victor Stinner528a9ab2015-09-03 21:30:26 +02004868#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004869 if (path->fd != -1)
4870 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004871 else
4872#endif
4873
Larry Hastings2f936352014-08-05 14:04:04 +10004874 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004875
4876 Py_END_ALLOW_THREADS
4877
4878 if (result < 0) {
4879 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004880 posix_error();
4881 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004882 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004883
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004884#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004885
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004886 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004887}
4888
Guido van Rossum3b066191991-06-04 19:40:25 +00004889/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004890
Larry Hastings2f936352014-08-05 14:04:04 +10004891
4892/*[clinic input]
4893os._exit
4894
4895 status: int
4896
4897Exit to the system with specified status, without normal exit processing.
4898[clinic start generated code]*/
4899
Larry Hastings2f936352014-08-05 14:04:04 +10004900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004901os__exit_impl(PyObject *module, int status)
4902/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004903{
4904 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004905 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004906}
4907
Steve Dowercc16be82016-09-08 10:35:16 -07004908#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4909#define EXECV_CHAR wchar_t
4910#else
4911#define EXECV_CHAR char
4912#endif
4913
pxinwrf2d7ac72019-05-21 18:46:37 +08004914#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004915static void
Steve Dowercc16be82016-09-08 10:35:16 -07004916free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004917{
Victor Stinner8c62be82010-05-06 00:08:46 +00004918 Py_ssize_t i;
4919 for (i = 0; i < count; i++)
4920 PyMem_Free(array[i]);
4921 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004922}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004923
Berker Peksag81816462016-09-15 20:19:47 +03004924static int
4925fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004926{
Victor Stinner8c62be82010-05-06 00:08:46 +00004927 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004928 PyObject *ub;
4929 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004930#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004931 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004932 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004933 *out = PyUnicode_AsWideCharString(ub, &size);
4934 if (*out)
4935 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004936#else
Berker Peksag81816462016-09-15 20:19:47 +03004937 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004939 size = PyBytes_GET_SIZE(ub);
4940 *out = PyMem_Malloc(size + 1);
4941 if (*out) {
4942 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4943 result = 1;
4944 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004945 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004946#endif
Berker Peksag81816462016-09-15 20:19:47 +03004947 Py_DECREF(ub);
4948 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004949}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004950#endif
4951
pxinwrf2d7ac72019-05-21 18:46:37 +08004952#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07004953static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004954parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4955{
Victor Stinner8c62be82010-05-06 00:08:46 +00004956 Py_ssize_t i, pos, envc;
4957 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004958 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004959 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004960
Victor Stinner8c62be82010-05-06 00:08:46 +00004961 i = PyMapping_Size(env);
4962 if (i < 0)
4963 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004964 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004965 if (envlist == NULL) {
4966 PyErr_NoMemory();
4967 return NULL;
4968 }
4969 envc = 0;
4970 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004971 if (!keys)
4972 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004974 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 goto error;
4976 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4977 PyErr_Format(PyExc_TypeError,
4978 "env.keys() or env.values() is not a list");
4979 goto error;
4980 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004981
Victor Stinner8c62be82010-05-06 00:08:46 +00004982 for (pos = 0; pos < i; pos++) {
4983 key = PyList_GetItem(keys, pos);
4984 val = PyList_GetItem(vals, pos);
4985 if (!key || !val)
4986 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004987
Berker Peksag81816462016-09-15 20:19:47 +03004988#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4989 if (!PyUnicode_FSDecoder(key, &key2))
4990 goto error;
4991 if (!PyUnicode_FSDecoder(val, &val2)) {
4992 Py_DECREF(key2);
4993 goto error;
4994 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004995 /* Search from index 1 because on Windows starting '=' is allowed for
4996 defining hidden environment variables. */
4997 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4998 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4999 {
5000 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005001 Py_DECREF(key2);
5002 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005003 goto error;
5004 }
Berker Peksag81816462016-09-15 20:19:47 +03005005 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5006#else
5007 if (!PyUnicode_FSConverter(key, &key2))
5008 goto error;
5009 if (!PyUnicode_FSConverter(val, &val2)) {
5010 Py_DECREF(key2);
5011 goto error;
5012 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005013 if (PyBytes_GET_SIZE(key2) == 0 ||
5014 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5015 {
5016 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005017 Py_DECREF(key2);
5018 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005019 goto error;
5020 }
Berker Peksag81816462016-09-15 20:19:47 +03005021 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5022 PyBytes_AS_STRING(val2));
5023#endif
5024 Py_DECREF(key2);
5025 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005026 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005027 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005028
5029 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5030 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005031 goto error;
5032 }
Berker Peksag81816462016-09-15 20:19:47 +03005033
Steve Dowercc16be82016-09-08 10:35:16 -07005034 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005035 }
5036 Py_DECREF(vals);
5037 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005038
Victor Stinner8c62be82010-05-06 00:08:46 +00005039 envlist[envc] = 0;
5040 *envc_ptr = envc;
5041 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005042
5043error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005044 Py_XDECREF(keys);
5045 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005046 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005047 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005048}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005049
Steve Dowercc16be82016-09-08 10:35:16 -07005050static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005051parse_arglist(PyObject* argv, Py_ssize_t *argc)
5052{
5053 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005054 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005055 if (argvlist == NULL) {
5056 PyErr_NoMemory();
5057 return NULL;
5058 }
5059 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005060 PyObject* item = PySequence_ITEM(argv, i);
5061 if (item == NULL)
5062 goto fail;
5063 if (!fsconvert_strdup(item, &argvlist[i])) {
5064 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005065 goto fail;
5066 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005067 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005068 }
5069 argvlist[*argc] = NULL;
5070 return argvlist;
5071fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005072 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005073 free_string_array(argvlist, *argc);
5074 return NULL;
5075}
Steve Dowercc16be82016-09-08 10:35:16 -07005076
Ross Lagerwall7807c352011-03-17 20:20:30 +02005077#endif
5078
Larry Hastings2f936352014-08-05 14:04:04 +10005079
Ross Lagerwall7807c352011-03-17 20:20:30 +02005080#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005081/*[clinic input]
5082os.execv
5083
Steve Dowercc16be82016-09-08 10:35:16 -07005084 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005085 Path of executable file.
5086 argv: object
5087 Tuple or list of strings.
5088 /
5089
5090Execute an executable path with arguments, replacing current process.
5091[clinic start generated code]*/
5092
Larry Hastings2f936352014-08-05 14:04:04 +10005093static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005094os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5095/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005096{
Steve Dowercc16be82016-09-08 10:35:16 -07005097 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005098 Py_ssize_t argc;
5099
5100 /* execv has two arguments: (path, argv), where
5101 argv is a list or tuple of strings. */
5102
Ross Lagerwall7807c352011-03-17 20:20:30 +02005103 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5104 PyErr_SetString(PyExc_TypeError,
5105 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005106 return NULL;
5107 }
5108 argc = PySequence_Size(argv);
5109 if (argc < 1) {
5110 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005111 return NULL;
5112 }
5113
5114 argvlist = parse_arglist(argv, &argc);
5115 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005116 return NULL;
5117 }
Steve Dowerbce26262016-11-19 19:17:26 -08005118 if (!argvlist[0][0]) {
5119 PyErr_SetString(PyExc_ValueError,
5120 "execv() arg 2 first element cannot be empty");
5121 free_string_array(argvlist, argc);
5122 return NULL;
5123 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005124
Steve Dowerbce26262016-11-19 19:17:26 -08005125 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005126#ifdef HAVE_WEXECV
5127 _wexecv(path->wide, argvlist);
5128#else
5129 execv(path->narrow, argvlist);
5130#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005131 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005132
5133 /* If we get here it's definitely an error */
5134
5135 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005136 return posix_error();
5137}
5138
Larry Hastings2f936352014-08-05 14:04:04 +10005139
5140/*[clinic input]
5141os.execve
5142
5143 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5144 Path of executable file.
5145 argv: object
5146 Tuple or list of strings.
5147 env: object
5148 Dictionary of strings mapping to strings.
5149
5150Execute an executable path with arguments, replacing current process.
5151[clinic start generated code]*/
5152
Larry Hastings2f936352014-08-05 14:04:04 +10005153static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005154os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5155/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005156{
Steve Dowercc16be82016-09-08 10:35:16 -07005157 EXECV_CHAR **argvlist = NULL;
5158 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005159 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005160
Victor Stinner8c62be82010-05-06 00:08:46 +00005161 /* execve has three arguments: (path, argv, env), where
5162 argv is a list or tuple of strings and env is a dictionary
5163 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005164
Ross Lagerwall7807c352011-03-17 20:20:30 +02005165 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005167 "execve: argv must be a tuple or list");
5168 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005169 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005170 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005171 if (argc < 1) {
5172 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5173 return NULL;
5174 }
5175
Victor Stinner8c62be82010-05-06 00:08:46 +00005176 if (!PyMapping_Check(env)) {
5177 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005178 "execve: environment must be a mapping object");
5179 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005180 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005181
Ross Lagerwall7807c352011-03-17 20:20:30 +02005182 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005183 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005184 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005185 }
Steve Dowerbce26262016-11-19 19:17:26 -08005186 if (!argvlist[0][0]) {
5187 PyErr_SetString(PyExc_ValueError,
5188 "execve: argv first element cannot be empty");
5189 goto fail;
5190 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005191
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 envlist = parse_envlist(env, &envc);
5193 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005194 goto fail;
5195
Steve Dowerbce26262016-11-19 19:17:26 -08005196 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005197#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005198 if (path->fd > -1)
5199 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005200 else
5201#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005202#ifdef HAVE_WEXECV
5203 _wexecve(path->wide, argvlist, envlist);
5204#else
Larry Hastings2f936352014-08-05 14:04:04 +10005205 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005206#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005207 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005208
5209 /* If we get here it's definitely an error */
5210
Alexey Izbyshev83460312018-10-20 03:28:22 +03005211 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005212
Steve Dowercc16be82016-09-08 10:35:16 -07005213 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005214 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005215 if (argvlist)
5216 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005217 return NULL;
5218}
Steve Dowercc16be82016-09-08 10:35:16 -07005219
Larry Hastings9cf065c2012-06-22 16:30:09 -07005220#endif /* HAVE_EXECV */
5221
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005222#ifdef HAVE_POSIX_SPAWN
5223
5224enum posix_spawn_file_actions_identifier {
5225 POSIX_SPAWN_OPEN,
5226 POSIX_SPAWN_CLOSE,
5227 POSIX_SPAWN_DUP2
5228};
5229
William Orr81574b82018-10-01 22:19:56 -07005230#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005231static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005232convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005233#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005234
5235static int
Victor Stinner325e4ba2019-02-01 15:47:24 +01005236parse_posix_spawn_flags(const char *func_name, PyObject *setpgroup,
5237 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005238 PyObject *setsigdef, PyObject *scheduler,
5239 posix_spawnattr_t *attrp)
5240{
5241 long all_flags = 0;
5242
5243 errno = posix_spawnattr_init(attrp);
5244 if (errno) {
5245 posix_error();
5246 return -1;
5247 }
5248
5249 if (setpgroup) {
5250 pid_t pgid = PyLong_AsPid(setpgroup);
5251 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5252 goto fail;
5253 }
5254 errno = posix_spawnattr_setpgroup(attrp, pgid);
5255 if (errno) {
5256 posix_error();
5257 goto fail;
5258 }
5259 all_flags |= POSIX_SPAWN_SETPGROUP;
5260 }
5261
5262 if (resetids) {
5263 all_flags |= POSIX_SPAWN_RESETIDS;
5264 }
5265
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005266 if (setsid) {
5267#ifdef POSIX_SPAWN_SETSID
5268 all_flags |= POSIX_SPAWN_SETSID;
5269#elif defined(POSIX_SPAWN_SETSID_NP)
5270 all_flags |= POSIX_SPAWN_SETSID_NP;
5271#else
5272 argument_unavailable_error(func_name, "setsid");
5273 return -1;
5274#endif
5275 }
5276
Pablo Galindo254a4662018-09-07 16:44:24 +01005277 if (setsigmask) {
5278 sigset_t set;
5279 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5280 goto fail;
5281 }
5282 errno = posix_spawnattr_setsigmask(attrp, &set);
5283 if (errno) {
5284 posix_error();
5285 goto fail;
5286 }
5287 all_flags |= POSIX_SPAWN_SETSIGMASK;
5288 }
5289
5290 if (setsigdef) {
5291 sigset_t set;
5292 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5293 goto fail;
5294 }
5295 errno = posix_spawnattr_setsigdefault(attrp, &set);
5296 if (errno) {
5297 posix_error();
5298 goto fail;
5299 }
5300 all_flags |= POSIX_SPAWN_SETSIGDEF;
5301 }
5302
5303 if (scheduler) {
5304#ifdef POSIX_SPAWN_SETSCHEDULER
5305 PyObject *py_schedpolicy;
5306 struct sched_param schedparam;
5307
5308 if (!PyArg_ParseTuple(scheduler, "OO&"
5309 ";A scheduler tuple must have two elements",
5310 &py_schedpolicy, convert_sched_param, &schedparam)) {
5311 goto fail;
5312 }
5313 if (py_schedpolicy != Py_None) {
5314 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5315
5316 if (schedpolicy == -1 && PyErr_Occurred()) {
5317 goto fail;
5318 }
5319 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5320 if (errno) {
5321 posix_error();
5322 goto fail;
5323 }
5324 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5325 }
5326 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5327 if (errno) {
5328 posix_error();
5329 goto fail;
5330 }
5331 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5332#else
5333 PyErr_SetString(PyExc_NotImplementedError,
5334 "The scheduler option is not supported in this system.");
5335 goto fail;
5336#endif
5337 }
5338
5339 errno = posix_spawnattr_setflags(attrp, all_flags);
5340 if (errno) {
5341 posix_error();
5342 goto fail;
5343 }
5344
5345 return 0;
5346
5347fail:
5348 (void)posix_spawnattr_destroy(attrp);
5349 return -1;
5350}
5351
5352static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005353parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005354 posix_spawn_file_actions_t *file_actionsp,
5355 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005356{
5357 PyObject *seq;
5358 PyObject *file_action = NULL;
5359 PyObject *tag_obj;
5360
5361 seq = PySequence_Fast(file_actions,
5362 "file_actions must be a sequence or None");
5363 if (seq == NULL) {
5364 return -1;
5365 }
5366
5367 errno = posix_spawn_file_actions_init(file_actionsp);
5368 if (errno) {
5369 posix_error();
5370 Py_DECREF(seq);
5371 return -1;
5372 }
5373
5374 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5375 file_action = PySequence_Fast_GET_ITEM(seq, i);
5376 Py_INCREF(file_action);
5377 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5378 PyErr_SetString(PyExc_TypeError,
5379 "Each file_actions element must be a non-empty tuple");
5380 goto fail;
5381 }
5382 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5383 if (tag == -1 && PyErr_Occurred()) {
5384 goto fail;
5385 }
5386
5387 /* Populate the file_actions object */
5388 switch (tag) {
5389 case POSIX_SPAWN_OPEN: {
5390 int fd, oflag;
5391 PyObject *path;
5392 unsigned long mode;
5393 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5394 ";A open file_action tuple must have 5 elements",
5395 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5396 &oflag, &mode))
5397 {
5398 goto fail;
5399 }
Pablo Galindocb970732018-06-19 09:19:50 +01005400 if (PyList_Append(temp_buffer, path)) {
5401 Py_DECREF(path);
5402 goto fail;
5403 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005404 errno = posix_spawn_file_actions_addopen(file_actionsp,
5405 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005406 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005407 if (errno) {
5408 posix_error();
5409 goto fail;
5410 }
5411 break;
5412 }
5413 case POSIX_SPAWN_CLOSE: {
5414 int fd;
5415 if (!PyArg_ParseTuple(file_action, "Oi"
5416 ";A close file_action tuple must have 2 elements",
5417 &tag_obj, &fd))
5418 {
5419 goto fail;
5420 }
5421 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5422 if (errno) {
5423 posix_error();
5424 goto fail;
5425 }
5426 break;
5427 }
5428 case POSIX_SPAWN_DUP2: {
5429 int fd1, fd2;
5430 if (!PyArg_ParseTuple(file_action, "Oii"
5431 ";A dup2 file_action tuple must have 3 elements",
5432 &tag_obj, &fd1, &fd2))
5433 {
5434 goto fail;
5435 }
5436 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5437 fd1, fd2);
5438 if (errno) {
5439 posix_error();
5440 goto fail;
5441 }
5442 break;
5443 }
5444 default: {
5445 PyErr_SetString(PyExc_TypeError,
5446 "Unknown file_actions identifier");
5447 goto fail;
5448 }
5449 }
5450 Py_DECREF(file_action);
5451 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005452
Serhiy Storchakaef347532018-05-01 16:45:04 +03005453 Py_DECREF(seq);
5454 return 0;
5455
5456fail:
5457 Py_DECREF(seq);
5458 Py_DECREF(file_action);
5459 (void)posix_spawn_file_actions_destroy(file_actionsp);
5460 return -1;
5461}
5462
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005463
5464static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005465py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5466 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005467 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005468 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005469{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005470 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005471 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005472 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005473 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005474 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005475 posix_spawnattr_t attr;
5476 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005477 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005478 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005479 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005480 pid_t pid;
5481 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005482
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005483 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005484 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005485 like posix.environ. */
5486
Serhiy Storchakaef347532018-05-01 16:45:04 +03005487 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005488 PyErr_Format(PyExc_TypeError,
5489 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005490 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005491 }
5492 argc = PySequence_Size(argv);
5493 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005494 PyErr_Format(PyExc_ValueError,
5495 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005496 return NULL;
5497 }
5498
5499 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005500 PyErr_Format(PyExc_TypeError,
5501 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005502 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005503 }
5504
5505 argvlist = parse_arglist(argv, &argc);
5506 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005507 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005508 }
5509 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005510 PyErr_Format(PyExc_ValueError,
5511 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005512 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005513 }
5514
5515 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005516 if (envlist == NULL) {
5517 goto exit;
5518 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005519
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005520 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005521 /* There is a bug in old versions of glibc that makes some of the
5522 * helper functions for manipulating file actions not copy the provided
5523 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5524 * copy the value of path for some old versions of glibc (<2.20).
5525 * The use of temp_buffer here is a workaround that keeps the
5526 * python objects that own the buffers alive until posix_spawn gets called.
5527 * Check https://bugs.python.org/issue33630 and
5528 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5529 temp_buffer = PyList_New(0);
5530 if (!temp_buffer) {
5531 goto exit;
5532 }
5533 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005534 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005535 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005536 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005537 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005538
Victor Stinner325e4ba2019-02-01 15:47:24 +01005539 if (parse_posix_spawn_flags(func_name, setpgroup, resetids, setsid,
5540 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005541 goto exit;
5542 }
5543 attrp = &attr;
5544
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005545 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005546#ifdef HAVE_POSIX_SPAWNP
5547 if (use_posix_spawnp) {
5548 err_code = posix_spawnp(&pid, path->narrow,
5549 file_actionsp, attrp, argvlist, envlist);
5550 }
5551 else
5552#endif /* HAVE_POSIX_SPAWNP */
5553 {
5554 err_code = posix_spawn(&pid, path->narrow,
5555 file_actionsp, attrp, argvlist, envlist);
5556 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005557 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005558
Serhiy Storchakaef347532018-05-01 16:45:04 +03005559 if (err_code) {
5560 errno = err_code;
5561 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005562 goto exit;
5563 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005564#ifdef _Py_MEMORY_SANITIZER
5565 __msan_unpoison(&pid, sizeof(pid));
5566#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005567 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005568
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005569exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005570 if (file_actionsp) {
5571 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005572 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005573 if (attrp) {
5574 (void)posix_spawnattr_destroy(attrp);
5575 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005576 if (envlist) {
5577 free_string_array(envlist, envc);
5578 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005579 if (argvlist) {
5580 free_string_array(argvlist, argc);
5581 }
Pablo Galindocb970732018-06-19 09:19:50 +01005582 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005583 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005584}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005585
5586
5587/*[clinic input]
5588
5589os.posix_spawn
5590 path: path_t
5591 Path of executable file.
5592 argv: object
5593 Tuple or list of strings.
5594 env: object
5595 Dictionary of strings mapping to strings.
5596 /
5597 *
5598 file_actions: object(c_default='NULL') = ()
5599 A sequence of file action tuples.
5600 setpgroup: object = NULL
5601 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5602 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005603 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5604 setsid: bool(accept={int}) = False
5605 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005606 setsigmask: object(c_default='NULL') = ()
5607 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5608 setsigdef: object(c_default='NULL') = ()
5609 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5610 scheduler: object = NULL
5611 A tuple with the scheduler policy (optional) and parameters.
5612
5613Execute the program specified by path in a new process.
5614[clinic start generated code]*/
5615
5616static PyObject *
5617os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5618 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005619 PyObject *setpgroup, int resetids, int setsid,
5620 PyObject *setsigmask, PyObject *setsigdef,
5621 PyObject *scheduler)
5622/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005623{
5624 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005625 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005626 scheduler);
5627}
5628 #endif /* HAVE_POSIX_SPAWN */
5629
5630
5631
5632#ifdef HAVE_POSIX_SPAWNP
5633/*[clinic input]
5634
5635os.posix_spawnp
5636 path: path_t
5637 Path of executable file.
5638 argv: object
5639 Tuple or list of strings.
5640 env: object
5641 Dictionary of strings mapping to strings.
5642 /
5643 *
5644 file_actions: object(c_default='NULL') = ()
5645 A sequence of file action tuples.
5646 setpgroup: object = NULL
5647 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5648 resetids: bool(accept={int}) = False
5649 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005650 setsid: bool(accept={int}) = False
5651 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005652 setsigmask: object(c_default='NULL') = ()
5653 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5654 setsigdef: object(c_default='NULL') = ()
5655 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5656 scheduler: object = NULL
5657 A tuple with the scheduler policy (optional) and parameters.
5658
5659Execute the program specified by path in a new process.
5660[clinic start generated code]*/
5661
5662static PyObject *
5663os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5664 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005665 PyObject *setpgroup, int resetids, int setsid,
5666 PyObject *setsigmask, PyObject *setsigdef,
5667 PyObject *scheduler)
5668/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005669{
5670 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005671 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005672 scheduler);
5673}
5674#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005675
pxinwrf2d7ac72019-05-21 18:46:37 +08005676#ifdef HAVE_RTPSPAWN
5677static intptr_t
5678_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5679 const char *envp[])
5680{
5681 RTP_ID rtpid;
5682 int status;
5683 pid_t res;
5684 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005685
pxinwrf2d7ac72019-05-21 18:46:37 +08005686 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5687 uStackSize=0 cannot be used, the default stack size is too small for
5688 Python. */
5689 if (envp) {
5690 rtpid = rtpSpawn(rtpFileName, argv, envp,
5691 100, 0x1000000, 0, VX_FP_TASK);
5692 }
5693 else {
5694 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5695 100, 0x1000000, 0, VX_FP_TASK);
5696 }
5697 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5698 do {
5699 res = waitpid((pid_t)rtpid, &status, 0);
5700 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5701
5702 if (res < 0)
5703 return RTP_ID_ERROR;
5704 return ((intptr_t)status);
5705 }
5706 return ((intptr_t)rtpid);
5707}
5708#endif
5709
5710#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10005711/*[clinic input]
5712os.spawnv
5713
5714 mode: int
5715 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005716 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005717 Path of executable file.
5718 argv: object
5719 Tuple or list of strings.
5720 /
5721
5722Execute the program specified by path in a new process.
5723[clinic start generated code]*/
5724
Larry Hastings2f936352014-08-05 14:04:04 +10005725static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005726os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5727/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005728{
Steve Dowercc16be82016-09-08 10:35:16 -07005729 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005730 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005731 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005732 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005733 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005734
Victor Stinner8c62be82010-05-06 00:08:46 +00005735 /* spawnv has three arguments: (mode, path, argv), where
5736 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005737
Victor Stinner8c62be82010-05-06 00:08:46 +00005738 if (PyList_Check(argv)) {
5739 argc = PyList_Size(argv);
5740 getitem = PyList_GetItem;
5741 }
5742 else if (PyTuple_Check(argv)) {
5743 argc = PyTuple_Size(argv);
5744 getitem = PyTuple_GetItem;
5745 }
5746 else {
5747 PyErr_SetString(PyExc_TypeError,
5748 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005749 return NULL;
5750 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005751 if (argc == 0) {
5752 PyErr_SetString(PyExc_ValueError,
5753 "spawnv() arg 2 cannot be empty");
5754 return NULL;
5755 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005756
Steve Dowercc16be82016-09-08 10:35:16 -07005757 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005758 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005759 return PyErr_NoMemory();
5760 }
5761 for (i = 0; i < argc; i++) {
5762 if (!fsconvert_strdup((*getitem)(argv, i),
5763 &argvlist[i])) {
5764 free_string_array(argvlist, i);
5765 PyErr_SetString(
5766 PyExc_TypeError,
5767 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005768 return NULL;
5769 }
Steve Dower93ff8722016-11-19 19:03:54 -08005770 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005771 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005772 PyErr_SetString(
5773 PyExc_ValueError,
5774 "spawnv() arg 2 first element cannot be empty");
5775 return NULL;
5776 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005777 }
5778 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005779
pxinwrf2d7ac72019-05-21 18:46:37 +08005780#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005781 if (mode == _OLD_P_OVERLAY)
5782 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005783#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005784
Victor Stinner8c62be82010-05-06 00:08:46 +00005785 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005786 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005787#ifdef HAVE_WSPAWNV
5788 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005789#elif defined(HAVE_RTPSPAWN)
5790 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07005791#else
5792 spawnval = _spawnv(mode, path->narrow, argvlist);
5793#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005794 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005795 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005796
Victor Stinner8c62be82010-05-06 00:08:46 +00005797 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005798
Victor Stinner8c62be82010-05-06 00:08:46 +00005799 if (spawnval == -1)
5800 return posix_error();
5801 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005802 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005803}
5804
Larry Hastings2f936352014-08-05 14:04:04 +10005805/*[clinic input]
5806os.spawnve
5807
5808 mode: int
5809 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005810 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005811 Path of executable file.
5812 argv: object
5813 Tuple or list of strings.
5814 env: object
5815 Dictionary of strings mapping to strings.
5816 /
5817
5818Execute the program specified by path in a new process.
5819[clinic start generated code]*/
5820
Larry Hastings2f936352014-08-05 14:04:04 +10005821static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005822os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005823 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005824/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005825{
Steve Dowercc16be82016-09-08 10:35:16 -07005826 EXECV_CHAR **argvlist;
5827 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005828 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005829 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005830 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005831 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005832 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005833
Victor Stinner8c62be82010-05-06 00:08:46 +00005834 /* spawnve has four arguments: (mode, path, argv, env), where
5835 argv is a list or tuple of strings and env is a dictionary
5836 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005837
Victor Stinner8c62be82010-05-06 00:08:46 +00005838 if (PyList_Check(argv)) {
5839 argc = PyList_Size(argv);
5840 getitem = PyList_GetItem;
5841 }
5842 else if (PyTuple_Check(argv)) {
5843 argc = PyTuple_Size(argv);
5844 getitem = PyTuple_GetItem;
5845 }
5846 else {
5847 PyErr_SetString(PyExc_TypeError,
5848 "spawnve() arg 2 must be a tuple or list");
5849 goto fail_0;
5850 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005851 if (argc == 0) {
5852 PyErr_SetString(PyExc_ValueError,
5853 "spawnve() arg 2 cannot be empty");
5854 goto fail_0;
5855 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005856 if (!PyMapping_Check(env)) {
5857 PyErr_SetString(PyExc_TypeError,
5858 "spawnve() arg 3 must be a mapping object");
5859 goto fail_0;
5860 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005861
Steve Dowercc16be82016-09-08 10:35:16 -07005862 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005863 if (argvlist == NULL) {
5864 PyErr_NoMemory();
5865 goto fail_0;
5866 }
5867 for (i = 0; i < argc; i++) {
5868 if (!fsconvert_strdup((*getitem)(argv, i),
5869 &argvlist[i]))
5870 {
5871 lastarg = i;
5872 goto fail_1;
5873 }
Steve Dowerbce26262016-11-19 19:17:26 -08005874 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005875 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005876 PyErr_SetString(
5877 PyExc_ValueError,
5878 "spawnv() arg 2 first element cannot be empty");
5879 goto fail_1;
5880 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005881 }
5882 lastarg = argc;
5883 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005884
Victor Stinner8c62be82010-05-06 00:08:46 +00005885 envlist = parse_envlist(env, &envc);
5886 if (envlist == NULL)
5887 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005888
pxinwrf2d7ac72019-05-21 18:46:37 +08005889#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005890 if (mode == _OLD_P_OVERLAY)
5891 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005892#endif
Tim Peters25059d32001-12-07 20:35:43 +00005893
Victor Stinner8c62be82010-05-06 00:08:46 +00005894 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005895 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005896#ifdef HAVE_WSPAWNV
5897 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005898#elif defined(HAVE_RTPSPAWN)
5899 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
5900 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005901#else
5902 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5903#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005904 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005905 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005906
Victor Stinner8c62be82010-05-06 00:08:46 +00005907 if (spawnval == -1)
5908 (void) posix_error();
5909 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005910 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005911
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 while (--envc >= 0)
5913 PyMem_DEL(envlist[envc]);
5914 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005915 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005916 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005917 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005919}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005920
Guido van Rossuma1065681999-01-25 23:20:23 +00005921#endif /* HAVE_SPAWNV */
5922
5923
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005924#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005925
5926/* Helper function to validate arguments.
5927 Returns 0 on success. non-zero on failure with a TypeError raised.
5928 If obj is non-NULL it must be callable. */
5929static int
5930check_null_or_callable(PyObject *obj, const char* obj_name)
5931{
5932 if (obj && !PyCallable_Check(obj)) {
5933 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5934 obj_name, Py_TYPE(obj)->tp_name);
5935 return -1;
5936 }
5937 return 0;
5938}
5939
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005940/*[clinic input]
5941os.register_at_fork
5942
Gregory P. Smith163468a2017-05-29 10:03:41 -07005943 *
5944 before: object=NULL
5945 A callable to be called in the parent before the fork() syscall.
5946 after_in_child: object=NULL
5947 A callable to be called in the child after fork().
5948 after_in_parent: object=NULL
5949 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005950
Gregory P. Smith163468a2017-05-29 10:03:41 -07005951Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005952
Gregory P. Smith163468a2017-05-29 10:03:41 -07005953'before' callbacks are called in reverse order.
5954'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005955
5956[clinic start generated code]*/
5957
5958static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005959os_register_at_fork_impl(PyObject *module, PyObject *before,
5960 PyObject *after_in_child, PyObject *after_in_parent)
5961/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005962{
5963 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005964
Gregory P. Smith163468a2017-05-29 10:03:41 -07005965 if (!before && !after_in_child && !after_in_parent) {
5966 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5967 return NULL;
5968 }
5969 if (check_null_or_callable(before, "before") ||
5970 check_null_or_callable(after_in_child, "after_in_child") ||
5971 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005972 return NULL;
5973 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02005974 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005975
Gregory P. Smith163468a2017-05-29 10:03:41 -07005976 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005977 return NULL;
5978 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005979 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005980 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005981 }
5982 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5983 return NULL;
5984 }
5985 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005986}
5987#endif /* HAVE_FORK */
5988
5989
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005990#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005991/*[clinic input]
5992os.fork1
5993
5994Fork a child process with a single multiplexed (i.e., not bound) thread.
5995
5996Return 0 to child process and PID of child to parent process.
5997[clinic start generated code]*/
5998
Larry Hastings2f936352014-08-05 14:04:04 +10005999static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006000os_fork1_impl(PyObject *module)
6001/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006002{
Victor Stinner8c62be82010-05-06 00:08:46 +00006003 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006004
Eric Snow59032962018-09-14 14:17:20 -07006005 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6006 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6007 return NULL;
6008 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006009 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006010 pid = fork1();
6011 if (pid == 0) {
6012 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006013 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006014 } else {
6015 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006016 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006017 }
6018 if (pid == -1)
6019 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006020 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006021}
Larry Hastings2f936352014-08-05 14:04:04 +10006022#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006023
6024
Guido van Rossumad0ee831995-03-01 10:34:45 +00006025#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006026/*[clinic input]
6027os.fork
6028
6029Fork a child process.
6030
6031Return 0 to child process and PID of child to parent process.
6032[clinic start generated code]*/
6033
Larry Hastings2f936352014-08-05 14:04:04 +10006034static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006035os_fork_impl(PyObject *module)
6036/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006037{
Victor Stinner8c62be82010-05-06 00:08:46 +00006038 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006039
Eric Snow59032962018-09-14 14:17:20 -07006040 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6041 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6042 return NULL;
6043 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006044 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006045 pid = fork();
6046 if (pid == 0) {
6047 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006048 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006049 } else {
6050 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006051 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006052 }
6053 if (pid == -1)
6054 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006055 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006056}
Larry Hastings2f936352014-08-05 14:04:04 +10006057#endif /* HAVE_FORK */
6058
Guido van Rossum85e3b011991-06-03 12:42:10 +00006059
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006060#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006061#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006062/*[clinic input]
6063os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006064
Larry Hastings2f936352014-08-05 14:04:04 +10006065 policy: int
6066
6067Get the maximum scheduling priority for policy.
6068[clinic start generated code]*/
6069
Larry Hastings2f936352014-08-05 14:04:04 +10006070static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006071os_sched_get_priority_max_impl(PyObject *module, int policy)
6072/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006073{
6074 int max;
6075
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006076 max = sched_get_priority_max(policy);
6077 if (max < 0)
6078 return posix_error();
6079 return PyLong_FromLong(max);
6080}
6081
Larry Hastings2f936352014-08-05 14:04:04 +10006082
6083/*[clinic input]
6084os.sched_get_priority_min
6085
6086 policy: int
6087
6088Get the minimum scheduling priority for policy.
6089[clinic start generated code]*/
6090
Larry Hastings2f936352014-08-05 14:04:04 +10006091static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006092os_sched_get_priority_min_impl(PyObject *module, int policy)
6093/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006094{
6095 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006096 if (min < 0)
6097 return posix_error();
6098 return PyLong_FromLong(min);
6099}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006100#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6101
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006102
Larry Hastings2f936352014-08-05 14:04:04 +10006103#ifdef HAVE_SCHED_SETSCHEDULER
6104/*[clinic input]
6105os.sched_getscheduler
6106 pid: pid_t
6107 /
6108
6109Get the scheduling policy for the process identifiedy by pid.
6110
6111Passing 0 for pid returns the scheduling policy for the calling process.
6112[clinic start generated code]*/
6113
Larry Hastings2f936352014-08-05 14:04:04 +10006114static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006115os_sched_getscheduler_impl(PyObject *module, pid_t pid)
6116/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006117{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006118 int policy;
6119
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006120 policy = sched_getscheduler(pid);
6121 if (policy < 0)
6122 return posix_error();
6123 return PyLong_FromLong(policy);
6124}
Larry Hastings2f936352014-08-05 14:04:04 +10006125#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006126
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006127
William Orr81574b82018-10-01 22:19:56 -07006128#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006129/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006130class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006131
6132@classmethod
6133os.sched_param.__new__
6134
6135 sched_priority: object
6136 A scheduling parameter.
6137
6138Current has only one field: sched_priority");
6139[clinic start generated code]*/
6140
Larry Hastings2f936352014-08-05 14:04:04 +10006141static PyObject *
6142os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006143/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006144{
6145 PyObject *res;
6146
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006147 res = PyStructSequence_New(type);
6148 if (!res)
6149 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006150 Py_INCREF(sched_priority);
6151 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006152 return res;
6153}
6154
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006155
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006156PyDoc_VAR(os_sched_param__doc__);
6157
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006158static PyStructSequence_Field sched_param_fields[] = {
6159 {"sched_priority", "the scheduling priority"},
6160 {0}
6161};
6162
6163static PyStructSequence_Desc sched_param_desc = {
6164 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006165 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006166 sched_param_fields,
6167 1
6168};
6169
6170static int
6171convert_sched_param(PyObject *param, struct sched_param *res)
6172{
6173 long priority;
6174
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006175 if (Py_TYPE(param) != SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006176 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6177 return 0;
6178 }
6179 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6180 if (priority == -1 && PyErr_Occurred())
6181 return 0;
6182 if (priority > INT_MAX || priority < INT_MIN) {
6183 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6184 return 0;
6185 }
6186 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6187 return 1;
6188}
William Orr81574b82018-10-01 22:19:56 -07006189#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006190
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006191
6192#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006193/*[clinic input]
6194os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006195
Larry Hastings2f936352014-08-05 14:04:04 +10006196 pid: pid_t
6197 policy: int
6198 param: sched_param
6199 /
6200
6201Set the scheduling policy for the process identified by pid.
6202
6203If pid is 0, the calling process is changed.
6204param is an instance of sched_param.
6205[clinic start generated code]*/
6206
Larry Hastings2f936352014-08-05 14:04:04 +10006207static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006208os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006209 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006210/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006211{
Jesus Cea9c822272011-09-10 01:40:52 +02006212 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006213 ** sched_setscheduler() returns 0 in Linux, but the previous
6214 ** scheduling policy under Solaris/Illumos, and others.
6215 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006216 */
Larry Hastings2f936352014-08-05 14:04:04 +10006217 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006218 return posix_error();
6219 Py_RETURN_NONE;
6220}
Larry Hastings2f936352014-08-05 14:04:04 +10006221#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006222
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006223
6224#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006225/*[clinic input]
6226os.sched_getparam
6227 pid: pid_t
6228 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006229
Larry Hastings2f936352014-08-05 14:04:04 +10006230Returns scheduling parameters for the process identified by pid.
6231
6232If pid is 0, returns parameters for the calling process.
6233Return value is an instance of sched_param.
6234[clinic start generated code]*/
6235
Larry Hastings2f936352014-08-05 14:04:04 +10006236static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006237os_sched_getparam_impl(PyObject *module, pid_t pid)
6238/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006239{
6240 struct sched_param param;
6241 PyObject *result;
6242 PyObject *priority;
6243
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006244 if (sched_getparam(pid, &param))
6245 return posix_error();
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006246 result = PyStructSequence_New(SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006247 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006248 return NULL;
6249 priority = PyLong_FromLong(param.sched_priority);
6250 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006251 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006252 return NULL;
6253 }
Larry Hastings2f936352014-08-05 14:04:04 +10006254 PyStructSequence_SET_ITEM(result, 0, priority);
6255 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006256}
6257
Larry Hastings2f936352014-08-05 14:04:04 +10006258
6259/*[clinic input]
6260os.sched_setparam
6261 pid: pid_t
6262 param: sched_param
6263 /
6264
6265Set scheduling parameters for the process identified by pid.
6266
6267If pid is 0, sets parameters for the calling process.
6268param should be an instance of sched_param.
6269[clinic start generated code]*/
6270
Larry Hastings2f936352014-08-05 14:04:04 +10006271static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006272os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006273 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006274/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006275{
6276 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006277 return posix_error();
6278 Py_RETURN_NONE;
6279}
Larry Hastings2f936352014-08-05 14:04:04 +10006280#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006281
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006282
6283#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006284/*[clinic input]
6285os.sched_rr_get_interval -> double
6286 pid: pid_t
6287 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006288
Larry Hastings2f936352014-08-05 14:04:04 +10006289Return the round-robin quantum for the process identified by pid, in seconds.
6290
6291Value returned is a float.
6292[clinic start generated code]*/
6293
Larry Hastings2f936352014-08-05 14:04:04 +10006294static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006295os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6296/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006297{
6298 struct timespec interval;
6299 if (sched_rr_get_interval(pid, &interval)) {
6300 posix_error();
6301 return -1.0;
6302 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006303#ifdef _Py_MEMORY_SANITIZER
6304 __msan_unpoison(&interval, sizeof(interval));
6305#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006306 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6307}
6308#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006309
Larry Hastings2f936352014-08-05 14:04:04 +10006310
6311/*[clinic input]
6312os.sched_yield
6313
6314Voluntarily relinquish the CPU.
6315[clinic start generated code]*/
6316
Larry Hastings2f936352014-08-05 14:04:04 +10006317static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006318os_sched_yield_impl(PyObject *module)
6319/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006320{
6321 if (sched_yield())
6322 return posix_error();
6323 Py_RETURN_NONE;
6324}
6325
Benjamin Peterson2740af82011-08-02 17:41:34 -05006326#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006327/* The minimum number of CPUs allocated in a cpu_set_t */
6328static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006329
Larry Hastings2f936352014-08-05 14:04:04 +10006330/*[clinic input]
6331os.sched_setaffinity
6332 pid: pid_t
6333 mask : object
6334 /
6335
6336Set the CPU affinity of the process identified by pid to mask.
6337
6338mask should be an iterable of integers identifying CPUs.
6339[clinic start generated code]*/
6340
Larry Hastings2f936352014-08-05 14:04:04 +10006341static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006342os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6343/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006344{
Antoine Pitrou84869872012-08-04 16:16:35 +02006345 int ncpus;
6346 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006347 cpu_set_t *cpu_set = NULL;
6348 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006349
Larry Hastings2f936352014-08-05 14:04:04 +10006350 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006351 if (iterator == NULL)
6352 return NULL;
6353
6354 ncpus = NCPUS_START;
6355 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006356 cpu_set = CPU_ALLOC(ncpus);
6357 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006358 PyErr_NoMemory();
6359 goto error;
6360 }
Larry Hastings2f936352014-08-05 14:04:04 +10006361 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006362
6363 while ((item = PyIter_Next(iterator))) {
6364 long cpu;
6365 if (!PyLong_Check(item)) {
6366 PyErr_Format(PyExc_TypeError,
6367 "expected an iterator of ints, "
6368 "but iterator yielded %R",
6369 Py_TYPE(item));
6370 Py_DECREF(item);
6371 goto error;
6372 }
6373 cpu = PyLong_AsLong(item);
6374 Py_DECREF(item);
6375 if (cpu < 0) {
6376 if (!PyErr_Occurred())
6377 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6378 goto error;
6379 }
6380 if (cpu > INT_MAX - 1) {
6381 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6382 goto error;
6383 }
6384 if (cpu >= ncpus) {
6385 /* Grow CPU mask to fit the CPU number */
6386 int newncpus = ncpus;
6387 cpu_set_t *newmask;
6388 size_t newsetsize;
6389 while (newncpus <= cpu) {
6390 if (newncpus > INT_MAX / 2)
6391 newncpus = cpu + 1;
6392 else
6393 newncpus = newncpus * 2;
6394 }
6395 newmask = CPU_ALLOC(newncpus);
6396 if (newmask == NULL) {
6397 PyErr_NoMemory();
6398 goto error;
6399 }
6400 newsetsize = CPU_ALLOC_SIZE(newncpus);
6401 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006402 memcpy(newmask, cpu_set, setsize);
6403 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006404 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006405 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006406 ncpus = newncpus;
6407 }
Larry Hastings2f936352014-08-05 14:04:04 +10006408 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006409 }
6410 Py_CLEAR(iterator);
6411
Larry Hastings2f936352014-08-05 14:04:04 +10006412 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006413 posix_error();
6414 goto error;
6415 }
Larry Hastings2f936352014-08-05 14:04:04 +10006416 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006417 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006418
6419error:
Larry Hastings2f936352014-08-05 14:04:04 +10006420 if (cpu_set)
6421 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006422 Py_XDECREF(iterator);
6423 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006424}
6425
Larry Hastings2f936352014-08-05 14:04:04 +10006426
6427/*[clinic input]
6428os.sched_getaffinity
6429 pid: pid_t
6430 /
6431
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006432Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006433
6434The affinity is returned as a set of CPU identifiers.
6435[clinic start generated code]*/
6436
Larry Hastings2f936352014-08-05 14:04:04 +10006437static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006438os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006439/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006440{
Antoine Pitrou84869872012-08-04 16:16:35 +02006441 int cpu, ncpus, count;
6442 size_t setsize;
6443 cpu_set_t *mask = NULL;
6444 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006445
Antoine Pitrou84869872012-08-04 16:16:35 +02006446 ncpus = NCPUS_START;
6447 while (1) {
6448 setsize = CPU_ALLOC_SIZE(ncpus);
6449 mask = CPU_ALLOC(ncpus);
6450 if (mask == NULL)
6451 return PyErr_NoMemory();
6452 if (sched_getaffinity(pid, setsize, mask) == 0)
6453 break;
6454 CPU_FREE(mask);
6455 if (errno != EINVAL)
6456 return posix_error();
6457 if (ncpus > INT_MAX / 2) {
6458 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6459 "a large enough CPU set");
6460 return NULL;
6461 }
6462 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006463 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006464
6465 res = PySet_New(NULL);
6466 if (res == NULL)
6467 goto error;
6468 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6469 if (CPU_ISSET_S(cpu, setsize, mask)) {
6470 PyObject *cpu_num = PyLong_FromLong(cpu);
6471 --count;
6472 if (cpu_num == NULL)
6473 goto error;
6474 if (PySet_Add(res, cpu_num)) {
6475 Py_DECREF(cpu_num);
6476 goto error;
6477 }
6478 Py_DECREF(cpu_num);
6479 }
6480 }
6481 CPU_FREE(mask);
6482 return res;
6483
6484error:
6485 if (mask)
6486 CPU_FREE(mask);
6487 Py_XDECREF(res);
6488 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006489}
6490
Benjamin Peterson2740af82011-08-02 17:41:34 -05006491#endif /* HAVE_SCHED_SETAFFINITY */
6492
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006493#endif /* HAVE_SCHED_H */
6494
Larry Hastings2f936352014-08-05 14:04:04 +10006495
Neal Norwitzb59798b2003-03-21 01:43:31 +00006496/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006497/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6498#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006499#define DEV_PTY_FILE "/dev/ptc"
6500#define HAVE_DEV_PTMX
6501#else
6502#define DEV_PTY_FILE "/dev/ptmx"
6503#endif
6504
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006505#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006506#ifdef HAVE_PTY_H
6507#include <pty.h>
6508#else
6509#ifdef HAVE_LIBUTIL_H
6510#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006511#else
6512#ifdef HAVE_UTIL_H
6513#include <util.h>
6514#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006515#endif /* HAVE_LIBUTIL_H */
6516#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006517#ifdef HAVE_STROPTS_H
6518#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006519#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006520#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006521
Larry Hastings2f936352014-08-05 14:04:04 +10006522
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006523#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006524/*[clinic input]
6525os.openpty
6526
6527Open a pseudo-terminal.
6528
6529Return a tuple of (master_fd, slave_fd) containing open file descriptors
6530for both the master and slave ends.
6531[clinic start generated code]*/
6532
Larry Hastings2f936352014-08-05 14:04:04 +10006533static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006534os_openpty_impl(PyObject *module)
6535/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006536{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006537 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006538#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006540#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006541#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006543#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006545#endif
6546#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006547
Thomas Wouters70c21a12000-07-14 14:28:33 +00006548#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006550 goto posix_error;
6551
6552 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6553 goto error;
6554 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6555 goto error;
6556
Neal Norwitzb59798b2003-03-21 01:43:31 +00006557#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006558 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6559 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006560 goto posix_error;
6561 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6562 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006563
Victor Stinnerdaf45552013-08-28 00:53:59 +02006564 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006566 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006567
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006568#else
Victor Stinner000de532013-11-25 23:19:58 +01006569 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006571 goto posix_error;
6572
Victor Stinner8c62be82010-05-06 00:08:46 +00006573 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006574
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 /* change permission of slave */
6576 if (grantpt(master_fd) < 0) {
6577 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006578 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006579 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006580
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 /* unlock slave */
6582 if (unlockpt(master_fd) < 0) {
6583 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006584 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006586
Victor Stinner8c62be82010-05-06 00:08:46 +00006587 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006588
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 slave_name = ptsname(master_fd); /* get name of slave */
6590 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006591 goto posix_error;
6592
6593 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006594 if (slave_fd == -1)
6595 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006596
6597 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6598 goto posix_error;
6599
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006600#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6602 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006603#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006605#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006606#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006607#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006608
Victor Stinner8c62be82010-05-06 00:08:46 +00006609 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006610
Victor Stinnerdaf45552013-08-28 00:53:59 +02006611posix_error:
6612 posix_error();
6613error:
6614 if (master_fd != -1)
6615 close(master_fd);
6616 if (slave_fd != -1)
6617 close(slave_fd);
6618 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006619}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006620#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006621
Larry Hastings2f936352014-08-05 14:04:04 +10006622
Fred Drake8cef4cf2000-06-28 16:40:38 +00006623#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006624/*[clinic input]
6625os.forkpty
6626
6627Fork a new process with a new pseudo-terminal as controlling tty.
6628
6629Returns a tuple of (pid, master_fd).
6630Like fork(), return pid of 0 to the child process,
6631and pid of child to the parent process.
6632To both, return fd of newly opened pseudo-terminal.
6633[clinic start generated code]*/
6634
Larry Hastings2f936352014-08-05 14:04:04 +10006635static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006636os_forkpty_impl(PyObject *module)
6637/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006638{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006639 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006640 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006641
Eric Snow59032962018-09-14 14:17:20 -07006642 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6643 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6644 return NULL;
6645 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006646 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006647 pid = forkpty(&master_fd, NULL, NULL, NULL);
6648 if (pid == 0) {
6649 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006650 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006651 } else {
6652 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006653 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006654 }
6655 if (pid == -1)
6656 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006657 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006658}
Larry Hastings2f936352014-08-05 14:04:04 +10006659#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006660
Ross Lagerwall7807c352011-03-17 20:20:30 +02006661
Guido van Rossumad0ee831995-03-01 10:34:45 +00006662#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006663/*[clinic input]
6664os.getegid
6665
6666Return the current process's effective group id.
6667[clinic start generated code]*/
6668
Larry Hastings2f936352014-08-05 14:04:04 +10006669static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006670os_getegid_impl(PyObject *module)
6671/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006672{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006673 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006674}
Larry Hastings2f936352014-08-05 14:04:04 +10006675#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006676
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006677
Guido van Rossumad0ee831995-03-01 10:34:45 +00006678#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006679/*[clinic input]
6680os.geteuid
6681
6682Return the current process's effective user id.
6683[clinic start generated code]*/
6684
Larry Hastings2f936352014-08-05 14:04:04 +10006685static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006686os_geteuid_impl(PyObject *module)
6687/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006688{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006689 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006690}
Larry Hastings2f936352014-08-05 14:04:04 +10006691#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006692
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006693
Guido van Rossumad0ee831995-03-01 10:34:45 +00006694#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006695/*[clinic input]
6696os.getgid
6697
6698Return the current process's group id.
6699[clinic start generated code]*/
6700
Larry Hastings2f936352014-08-05 14:04:04 +10006701static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006702os_getgid_impl(PyObject *module)
6703/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006704{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006705 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006706}
Larry Hastings2f936352014-08-05 14:04:04 +10006707#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006708
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006709
Berker Peksag39404992016-09-15 20:45:16 +03006710#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006711/*[clinic input]
6712os.getpid
6713
6714Return the current process id.
6715[clinic start generated code]*/
6716
Larry Hastings2f936352014-08-05 14:04:04 +10006717static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006718os_getpid_impl(PyObject *module)
6719/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006720{
Victor Stinner8c62be82010-05-06 00:08:46 +00006721 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006722}
Berker Peksag39404992016-09-15 20:45:16 +03006723#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006724
Miss Islington (bot)c80183e2019-06-13 00:27:23 -07006725#ifdef NGROUPS_MAX
6726#define MAX_GROUPS NGROUPS_MAX
6727#else
6728 /* defined to be 16 on Solaris7, so this should be a small number */
6729#define MAX_GROUPS 64
6730#endif
6731
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006732#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006733
6734/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006735PyDoc_STRVAR(posix_getgrouplist__doc__,
6736"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6737Returns a list of groups to which a user belongs.\n\n\
6738 user: username to lookup\n\
6739 group: base group id of the user");
6740
6741static PyObject *
6742posix_getgrouplist(PyObject *self, PyObject *args)
6743{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006744 const char *user;
6745 int i, ngroups;
6746 PyObject *list;
6747#ifdef __APPLE__
6748 int *groups, basegid;
6749#else
6750 gid_t *groups, basegid;
6751#endif
Miss Islington (bot)c80183e2019-06-13 00:27:23 -07006752
6753 /*
6754 * NGROUPS_MAX is defined by POSIX.1 as the maximum
6755 * number of supplimental groups a users can belong to.
6756 * We have to increment it by one because
6757 * getgrouplist() returns both the supplemental groups
6758 * and the primary group, i.e. all of the groups the
6759 * user belongs to.
6760 */
6761 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006762
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006763#ifdef __APPLE__
6764 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006765 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006766#else
6767 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6768 _Py_Gid_Converter, &basegid))
6769 return NULL;
6770#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006771
6772#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006773 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006774#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006775 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006776#endif
6777 if (groups == NULL)
6778 return PyErr_NoMemory();
6779
6780 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6781 PyMem_Del(groups);
6782 return posix_error();
6783 }
6784
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006785#ifdef _Py_MEMORY_SANITIZER
6786 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6787 __msan_unpoison(&ngroups, sizeof(ngroups));
6788 __msan_unpoison(groups, ngroups*sizeof(*groups));
6789#endif
6790
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006791 list = PyList_New(ngroups);
6792 if (list == NULL) {
6793 PyMem_Del(groups);
6794 return NULL;
6795 }
6796
6797 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006798#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006799 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006800#else
6801 PyObject *o = _PyLong_FromGid(groups[i]);
6802#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006803 if (o == NULL) {
6804 Py_DECREF(list);
6805 PyMem_Del(groups);
6806 return NULL;
6807 }
6808 PyList_SET_ITEM(list, i, o);
6809 }
6810
6811 PyMem_Del(groups);
6812
6813 return list;
6814}
Larry Hastings2f936352014-08-05 14:04:04 +10006815#endif /* HAVE_GETGROUPLIST */
6816
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006817
Fred Drakec9680921999-12-13 16:37:25 +00006818#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006819/*[clinic input]
6820os.getgroups
6821
6822Return list of supplemental group IDs for the process.
6823[clinic start generated code]*/
6824
Larry Hastings2f936352014-08-05 14:04:04 +10006825static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006826os_getgroups_impl(PyObject *module)
6827/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006828{
6829 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006831
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006832 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006833 * This is a helper variable to store the intermediate result when
6834 * that happens.
6835 *
6836 * To keep the code readable the OSX behaviour is unconditional,
6837 * according to the POSIX spec this should be safe on all unix-y
6838 * systems.
6839 */
6840 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006842
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006843#ifdef __APPLE__
6844 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6845 * there are more groups than can fit in grouplist. Therefore, on OS X
6846 * always first call getgroups with length 0 to get the actual number
6847 * of groups.
6848 */
6849 n = getgroups(0, NULL);
6850 if (n < 0) {
6851 return posix_error();
6852 } else if (n <= MAX_GROUPS) {
6853 /* groups will fit in existing array */
6854 alt_grouplist = grouplist;
6855 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006856 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006857 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006858 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006859 }
6860 }
6861
6862 n = getgroups(n, alt_grouplist);
6863 if (n == -1) {
6864 if (alt_grouplist != grouplist) {
6865 PyMem_Free(alt_grouplist);
6866 }
6867 return posix_error();
6868 }
6869#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006871 if (n < 0) {
6872 if (errno == EINVAL) {
6873 n = getgroups(0, NULL);
6874 if (n == -1) {
6875 return posix_error();
6876 }
6877 if (n == 0) {
6878 /* Avoid malloc(0) */
6879 alt_grouplist = grouplist;
6880 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006881 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006882 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006883 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006884 }
6885 n = getgroups(n, alt_grouplist);
6886 if (n == -1) {
6887 PyMem_Free(alt_grouplist);
6888 return posix_error();
6889 }
6890 }
6891 } else {
6892 return posix_error();
6893 }
6894 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006895#endif
6896
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006897 result = PyList_New(n);
6898 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006899 int i;
6900 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006901 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006902 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006903 Py_DECREF(result);
6904 result = NULL;
6905 break;
Fred Drakec9680921999-12-13 16:37:25 +00006906 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006908 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006909 }
6910
6911 if (alt_grouplist != grouplist) {
6912 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006914
Fred Drakec9680921999-12-13 16:37:25 +00006915 return result;
6916}
Larry Hastings2f936352014-08-05 14:04:04 +10006917#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006918
Antoine Pitroub7572f02009-12-02 20:46:48 +00006919#ifdef HAVE_INITGROUPS
6920PyDoc_STRVAR(posix_initgroups__doc__,
6921"initgroups(username, gid) -> None\n\n\
6922Call the system initgroups() to initialize the group access list with all of\n\
6923the groups of which the specified username is a member, plus the specified\n\
6924group id.");
6925
Larry Hastings2f936352014-08-05 14:04:04 +10006926/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006927static PyObject *
6928posix_initgroups(PyObject *self, PyObject *args)
6929{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006930 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006931 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006932 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006933#ifdef __APPLE__
6934 int gid;
6935#else
6936 gid_t gid;
6937#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006938
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006939#ifdef __APPLE__
6940 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6941 PyUnicode_FSConverter, &oname,
6942 &gid))
6943#else
6944 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6945 PyUnicode_FSConverter, &oname,
6946 _Py_Gid_Converter, &gid))
6947#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006948 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006949 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006950
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006951 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006952 Py_DECREF(oname);
6953 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006954 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006955
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006956 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006957}
Larry Hastings2f936352014-08-05 14:04:04 +10006958#endif /* HAVE_INITGROUPS */
6959
Antoine Pitroub7572f02009-12-02 20:46:48 +00006960
Martin v. Löwis606edc12002-06-13 21:09:11 +00006961#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006962/*[clinic input]
6963os.getpgid
6964
6965 pid: pid_t
6966
6967Call the system call getpgid(), and return the result.
6968[clinic start generated code]*/
6969
Larry Hastings2f936352014-08-05 14:04:04 +10006970static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006971os_getpgid_impl(PyObject *module, pid_t pid)
6972/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006973{
6974 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006975 if (pgid < 0)
6976 return posix_error();
6977 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006978}
6979#endif /* HAVE_GETPGID */
6980
6981
Guido van Rossumb6775db1994-08-01 11:34:53 +00006982#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006983/*[clinic input]
6984os.getpgrp
6985
6986Return the current process group id.
6987[clinic start generated code]*/
6988
Larry Hastings2f936352014-08-05 14:04:04 +10006989static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006990os_getpgrp_impl(PyObject *module)
6991/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006992{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006993#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006995#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006996 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006997#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006998}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006999#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007000
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007001
Guido van Rossumb6775db1994-08-01 11:34:53 +00007002#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007003/*[clinic input]
7004os.setpgrp
7005
7006Make the current process the leader of its process group.
7007[clinic start generated code]*/
7008
Larry Hastings2f936352014-08-05 14:04:04 +10007009static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007010os_setpgrp_impl(PyObject *module)
7011/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007012{
Guido van Rossum64933891994-10-20 21:56:42 +00007013#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007014 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007015#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007017#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007019 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007020}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007021#endif /* HAVE_SETPGRP */
7022
Guido van Rossumad0ee831995-03-01 10:34:45 +00007023#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007024
7025#ifdef MS_WINDOWS
7026#include <tlhelp32.h>
7027
7028static PyObject*
7029win32_getppid()
7030{
7031 HANDLE snapshot;
7032 pid_t mypid;
7033 PyObject* result = NULL;
7034 BOOL have_record;
7035 PROCESSENTRY32 pe;
7036
7037 mypid = getpid(); /* This function never fails */
7038
7039 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7040 if (snapshot == INVALID_HANDLE_VALUE)
7041 return PyErr_SetFromWindowsErr(GetLastError());
7042
7043 pe.dwSize = sizeof(pe);
7044 have_record = Process32First(snapshot, &pe);
7045 while (have_record) {
7046 if (mypid == (pid_t)pe.th32ProcessID) {
7047 /* We could cache the ulong value in a static variable. */
7048 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7049 break;
7050 }
7051
7052 have_record = Process32Next(snapshot, &pe);
7053 }
7054
7055 /* If our loop exits and our pid was not found (result will be NULL)
7056 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7057 * error anyway, so let's raise it. */
7058 if (!result)
7059 result = PyErr_SetFromWindowsErr(GetLastError());
7060
7061 CloseHandle(snapshot);
7062
7063 return result;
7064}
7065#endif /*MS_WINDOWS*/
7066
Larry Hastings2f936352014-08-05 14:04:04 +10007067
7068/*[clinic input]
7069os.getppid
7070
7071Return the parent's process id.
7072
7073If the parent process has already exited, Windows machines will still
7074return its id; others systems will return the id of the 'init' process (1).
7075[clinic start generated code]*/
7076
Larry Hastings2f936352014-08-05 14:04:04 +10007077static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007078os_getppid_impl(PyObject *module)
7079/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007080{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007081#ifdef MS_WINDOWS
7082 return win32_getppid();
7083#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007085#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007086}
7087#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007088
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007089
Fred Drake12c6e2d1999-12-14 21:25:03 +00007090#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007091/*[clinic input]
7092os.getlogin
7093
7094Return the actual login name.
7095[clinic start generated code]*/
7096
Larry Hastings2f936352014-08-05 14:04:04 +10007097static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007098os_getlogin_impl(PyObject *module)
7099/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007100{
Victor Stinner8c62be82010-05-06 00:08:46 +00007101 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007102#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007103 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007104 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007105
7106 if (GetUserNameW(user_name, &num_chars)) {
7107 /* num_chars is the number of unicode chars plus null terminator */
7108 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007109 }
7110 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007111 result = PyErr_SetFromWindowsErr(GetLastError());
7112#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007113 char *name;
7114 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007115
Victor Stinner8c62be82010-05-06 00:08:46 +00007116 errno = 0;
7117 name = getlogin();
7118 if (name == NULL) {
7119 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007120 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007121 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007122 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007123 }
7124 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007125 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007126 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007127#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007128 return result;
7129}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007130#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007131
Larry Hastings2f936352014-08-05 14:04:04 +10007132
Guido van Rossumad0ee831995-03-01 10:34:45 +00007133#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007134/*[clinic input]
7135os.getuid
7136
7137Return the current process's user id.
7138[clinic start generated code]*/
7139
Larry Hastings2f936352014-08-05 14:04:04 +10007140static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007141os_getuid_impl(PyObject *module)
7142/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007143{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007144 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007145}
Larry Hastings2f936352014-08-05 14:04:04 +10007146#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007147
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007148
Brian Curtineb24d742010-04-12 17:16:38 +00007149#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007150#define HAVE_KILL
7151#endif /* MS_WINDOWS */
7152
7153#ifdef HAVE_KILL
7154/*[clinic input]
7155os.kill
7156
7157 pid: pid_t
7158 signal: Py_ssize_t
7159 /
7160
7161Kill a process with a signal.
7162[clinic start generated code]*/
7163
Larry Hastings2f936352014-08-05 14:04:04 +10007164static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007165os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7166/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007167#ifndef MS_WINDOWS
7168{
7169 if (kill(pid, (int)signal) == -1)
7170 return posix_error();
7171 Py_RETURN_NONE;
7172}
7173#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00007174{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007175 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007176 DWORD sig = (DWORD)signal;
7177 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007178 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007179
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 /* Console processes which share a common console can be sent CTRL+C or
7181 CTRL+BREAK events, provided they handle said events. */
7182 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007183 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007184 err = GetLastError();
7185 PyErr_SetFromWindowsErr(err);
7186 }
7187 else
7188 Py_RETURN_NONE;
7189 }
Brian Curtineb24d742010-04-12 17:16:38 +00007190
Victor Stinner8c62be82010-05-06 00:08:46 +00007191 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7192 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007193 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007194 if (handle == NULL) {
7195 err = GetLastError();
7196 return PyErr_SetFromWindowsErr(err);
7197 }
Brian Curtineb24d742010-04-12 17:16:38 +00007198
Victor Stinner8c62be82010-05-06 00:08:46 +00007199 if (TerminateProcess(handle, sig) == 0) {
7200 err = GetLastError();
7201 result = PyErr_SetFromWindowsErr(err);
7202 } else {
7203 Py_INCREF(Py_None);
7204 result = Py_None;
7205 }
Brian Curtineb24d742010-04-12 17:16:38 +00007206
Victor Stinner8c62be82010-05-06 00:08:46 +00007207 CloseHandle(handle);
7208 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00007209}
Larry Hastings2f936352014-08-05 14:04:04 +10007210#endif /* !MS_WINDOWS */
7211#endif /* HAVE_KILL */
7212
7213
7214#ifdef HAVE_KILLPG
7215/*[clinic input]
7216os.killpg
7217
7218 pgid: pid_t
7219 signal: int
7220 /
7221
7222Kill a process group with a signal.
7223[clinic start generated code]*/
7224
Larry Hastings2f936352014-08-05 14:04:04 +10007225static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007226os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7227/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007228{
7229 /* XXX some man pages make the `pgid` parameter an int, others
7230 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7231 take the same type. Moreover, pid_t is always at least as wide as
7232 int (else compilation of this module fails), which is safe. */
7233 if (killpg(pgid, signal) == -1)
7234 return posix_error();
7235 Py_RETURN_NONE;
7236}
7237#endif /* HAVE_KILLPG */
7238
Brian Curtineb24d742010-04-12 17:16:38 +00007239
Guido van Rossumc0125471996-06-28 18:55:32 +00007240#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007241#ifdef HAVE_SYS_LOCK_H
7242#include <sys/lock.h>
7243#endif
7244
Larry Hastings2f936352014-08-05 14:04:04 +10007245/*[clinic input]
7246os.plock
7247 op: int
7248 /
7249
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007250Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007251[clinic start generated code]*/
7252
Larry Hastings2f936352014-08-05 14:04:04 +10007253static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007254os_plock_impl(PyObject *module, int op)
7255/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007256{
Victor Stinner8c62be82010-05-06 00:08:46 +00007257 if (plock(op) == -1)
7258 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007259 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007260}
Larry Hastings2f936352014-08-05 14:04:04 +10007261#endif /* HAVE_PLOCK */
7262
Guido van Rossumc0125471996-06-28 18:55:32 +00007263
Guido van Rossumb6775db1994-08-01 11:34:53 +00007264#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007265/*[clinic input]
7266os.setuid
7267
7268 uid: uid_t
7269 /
7270
7271Set the current process's user id.
7272[clinic start generated code]*/
7273
Larry Hastings2f936352014-08-05 14:04:04 +10007274static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007275os_setuid_impl(PyObject *module, uid_t uid)
7276/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007277{
Victor Stinner8c62be82010-05-06 00:08:46 +00007278 if (setuid(uid) < 0)
7279 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007280 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007281}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007282#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007283
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007284
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007285#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007286/*[clinic input]
7287os.seteuid
7288
7289 euid: uid_t
7290 /
7291
7292Set the current process's effective user id.
7293[clinic start generated code]*/
7294
Larry Hastings2f936352014-08-05 14:04:04 +10007295static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007296os_seteuid_impl(PyObject *module, uid_t euid)
7297/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007298{
7299 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007300 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007301 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007302}
7303#endif /* HAVE_SETEUID */
7304
Larry Hastings2f936352014-08-05 14:04:04 +10007305
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007306#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007307/*[clinic input]
7308os.setegid
7309
7310 egid: gid_t
7311 /
7312
7313Set the current process's effective group id.
7314[clinic start generated code]*/
7315
Larry Hastings2f936352014-08-05 14:04:04 +10007316static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007317os_setegid_impl(PyObject *module, gid_t egid)
7318/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007319{
7320 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007321 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007322 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007323}
7324#endif /* HAVE_SETEGID */
7325
Larry Hastings2f936352014-08-05 14:04:04 +10007326
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007327#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007328/*[clinic input]
7329os.setreuid
7330
7331 ruid: uid_t
7332 euid: uid_t
7333 /
7334
7335Set the current process's real and effective user ids.
7336[clinic start generated code]*/
7337
Larry Hastings2f936352014-08-05 14:04:04 +10007338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007339os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7340/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007341{
Victor Stinner8c62be82010-05-06 00:08:46 +00007342 if (setreuid(ruid, euid) < 0) {
7343 return posix_error();
7344 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007345 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007346 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007347}
7348#endif /* HAVE_SETREUID */
7349
Larry Hastings2f936352014-08-05 14:04:04 +10007350
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007351#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007352/*[clinic input]
7353os.setregid
7354
7355 rgid: gid_t
7356 egid: gid_t
7357 /
7358
7359Set the current process's real and effective group ids.
7360[clinic start generated code]*/
7361
Larry Hastings2f936352014-08-05 14:04:04 +10007362static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007363os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7364/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007365{
7366 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007367 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007368 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007369}
7370#endif /* HAVE_SETREGID */
7371
Larry Hastings2f936352014-08-05 14:04:04 +10007372
Guido van Rossumb6775db1994-08-01 11:34:53 +00007373#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007374/*[clinic input]
7375os.setgid
7376 gid: gid_t
7377 /
7378
7379Set the current process's group id.
7380[clinic start generated code]*/
7381
Larry Hastings2f936352014-08-05 14:04:04 +10007382static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007383os_setgid_impl(PyObject *module, gid_t gid)
7384/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007385{
Victor Stinner8c62be82010-05-06 00:08:46 +00007386 if (setgid(gid) < 0)
7387 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007388 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007389}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007390#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007391
Larry Hastings2f936352014-08-05 14:04:04 +10007392
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007393#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007394/*[clinic input]
7395os.setgroups
7396
7397 groups: object
7398 /
7399
7400Set the groups of the current process to list.
7401[clinic start generated code]*/
7402
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007403static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007404os_setgroups(PyObject *module, PyObject *groups)
7405/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007406{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007407 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007408 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007409
Victor Stinner8c62be82010-05-06 00:08:46 +00007410 if (!PySequence_Check(groups)) {
7411 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7412 return NULL;
7413 }
7414 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007415 if (len < 0) {
7416 return NULL;
7417 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007418 if (len > MAX_GROUPS) {
7419 PyErr_SetString(PyExc_ValueError, "too many groups");
7420 return NULL;
7421 }
7422 for(i = 0; i < len; i++) {
7423 PyObject *elem;
7424 elem = PySequence_GetItem(groups, i);
7425 if (!elem)
7426 return NULL;
7427 if (!PyLong_Check(elem)) {
7428 PyErr_SetString(PyExc_TypeError,
7429 "groups must be integers");
7430 Py_DECREF(elem);
7431 return NULL;
7432 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007433 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007434 Py_DECREF(elem);
7435 return NULL;
7436 }
7437 }
7438 Py_DECREF(elem);
7439 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007440
Victor Stinner8c62be82010-05-06 00:08:46 +00007441 if (setgroups(len, grouplist) < 0)
7442 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007443 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007444}
7445#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007446
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007447#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7448static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007449wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007450{
Victor Stinner8c62be82010-05-06 00:08:46 +00007451 PyObject *result;
7452 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007453 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007454
Victor Stinner8c62be82010-05-06 00:08:46 +00007455 if (pid == -1)
7456 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007457
Victor Stinner8c62be82010-05-06 00:08:46 +00007458 if (struct_rusage == NULL) {
7459 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7460 if (m == NULL)
7461 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007462 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007463 Py_DECREF(m);
7464 if (struct_rusage == NULL)
7465 return NULL;
7466 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007467
Victor Stinner8c62be82010-05-06 00:08:46 +00007468 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7469 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7470 if (!result)
7471 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007472
7473#ifndef doubletime
7474#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7475#endif
7476
Victor Stinner8c62be82010-05-06 00:08:46 +00007477 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007478 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007479 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007480 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007481#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007482 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7483 SET_INT(result, 2, ru->ru_maxrss);
7484 SET_INT(result, 3, ru->ru_ixrss);
7485 SET_INT(result, 4, ru->ru_idrss);
7486 SET_INT(result, 5, ru->ru_isrss);
7487 SET_INT(result, 6, ru->ru_minflt);
7488 SET_INT(result, 7, ru->ru_majflt);
7489 SET_INT(result, 8, ru->ru_nswap);
7490 SET_INT(result, 9, ru->ru_inblock);
7491 SET_INT(result, 10, ru->ru_oublock);
7492 SET_INT(result, 11, ru->ru_msgsnd);
7493 SET_INT(result, 12, ru->ru_msgrcv);
7494 SET_INT(result, 13, ru->ru_nsignals);
7495 SET_INT(result, 14, ru->ru_nvcsw);
7496 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007497#undef SET_INT
7498
Victor Stinner8c62be82010-05-06 00:08:46 +00007499 if (PyErr_Occurred()) {
7500 Py_DECREF(result);
7501 return NULL;
7502 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007503
Victor Stinner8c62be82010-05-06 00:08:46 +00007504 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007505}
7506#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7507
Larry Hastings2f936352014-08-05 14:04:04 +10007508
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007509#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007510/*[clinic input]
7511os.wait3
7512
7513 options: int
7514Wait for completion of a child process.
7515
7516Returns a tuple of information about the child process:
7517 (pid, status, rusage)
7518[clinic start generated code]*/
7519
Larry Hastings2f936352014-08-05 14:04:04 +10007520static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007521os_wait3_impl(PyObject *module, int options)
7522/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007523{
Victor Stinner8c62be82010-05-06 00:08:46 +00007524 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007525 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007526 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007527 WAIT_TYPE status;
7528 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007529
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007530 do {
7531 Py_BEGIN_ALLOW_THREADS
7532 pid = wait3(&status, options, &ru);
7533 Py_END_ALLOW_THREADS
7534 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7535 if (pid < 0)
7536 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007537
Victor Stinner4195b5c2012-02-08 23:03:19 +01007538 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007539}
7540#endif /* HAVE_WAIT3 */
7541
Larry Hastings2f936352014-08-05 14:04:04 +10007542
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007543#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007544/*[clinic input]
7545
7546os.wait4
7547
7548 pid: pid_t
7549 options: int
7550
7551Wait for completion of a specific child process.
7552
7553Returns a tuple of information about the child process:
7554 (pid, status, rusage)
7555[clinic start generated code]*/
7556
Larry Hastings2f936352014-08-05 14:04:04 +10007557static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007558os_wait4_impl(PyObject *module, pid_t pid, int options)
7559/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007560{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007561 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007563 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007564 WAIT_TYPE status;
7565 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007566
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007567 do {
7568 Py_BEGIN_ALLOW_THREADS
7569 res = wait4(pid, &status, options, &ru);
7570 Py_END_ALLOW_THREADS
7571 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7572 if (res < 0)
7573 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007574
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007575 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007576}
7577#endif /* HAVE_WAIT4 */
7578
Larry Hastings2f936352014-08-05 14:04:04 +10007579
Ross Lagerwall7807c352011-03-17 20:20:30 +02007580#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007581/*[clinic input]
7582os.waitid
7583
7584 idtype: idtype_t
7585 Must be one of be P_PID, P_PGID or P_ALL.
7586 id: id_t
7587 The id to wait on.
7588 options: int
7589 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7590 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7591 /
7592
7593Returns the result of waiting for a process or processes.
7594
7595Returns either waitid_result or None if WNOHANG is specified and there are
7596no children in a waitable state.
7597[clinic start generated code]*/
7598
Larry Hastings2f936352014-08-05 14:04:04 +10007599static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007600os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7601/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007602{
7603 PyObject *result;
7604 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007605 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007606 siginfo_t si;
7607 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007608
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007609 do {
7610 Py_BEGIN_ALLOW_THREADS
7611 res = waitid(idtype, id, &si, options);
7612 Py_END_ALLOW_THREADS
7613 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7614 if (res < 0)
7615 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007616
7617 if (si.si_pid == 0)
7618 Py_RETURN_NONE;
7619
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007620 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007621 if (!result)
7622 return NULL;
7623
7624 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007625 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007626 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7627 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7628 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7629 if (PyErr_Occurred()) {
7630 Py_DECREF(result);
7631 return NULL;
7632 }
7633
7634 return result;
7635}
Larry Hastings2f936352014-08-05 14:04:04 +10007636#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007637
Larry Hastings2f936352014-08-05 14:04:04 +10007638
7639#if defined(HAVE_WAITPID)
7640/*[clinic input]
7641os.waitpid
7642 pid: pid_t
7643 options: int
7644 /
7645
7646Wait for completion of a given child process.
7647
7648Returns a tuple of information regarding the child process:
7649 (pid, status)
7650
7651The options argument is ignored on Windows.
7652[clinic start generated code]*/
7653
Larry Hastings2f936352014-08-05 14:04:04 +10007654static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007655os_waitpid_impl(PyObject *module, pid_t pid, int options)
7656/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007657{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007658 pid_t res;
7659 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007660 WAIT_TYPE status;
7661 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007662
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007663 do {
7664 Py_BEGIN_ALLOW_THREADS
7665 res = waitpid(pid, &status, options);
7666 Py_END_ALLOW_THREADS
7667 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7668 if (res < 0)
7669 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007670
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007671 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007672}
Tim Petersab034fa2002-02-01 11:27:43 +00007673#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007674/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007675/*[clinic input]
7676os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007677 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007678 options: int
7679 /
7680
7681Wait for completion of a given process.
7682
7683Returns a tuple of information regarding the process:
7684 (pid, status << 8)
7685
7686The options argument is ignored on Windows.
7687[clinic start generated code]*/
7688
Larry Hastings2f936352014-08-05 14:04:04 +10007689static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007690os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007691/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007692{
7693 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007694 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007695 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007696
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007697 do {
7698 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007699 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007700 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007701 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007702 Py_END_ALLOW_THREADS
7703 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007704 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007705 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007706
Victor Stinner8c62be82010-05-06 00:08:46 +00007707 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007708 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007709}
Larry Hastings2f936352014-08-05 14:04:04 +10007710#endif
7711
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007712
Guido van Rossumad0ee831995-03-01 10:34:45 +00007713#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007714/*[clinic input]
7715os.wait
7716
7717Wait for completion of a child process.
7718
7719Returns a tuple of information about the child process:
7720 (pid, status)
7721[clinic start generated code]*/
7722
Larry Hastings2f936352014-08-05 14:04:04 +10007723static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007724os_wait_impl(PyObject *module)
7725/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007726{
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007728 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007729 WAIT_TYPE status;
7730 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007731
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007732 do {
7733 Py_BEGIN_ALLOW_THREADS
7734 pid = wait(&status);
7735 Py_END_ALLOW_THREADS
7736 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7737 if (pid < 0)
7738 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007739
Victor Stinner8c62be82010-05-06 00:08:46 +00007740 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007741}
Larry Hastings2f936352014-08-05 14:04:04 +10007742#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007743
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007744
Larry Hastings9cf065c2012-06-22 16:30:09 -07007745#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007746/*[clinic input]
7747os.readlink
7748
7749 path: path_t
7750 *
7751 dir_fd: dir_fd(requires='readlinkat') = None
7752
7753Return a string representing the path to which the symbolic link points.
7754
7755If dir_fd is not None, it should be a file descriptor open to a directory,
7756and path should be relative; path will then be relative to that directory.
7757
7758dir_fd may not be implemented on your platform. If it is unavailable,
7759using it will raise a NotImplementedError.
7760[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007761
Barry Warsaw53699e91996-12-10 23:23:01 +00007762static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007763os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7764/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007765{
Berker Peksage0b5b202018-08-15 13:03:41 +03007766#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007767 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007768 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007769
7770 Py_BEGIN_ALLOW_THREADS
7771#ifdef HAVE_READLINKAT
7772 if (dir_fd != DEFAULT_DIR_FD)
7773 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7774 else
7775#endif
7776 length = readlink(path->narrow, buffer, MAXPATHLEN);
7777 Py_END_ALLOW_THREADS
7778
7779 if (length < 0) {
7780 return path_error(path);
7781 }
7782 buffer[length] = '\0';
7783
7784 if (PyUnicode_Check(path->object))
7785 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7786 else
7787 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007788#elif defined(MS_WINDOWS)
7789 DWORD n_bytes_returned;
7790 DWORD io_result;
7791 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007792 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7793 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
7794 const wchar_t *print_name;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007795 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007796
Larry Hastings2f936352014-08-05 14:04:04 +10007797 /* First get a handle to the reparse point */
7798 Py_BEGIN_ALLOW_THREADS
7799 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007800 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007801 0,
7802 0,
7803 0,
7804 OPEN_EXISTING,
7805 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7806 0);
7807 Py_END_ALLOW_THREADS
7808
Berker Peksage0b5b202018-08-15 13:03:41 +03007809 if (reparse_point_handle == INVALID_HANDLE_VALUE) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007810 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007811 }
Larry Hastings2f936352014-08-05 14:04:04 +10007812
7813 Py_BEGIN_ALLOW_THREADS
7814 /* New call DeviceIoControl to read the reparse point */
7815 io_result = DeviceIoControl(
7816 reparse_point_handle,
7817 FSCTL_GET_REPARSE_POINT,
7818 0, 0, /* in buffer */
7819 target_buffer, sizeof(target_buffer),
7820 &n_bytes_returned,
7821 0 /* we're not using OVERLAPPED_IO */
7822 );
7823 CloseHandle(reparse_point_handle);
7824 Py_END_ALLOW_THREADS
7825
Berker Peksage0b5b202018-08-15 13:03:41 +03007826 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007827 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007828 }
Larry Hastings2f936352014-08-05 14:04:04 +10007829
7830 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7831 {
7832 PyErr_SetString(PyExc_ValueError,
7833 "not a symbolic link");
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007834 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007835 }
SSE43c34aad2018-02-13 00:10:35 +07007836 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7837 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007838
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007839 result = PyUnicode_FromWideChar(print_name,
7840 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
7841 if (path->narrow) {
7842 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Berker Peksage0b5b202018-08-15 13:03:41 +03007843 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007844 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007845#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007846}
Berker Peksage0b5b202018-08-15 13:03:41 +03007847#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007848
Larry Hastings9cf065c2012-06-22 16:30:09 -07007849#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007850
7851#if defined(MS_WINDOWS)
7852
Steve Dower6921e732018-03-05 14:26:08 -08007853/* Remove the last portion of the path - return 0 on success */
7854static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007855_dirnameW(WCHAR *path)
7856{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007857 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007858 size_t length = wcsnlen_s(path, MAX_PATH);
7859 if (length == MAX_PATH) {
7860 return -1;
7861 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007862
7863 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007864 for(ptr = path + length; ptr != path; ptr--) {
7865 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007866 break;
Steve Dower6921e732018-03-05 14:26:08 -08007867 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007868 }
7869 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007870 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007871}
7872
Victor Stinner31b3b922013-06-05 01:49:17 +02007873/* Is this path absolute? */
7874static int
7875_is_absW(const WCHAR *path)
7876{
Steve Dower6921e732018-03-05 14:26:08 -08007877 return path[0] == L'\\' || path[0] == L'/' ||
7878 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007879}
7880
Steve Dower6921e732018-03-05 14:26:08 -08007881/* join root and rest with a backslash - return 0 on success */
7882static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007883_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7884{
Victor Stinner31b3b922013-06-05 01:49:17 +02007885 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007886 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007887 }
7888
Steve Dower6921e732018-03-05 14:26:08 -08007889 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7890 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007891 }
Steve Dower6921e732018-03-05 14:26:08 -08007892
7893 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7894 return -1;
7895 }
7896
7897 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007898}
7899
Victor Stinner31b3b922013-06-05 01:49:17 +02007900/* Return True if the path at src relative to dest is a directory */
7901static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007902_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007903{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007904 WIN32_FILE_ATTRIBUTE_DATA src_info;
7905 WCHAR dest_parent[MAX_PATH];
7906 WCHAR src_resolved[MAX_PATH] = L"";
7907
7908 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007909 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7910 _dirnameW(dest_parent)) {
7911 return 0;
7912 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007913 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007914 if (_joinW(src_resolved, dest_parent, src)) {
7915 return 0;
7916 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007917 return (
7918 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7919 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7920 );
7921}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007922#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007923
Larry Hastings2f936352014-08-05 14:04:04 +10007924
7925/*[clinic input]
7926os.symlink
7927 src: path_t
7928 dst: path_t
7929 target_is_directory: bool = False
7930 *
7931 dir_fd: dir_fd(requires='symlinkat')=None
7932
7933# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7934
7935Create a symbolic link pointing to src named dst.
7936
7937target_is_directory is required on Windows if the target is to be
7938 interpreted as a directory. (On Windows, symlink requires
7939 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7940 target_is_directory is ignored on non-Windows platforms.
7941
7942If dir_fd is not None, it should be a file descriptor open to a directory,
7943 and path should be relative; path will then be relative to that directory.
7944dir_fd may not be implemented on your platform.
7945 If it is unavailable, using it will raise a NotImplementedError.
7946
7947[clinic start generated code]*/
7948
Larry Hastings2f936352014-08-05 14:04:04 +10007949static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007950os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007951 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007952/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007953{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007954#ifdef MS_WINDOWS
7955 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007956 DWORD flags = 0;
7957
7958 /* Assumed true, set to false if detected to not be available. */
7959 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007960#else
7961 int result;
7962#endif
7963
Larry Hastings9cf065c2012-06-22 16:30:09 -07007964#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007965
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007966 if (windows_has_symlink_unprivileged_flag) {
7967 /* Allow non-admin symlinks if system allows it. */
7968 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
7969 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007970
Larry Hastings9cf065c2012-06-22 16:30:09 -07007971 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007972 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007973 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
7974 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
7975 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
7976 }
7977
7978 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08007979 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007980 Py_END_ALLOW_THREADS
7981
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007982 if (windows_has_symlink_unprivileged_flag && !result &&
7983 ERROR_INVALID_PARAMETER == GetLastError()) {
7984
7985 Py_BEGIN_ALLOW_THREADS
7986 _Py_BEGIN_SUPPRESS_IPH
7987 /* This error might be caused by
7988 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
7989 Try again, and update windows_has_symlink_unprivileged_flag if we
7990 are successful this time.
7991
7992 NOTE: There is a risk of a race condition here if there are other
7993 conditions than the flag causing ERROR_INVALID_PARAMETER, and
7994 another process (or thread) changes that condition in between our
7995 calls to CreateSymbolicLink.
7996 */
7997 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
7998 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
7999 _Py_END_SUPPRESS_IPH
8000 Py_END_ALLOW_THREADS
8001
8002 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8003 windows_has_symlink_unprivileged_flag = FALSE;
8004 }
8005 }
8006
Larry Hastings2f936352014-08-05 14:04:04 +10008007 if (!result)
8008 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008009
8010#else
8011
Steve Dower6921e732018-03-05 14:26:08 -08008012 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8013 PyErr_SetString(PyExc_ValueError,
8014 "symlink: src and dst must be the same type");
8015 return NULL;
8016 }
8017
Larry Hastings9cf065c2012-06-22 16:30:09 -07008018 Py_BEGIN_ALLOW_THREADS
8019#if HAVE_SYMLINKAT
8020 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10008021 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008022 else
8023#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008024 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008025 Py_END_ALLOW_THREADS
8026
Larry Hastings2f936352014-08-05 14:04:04 +10008027 if (result)
8028 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008029#endif
8030
Larry Hastings2f936352014-08-05 14:04:04 +10008031 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008032}
8033#endif /* HAVE_SYMLINK */
8034
Larry Hastings9cf065c2012-06-22 16:30:09 -07008035
Brian Curtind40e6f72010-07-08 21:39:08 +00008036
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008037
Larry Hastings605a62d2012-06-24 04:33:36 -07008038static PyStructSequence_Field times_result_fields[] = {
8039 {"user", "user time"},
8040 {"system", "system time"},
8041 {"children_user", "user time of children"},
8042 {"children_system", "system time of children"},
8043 {"elapsed", "elapsed time since an arbitrary point in the past"},
8044 {NULL}
8045};
8046
8047PyDoc_STRVAR(times_result__doc__,
8048"times_result: Result from os.times().\n\n\
8049This object may be accessed either as a tuple of\n\
8050 (user, system, children_user, children_system, elapsed),\n\
8051or via the attributes user, system, children_user, children_system,\n\
8052and elapsed.\n\
8053\n\
8054See os.times for more information.");
8055
8056static PyStructSequence_Desc times_result_desc = {
8057 "times_result", /* name */
8058 times_result__doc__, /* doc */
8059 times_result_fields,
8060 5
8061};
8062
Eddie Elizondo474eedf2018-11-13 04:09:31 -08008063static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07008064
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008065#ifdef MS_WINDOWS
8066#define HAVE_TIMES /* mandatory, for the method table */
8067#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008068
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008069#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008070
8071static PyObject *
8072build_times_result(double user, double system,
8073 double children_user, double children_system,
8074 double elapsed)
8075{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08008076 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008077 if (value == NULL)
8078 return NULL;
8079
8080#define SET(i, field) \
8081 { \
8082 PyObject *o = PyFloat_FromDouble(field); \
8083 if (!o) { \
8084 Py_DECREF(value); \
8085 return NULL; \
8086 } \
8087 PyStructSequence_SET_ITEM(value, i, o); \
8088 } \
8089
8090 SET(0, user);
8091 SET(1, system);
8092 SET(2, children_user);
8093 SET(3, children_system);
8094 SET(4, elapsed);
8095
8096#undef SET
8097
8098 return value;
8099}
8100
Larry Hastings605a62d2012-06-24 04:33:36 -07008101
Larry Hastings2f936352014-08-05 14:04:04 +10008102#ifndef MS_WINDOWS
8103#define NEED_TICKS_PER_SECOND
8104static long ticks_per_second = -1;
8105#endif /* MS_WINDOWS */
8106
8107/*[clinic input]
8108os.times
8109
8110Return a collection containing process timing information.
8111
8112The object returned behaves like a named tuple with these fields:
8113 (utime, stime, cutime, cstime, elapsed_time)
8114All fields are floating point numbers.
8115[clinic start generated code]*/
8116
Larry Hastings2f936352014-08-05 14:04:04 +10008117static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008118os_times_impl(PyObject *module)
8119/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008120#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008121{
Victor Stinner8c62be82010-05-06 00:08:46 +00008122 FILETIME create, exit, kernel, user;
8123 HANDLE hProc;
8124 hProc = GetCurrentProcess();
8125 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8126 /* The fields of a FILETIME structure are the hi and lo part
8127 of a 64-bit value expressed in 100 nanosecond units.
8128 1e7 is one second in such units; 1e-7 the inverse.
8129 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8130 */
Larry Hastings605a62d2012-06-24 04:33:36 -07008131 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00008132 (double)(user.dwHighDateTime*429.4967296 +
8133 user.dwLowDateTime*1e-7),
8134 (double)(kernel.dwHighDateTime*429.4967296 +
8135 kernel.dwLowDateTime*1e-7),
8136 (double)0,
8137 (double)0,
8138 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008139}
Larry Hastings2f936352014-08-05 14:04:04 +10008140#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008141{
Larry Hastings2f936352014-08-05 14:04:04 +10008142
8143
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008144 struct tms t;
8145 clock_t c;
8146 errno = 0;
8147 c = times(&t);
8148 if (c == (clock_t) -1)
8149 return posix_error();
8150 return build_times_result(
8151 (double)t.tms_utime / ticks_per_second,
8152 (double)t.tms_stime / ticks_per_second,
8153 (double)t.tms_cutime / ticks_per_second,
8154 (double)t.tms_cstime / ticks_per_second,
8155 (double)c / ticks_per_second);
8156}
Larry Hastings2f936352014-08-05 14:04:04 +10008157#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008158#endif /* HAVE_TIMES */
8159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008160
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008161#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008162/*[clinic input]
8163os.getsid
8164
8165 pid: pid_t
8166 /
8167
8168Call the system call getsid(pid) and return the result.
8169[clinic start generated code]*/
8170
Larry Hastings2f936352014-08-05 14:04:04 +10008171static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008172os_getsid_impl(PyObject *module, pid_t pid)
8173/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008174{
Victor Stinner8c62be82010-05-06 00:08:46 +00008175 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008176 sid = getsid(pid);
8177 if (sid < 0)
8178 return posix_error();
8179 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008180}
8181#endif /* HAVE_GETSID */
8182
8183
Guido van Rossumb6775db1994-08-01 11:34:53 +00008184#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008185/*[clinic input]
8186os.setsid
8187
8188Call the system call setsid().
8189[clinic start generated code]*/
8190
Larry Hastings2f936352014-08-05 14:04:04 +10008191static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008192os_setsid_impl(PyObject *module)
8193/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008194{
Victor Stinner8c62be82010-05-06 00:08:46 +00008195 if (setsid() < 0)
8196 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008197 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008198}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008199#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008200
Larry Hastings2f936352014-08-05 14:04:04 +10008201
Guido van Rossumb6775db1994-08-01 11:34:53 +00008202#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008203/*[clinic input]
8204os.setpgid
8205
8206 pid: pid_t
8207 pgrp: pid_t
8208 /
8209
8210Call the system call setpgid(pid, pgrp).
8211[clinic start generated code]*/
8212
Larry Hastings2f936352014-08-05 14:04:04 +10008213static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008214os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8215/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008216{
Victor Stinner8c62be82010-05-06 00:08:46 +00008217 if (setpgid(pid, pgrp) < 0)
8218 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008219 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008220}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008221#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008222
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008223
Guido van Rossumb6775db1994-08-01 11:34:53 +00008224#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008225/*[clinic input]
8226os.tcgetpgrp
8227
8228 fd: int
8229 /
8230
8231Return the process group associated with the terminal specified by fd.
8232[clinic start generated code]*/
8233
Larry Hastings2f936352014-08-05 14:04:04 +10008234static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008235os_tcgetpgrp_impl(PyObject *module, int fd)
8236/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008237{
8238 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008239 if (pgid < 0)
8240 return posix_error();
8241 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008242}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008243#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008244
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008245
Guido van Rossumb6775db1994-08-01 11:34:53 +00008246#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008247/*[clinic input]
8248os.tcsetpgrp
8249
8250 fd: int
8251 pgid: pid_t
8252 /
8253
8254Set the process group associated with the terminal specified by fd.
8255[clinic start generated code]*/
8256
Larry Hastings2f936352014-08-05 14:04:04 +10008257static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008258os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8259/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008260{
Victor Stinner8c62be82010-05-06 00:08:46 +00008261 if (tcsetpgrp(fd, pgid) < 0)
8262 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008263 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008264}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008265#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008266
Guido van Rossum687dd131993-05-17 08:34:16 +00008267/* Functions acting on file descriptors */
8268
Victor Stinnerdaf45552013-08-28 00:53:59 +02008269#ifdef O_CLOEXEC
8270extern int _Py_open_cloexec_works;
8271#endif
8272
Larry Hastings2f936352014-08-05 14:04:04 +10008273
8274/*[clinic input]
8275os.open -> int
8276 path: path_t
8277 flags: int
8278 mode: int = 0o777
8279 *
8280 dir_fd: dir_fd(requires='openat') = None
8281
8282# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8283
8284Open a file for low level IO. Returns a file descriptor (integer).
8285
8286If dir_fd is not None, it should be a file descriptor open to a directory,
8287 and path should be relative; path will then be relative to that directory.
8288dir_fd may not be implemented on your platform.
8289 If it is unavailable, using it will raise a NotImplementedError.
8290[clinic start generated code]*/
8291
Larry Hastings2f936352014-08-05 14:04:04 +10008292static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008293os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8294/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008295{
8296 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008297 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008298
Victor Stinnerdaf45552013-08-28 00:53:59 +02008299#ifdef O_CLOEXEC
8300 int *atomic_flag_works = &_Py_open_cloexec_works;
8301#elif !defined(MS_WINDOWS)
8302 int *atomic_flag_works = NULL;
8303#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008304
Victor Stinnerdaf45552013-08-28 00:53:59 +02008305#ifdef MS_WINDOWS
8306 flags |= O_NOINHERIT;
8307#elif defined(O_CLOEXEC)
8308 flags |= O_CLOEXEC;
8309#endif
8310
Steve Dowerb82e17e2019-05-23 08:45:22 -07008311 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
8312 return -1;
8313 }
8314
Steve Dower8fc89802015-04-12 00:26:27 -04008315 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008316 do {
8317 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008318#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008319 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008320#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008321#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008322 if (dir_fd != DEFAULT_DIR_FD)
8323 fd = openat(dir_fd, path->narrow, flags, mode);
8324 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008325#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008326 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008327#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008328 Py_END_ALLOW_THREADS
8329 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008330 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008331
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008332 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008333 if (!async_err)
8334 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008335 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008336 }
8337
Victor Stinnerdaf45552013-08-28 00:53:59 +02008338#ifndef MS_WINDOWS
8339 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8340 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008341 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008342 }
8343#endif
8344
Larry Hastings2f936352014-08-05 14:04:04 +10008345 return fd;
8346}
8347
8348
8349/*[clinic input]
8350os.close
8351
8352 fd: int
8353
8354Close a file descriptor.
8355[clinic start generated code]*/
8356
Barry Warsaw53699e91996-12-10 23:23:01 +00008357static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008358os_close_impl(PyObject *module, int fd)
8359/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008360{
Larry Hastings2f936352014-08-05 14:04:04 +10008361 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008362 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8363 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8364 * for more details.
8365 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008366 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008367 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008368 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008369 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008370 Py_END_ALLOW_THREADS
8371 if (res < 0)
8372 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008373 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008374}
8375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008376
Larry Hastings2f936352014-08-05 14:04:04 +10008377/*[clinic input]
8378os.closerange
8379
8380 fd_low: int
8381 fd_high: int
8382 /
8383
8384Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8385[clinic start generated code]*/
8386
Larry Hastings2f936352014-08-05 14:04:04 +10008387static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008388os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8389/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008390{
8391 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008392 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008393 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008394 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008395 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008396 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008397 Py_END_ALLOW_THREADS
8398 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008399}
8400
8401
Larry Hastings2f936352014-08-05 14:04:04 +10008402/*[clinic input]
8403os.dup -> int
8404
8405 fd: int
8406 /
8407
8408Return a duplicate of a file descriptor.
8409[clinic start generated code]*/
8410
Larry Hastings2f936352014-08-05 14:04:04 +10008411static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008412os_dup_impl(PyObject *module, int fd)
8413/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008414{
8415 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008416}
8417
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008418
Larry Hastings2f936352014-08-05 14:04:04 +10008419/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008420os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008421 fd: int
8422 fd2: int
8423 inheritable: bool=True
8424
8425Duplicate file descriptor.
8426[clinic start generated code]*/
8427
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008428static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008429os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008430/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008431{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008432 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008433#if defined(HAVE_DUP3) && \
8434 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8435 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008436 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008437#endif
8438
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008439 if (fd < 0 || fd2 < 0) {
8440 posix_error();
8441 return -1;
8442 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008443
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008444 /* dup2() can fail with EINTR if the target FD is already open, because it
8445 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8446 * upon close(), and therefore below.
8447 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008448#ifdef MS_WINDOWS
8449 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008450 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008451 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008452 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008453 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008454 if (res < 0) {
8455 posix_error();
8456 return -1;
8457 }
8458 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008459
8460 /* Character files like console cannot be make non-inheritable */
8461 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8462 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008463 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008464 }
8465
8466#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8467 Py_BEGIN_ALLOW_THREADS
8468 if (!inheritable)
8469 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8470 else
8471 res = dup2(fd, fd2);
8472 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008473 if (res < 0) {
8474 posix_error();
8475 return -1;
8476 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008477
8478#else
8479
8480#ifdef HAVE_DUP3
8481 if (!inheritable && dup3_works != 0) {
8482 Py_BEGIN_ALLOW_THREADS
8483 res = dup3(fd, fd2, O_CLOEXEC);
8484 Py_END_ALLOW_THREADS
8485 if (res < 0) {
8486 if (dup3_works == -1)
8487 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008488 if (dup3_works) {
8489 posix_error();
8490 return -1;
8491 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008492 }
8493 }
8494
8495 if (inheritable || dup3_works == 0)
8496 {
8497#endif
8498 Py_BEGIN_ALLOW_THREADS
8499 res = dup2(fd, fd2);
8500 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008501 if (res < 0) {
8502 posix_error();
8503 return -1;
8504 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008505
8506 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8507 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008508 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008509 }
8510#ifdef HAVE_DUP3
8511 }
8512#endif
8513
8514#endif
8515
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008516 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008517}
8518
Larry Hastings2f936352014-08-05 14:04:04 +10008519
Ross Lagerwall7807c352011-03-17 20:20:30 +02008520#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008521/*[clinic input]
8522os.lockf
8523
8524 fd: int
8525 An open file descriptor.
8526 command: int
8527 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8528 length: Py_off_t
8529 The number of bytes to lock, starting at the current position.
8530 /
8531
8532Apply, test or remove a POSIX lock on an open file descriptor.
8533
8534[clinic start generated code]*/
8535
Larry Hastings2f936352014-08-05 14:04:04 +10008536static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008537os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8538/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008539{
8540 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008541
8542 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008543 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008544 Py_END_ALLOW_THREADS
8545
8546 if (res < 0)
8547 return posix_error();
8548
8549 Py_RETURN_NONE;
8550}
Larry Hastings2f936352014-08-05 14:04:04 +10008551#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008552
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008553
Larry Hastings2f936352014-08-05 14:04:04 +10008554/*[clinic input]
8555os.lseek -> Py_off_t
8556
8557 fd: int
8558 position: Py_off_t
8559 how: int
8560 /
8561
8562Set the position of a file descriptor. Return the new position.
8563
8564Return the new cursor position in number of bytes
8565relative to the beginning of the file.
8566[clinic start generated code]*/
8567
Larry Hastings2f936352014-08-05 14:04:04 +10008568static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008569os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8570/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008571{
8572 Py_off_t result;
8573
Guido van Rossum687dd131993-05-17 08:34:16 +00008574#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008575 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8576 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008577 case 0: how = SEEK_SET; break;
8578 case 1: how = SEEK_CUR; break;
8579 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008580 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008581#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008582
Victor Stinner8c62be82010-05-06 00:08:46 +00008583 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008584 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008585#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008586 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008587#else
Larry Hastings2f936352014-08-05 14:04:04 +10008588 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008589#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008590 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008591 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008592 if (result < 0)
8593 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008594
Larry Hastings2f936352014-08-05 14:04:04 +10008595 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008596}
8597
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008598
Larry Hastings2f936352014-08-05 14:04:04 +10008599/*[clinic input]
8600os.read
8601 fd: int
8602 length: Py_ssize_t
8603 /
8604
8605Read from a file descriptor. Returns a bytes object.
8606[clinic start generated code]*/
8607
Larry Hastings2f936352014-08-05 14:04:04 +10008608static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008609os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8610/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008611{
Victor Stinner8c62be82010-05-06 00:08:46 +00008612 Py_ssize_t n;
8613 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008614
8615 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008616 errno = EINVAL;
8617 return posix_error();
8618 }
Larry Hastings2f936352014-08-05 14:04:04 +10008619
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008620 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008621
8622 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008623 if (buffer == NULL)
8624 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008625
Victor Stinner66aab0c2015-03-19 22:53:20 +01008626 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8627 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008628 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008629 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008630 }
Larry Hastings2f936352014-08-05 14:04:04 +10008631
8632 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008633 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008634
Victor Stinner8c62be82010-05-06 00:08:46 +00008635 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008636}
8637
Ross Lagerwall7807c352011-03-17 20:20:30 +02008638#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008639 || defined(__APPLE__))) \
8640 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8641 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8642static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008643iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008644{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008645 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008646
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008647 *iov = PyMem_New(struct iovec, cnt);
8648 if (*iov == NULL) {
8649 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008650 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008651 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008652
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008653 *buf = PyMem_New(Py_buffer, cnt);
8654 if (*buf == NULL) {
8655 PyMem_Del(*iov);
8656 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008657 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008658 }
8659
8660 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008661 PyObject *item = PySequence_GetItem(seq, i);
8662 if (item == NULL)
8663 goto fail;
8664 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8665 Py_DECREF(item);
8666 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008667 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008668 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008669 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008670 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008671 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008672 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008673
8674fail:
8675 PyMem_Del(*iov);
8676 for (j = 0; j < i; j++) {
8677 PyBuffer_Release(&(*buf)[j]);
8678 }
8679 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008680 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008681}
8682
8683static void
8684iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8685{
8686 int i;
8687 PyMem_Del(iov);
8688 for (i = 0; i < cnt; i++) {
8689 PyBuffer_Release(&buf[i]);
8690 }
8691 PyMem_Del(buf);
8692}
8693#endif
8694
Larry Hastings2f936352014-08-05 14:04:04 +10008695
Ross Lagerwall7807c352011-03-17 20:20:30 +02008696#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008697/*[clinic input]
8698os.readv -> Py_ssize_t
8699
8700 fd: int
8701 buffers: object
8702 /
8703
8704Read from a file descriptor fd into an iterable of buffers.
8705
8706The buffers should be mutable buffers accepting bytes.
8707readv will transfer data into each buffer until it is full
8708and then move on to the next buffer in the sequence to hold
8709the rest of the data.
8710
8711readv returns the total number of bytes read,
8712which may be less than the total capacity of all the buffers.
8713[clinic start generated code]*/
8714
Larry Hastings2f936352014-08-05 14:04:04 +10008715static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008716os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8717/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008718{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008719 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008720 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008721 struct iovec *iov;
8722 Py_buffer *buf;
8723
Larry Hastings2f936352014-08-05 14:04:04 +10008724 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008725 PyErr_SetString(PyExc_TypeError,
8726 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008727 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008728 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008729
Larry Hastings2f936352014-08-05 14:04:04 +10008730 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008731 if (cnt < 0)
8732 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008733
8734 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8735 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008736
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008737 do {
8738 Py_BEGIN_ALLOW_THREADS
8739 n = readv(fd, iov, cnt);
8740 Py_END_ALLOW_THREADS
8741 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008742
8743 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008744 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008745 if (!async_err)
8746 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008747 return -1;
8748 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008749
Larry Hastings2f936352014-08-05 14:04:04 +10008750 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008751}
Larry Hastings2f936352014-08-05 14:04:04 +10008752#endif /* HAVE_READV */
8753
Ross Lagerwall7807c352011-03-17 20:20:30 +02008754
8755#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008756/*[clinic input]
8757# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8758os.pread
8759
8760 fd: int
8761 length: int
8762 offset: Py_off_t
8763 /
8764
8765Read a number of bytes from a file descriptor starting at a particular offset.
8766
8767Read length bytes from file descriptor fd, starting at offset bytes from
8768the beginning of the file. The file offset remains unchanged.
8769[clinic start generated code]*/
8770
Larry Hastings2f936352014-08-05 14:04:04 +10008771static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008772os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8773/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008774{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008775 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008776 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008777 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008778
Larry Hastings2f936352014-08-05 14:04:04 +10008779 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008780 errno = EINVAL;
8781 return posix_error();
8782 }
Larry Hastings2f936352014-08-05 14:04:04 +10008783 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008784 if (buffer == NULL)
8785 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008786
8787 do {
8788 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008789 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008790 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008791 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008792 Py_END_ALLOW_THREADS
8793 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8794
Ross Lagerwall7807c352011-03-17 20:20:30 +02008795 if (n < 0) {
8796 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008797 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008798 }
Larry Hastings2f936352014-08-05 14:04:04 +10008799 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008800 _PyBytes_Resize(&buffer, n);
8801 return buffer;
8802}
Larry Hastings2f936352014-08-05 14:04:04 +10008803#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008804
Pablo Galindo4defba32018-01-27 16:16:37 +00008805#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8806/*[clinic input]
8807os.preadv -> Py_ssize_t
8808
8809 fd: int
8810 buffers: object
8811 offset: Py_off_t
8812 flags: int = 0
8813 /
8814
8815Reads from a file descriptor into a number of mutable bytes-like objects.
8816
8817Combines the functionality of readv() and pread(). As readv(), it will
8818transfer data into each buffer until it is full and then move on to the next
8819buffer in the sequence to hold the rest of the data. Its fourth argument,
8820specifies the file offset at which the input operation is to be performed. It
8821will return the total number of bytes read (which can be less than the total
8822capacity of all the objects).
8823
8824The flags argument contains a bitwise OR of zero or more of the following flags:
8825
8826- RWF_HIPRI
8827- RWF_NOWAIT
8828
8829Using non-zero flags requires Linux 4.6 or newer.
8830[clinic start generated code]*/
8831
8832static Py_ssize_t
8833os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8834 int flags)
8835/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8836{
8837 Py_ssize_t cnt, n;
8838 int async_err = 0;
8839 struct iovec *iov;
8840 Py_buffer *buf;
8841
8842 if (!PySequence_Check(buffers)) {
8843 PyErr_SetString(PyExc_TypeError,
8844 "preadv2() arg 2 must be a sequence");
8845 return -1;
8846 }
8847
8848 cnt = PySequence_Size(buffers);
8849 if (cnt < 0) {
8850 return -1;
8851 }
8852
8853#ifndef HAVE_PREADV2
8854 if(flags != 0) {
8855 argument_unavailable_error("preadv2", "flags");
8856 return -1;
8857 }
8858#endif
8859
8860 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8861 return -1;
8862 }
8863#ifdef HAVE_PREADV2
8864 do {
8865 Py_BEGIN_ALLOW_THREADS
8866 _Py_BEGIN_SUPPRESS_IPH
8867 n = preadv2(fd, iov, cnt, offset, flags);
8868 _Py_END_SUPPRESS_IPH
8869 Py_END_ALLOW_THREADS
8870 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8871#else
8872 do {
8873 Py_BEGIN_ALLOW_THREADS
8874 _Py_BEGIN_SUPPRESS_IPH
8875 n = preadv(fd, iov, cnt, offset);
8876 _Py_END_SUPPRESS_IPH
8877 Py_END_ALLOW_THREADS
8878 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8879#endif
8880
8881 iov_cleanup(iov, buf, cnt);
8882 if (n < 0) {
8883 if (!async_err) {
8884 posix_error();
8885 }
8886 return -1;
8887 }
8888
8889 return n;
8890}
8891#endif /* HAVE_PREADV */
8892
Larry Hastings2f936352014-08-05 14:04:04 +10008893
8894/*[clinic input]
8895os.write -> Py_ssize_t
8896
8897 fd: int
8898 data: Py_buffer
8899 /
8900
8901Write a bytes object to a file descriptor.
8902[clinic start generated code]*/
8903
Larry Hastings2f936352014-08-05 14:04:04 +10008904static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008905os_write_impl(PyObject *module, int fd, Py_buffer *data)
8906/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008907{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008908 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008909}
8910
8911#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008912PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008913"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008914sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008915 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008916Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008917
Larry Hastings2f936352014-08-05 14:04:04 +10008918/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008919static PyObject *
8920posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8921{
8922 int in, out;
8923 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008924 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008925 off_t offset;
8926
8927#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8928#ifndef __APPLE__
8929 Py_ssize_t len;
8930#endif
8931 PyObject *headers = NULL, *trailers = NULL;
8932 Py_buffer *hbuf, *tbuf;
8933 off_t sbytes;
8934 struct sf_hdtr sf;
8935 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008936 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008937 static char *keywords[] = {"out", "in",
8938 "offset", "count",
8939 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008940
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008941 sf.headers = NULL;
8942 sf.trailers = NULL;
8943
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008944#ifdef __APPLE__
8945 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008946 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008947#else
8948 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008949 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008950#endif
8951 &headers, &trailers, &flags))
8952 return NULL;
8953 if (headers != NULL) {
8954 if (!PySequence_Check(headers)) {
8955 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008956 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008957 return NULL;
8958 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008959 Py_ssize_t i = PySequence_Size(headers);
8960 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008961 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008962 if (i > INT_MAX) {
8963 PyErr_SetString(PyExc_OverflowError,
8964 "sendfile() header is too large");
8965 return NULL;
8966 }
8967 if (i > 0) {
8968 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008969 if (iov_setup(&(sf.headers), &hbuf,
8970 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008971 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008972#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008973 for (i = 0; i < sf.hdr_cnt; i++) {
8974 Py_ssize_t blen = sf.headers[i].iov_len;
8975# define OFF_T_MAX 0x7fffffffffffffff
8976 if (sbytes >= OFF_T_MAX - blen) {
8977 PyErr_SetString(PyExc_OverflowError,
8978 "sendfile() header is too large");
8979 return NULL;
8980 }
8981 sbytes += blen;
8982 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008983#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008984 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008985 }
8986 }
8987 if (trailers != NULL) {
8988 if (!PySequence_Check(trailers)) {
8989 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008990 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008991 return NULL;
8992 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008993 Py_ssize_t i = PySequence_Size(trailers);
8994 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008995 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008996 if (i > INT_MAX) {
8997 PyErr_SetString(PyExc_OverflowError,
8998 "sendfile() trailer is too large");
8999 return NULL;
9000 }
9001 if (i > 0) {
9002 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009003 if (iov_setup(&(sf.trailers), &tbuf,
9004 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009005 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009006 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009007 }
9008 }
9009
Steve Dower8fc89802015-04-12 00:26:27 -04009010 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009011 do {
9012 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009013#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009014 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009015#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009016 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009017#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009018 Py_END_ALLOW_THREADS
9019 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009020 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009021
9022 if (sf.headers != NULL)
9023 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9024 if (sf.trailers != NULL)
9025 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9026
9027 if (ret < 0) {
9028 if ((errno == EAGAIN) || (errno == EBUSY)) {
9029 if (sbytes != 0) {
9030 // some data has been sent
9031 goto done;
9032 }
9033 else {
9034 // no data has been sent; upper application is supposed
9035 // to retry on EAGAIN or EBUSY
9036 return posix_error();
9037 }
9038 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009039 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009040 }
9041 goto done;
9042
9043done:
9044 #if !defined(HAVE_LARGEFILE_SUPPORT)
9045 return Py_BuildValue("l", sbytes);
9046 #else
9047 return Py_BuildValue("L", sbytes);
9048 #endif
9049
9050#else
9051 Py_ssize_t count;
9052 PyObject *offobj;
9053 static char *keywords[] = {"out", "in",
9054 "offset", "count", NULL};
9055 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
9056 keywords, &out, &in, &offobj, &count))
9057 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009058#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009059 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009060 do {
9061 Py_BEGIN_ALLOW_THREADS
9062 ret = sendfile(out, in, NULL, count);
9063 Py_END_ALLOW_THREADS
9064 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009065 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009066 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009067 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009068 }
9069#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009070 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009071 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009072
9073 do {
9074 Py_BEGIN_ALLOW_THREADS
9075 ret = sendfile(out, in, &offset, count);
9076 Py_END_ALLOW_THREADS
9077 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009078 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009079 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009080 return Py_BuildValue("n", ret);
9081#endif
9082}
Larry Hastings2f936352014-08-05 14:04:04 +10009083#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009084
Larry Hastings2f936352014-08-05 14:04:04 +10009085
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009086#if defined(__APPLE__)
9087/*[clinic input]
9088os._fcopyfile
9089
9090 infd: int
9091 outfd: int
9092 flags: int
9093 /
9094
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009095Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009096[clinic start generated code]*/
9097
9098static PyObject *
9099os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009100/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009101{
9102 int ret;
9103
9104 Py_BEGIN_ALLOW_THREADS
9105 ret = fcopyfile(infd, outfd, NULL, flags);
9106 Py_END_ALLOW_THREADS
9107 if (ret < 0)
9108 return posix_error();
9109 Py_RETURN_NONE;
9110}
9111#endif
9112
9113
Larry Hastings2f936352014-08-05 14:04:04 +10009114/*[clinic input]
9115os.fstat
9116
9117 fd : int
9118
9119Perform a stat system call on the given file descriptor.
9120
9121Like stat(), but for an open file descriptor.
9122Equivalent to os.stat(fd).
9123[clinic start generated code]*/
9124
Larry Hastings2f936352014-08-05 14:04:04 +10009125static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009126os_fstat_impl(PyObject *module, int fd)
9127/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009128{
Victor Stinner8c62be82010-05-06 00:08:46 +00009129 STRUCT_STAT st;
9130 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009131 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009132
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009133 do {
9134 Py_BEGIN_ALLOW_THREADS
9135 res = FSTAT(fd, &st);
9136 Py_END_ALLOW_THREADS
9137 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009138 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009139#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009140 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009141#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009142 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009143#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009144 }
Tim Peters5aa91602002-01-30 05:46:57 +00009145
Victor Stinner4195b5c2012-02-08 23:03:19 +01009146 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009147}
9148
Larry Hastings2f936352014-08-05 14:04:04 +10009149
9150/*[clinic input]
9151os.isatty -> bool
9152 fd: int
9153 /
9154
9155Return True if the fd is connected to a terminal.
9156
9157Return True if the file descriptor is an open file descriptor
9158connected to the slave end of a terminal.
9159[clinic start generated code]*/
9160
Larry Hastings2f936352014-08-05 14:04:04 +10009161static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009162os_isatty_impl(PyObject *module, int fd)
9163/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009164{
Steve Dower8fc89802015-04-12 00:26:27 -04009165 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009166 _Py_BEGIN_SUPPRESS_IPH
9167 return_value = isatty(fd);
9168 _Py_END_SUPPRESS_IPH
9169 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009170}
9171
9172
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009173#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009174/*[clinic input]
9175os.pipe
9176
9177Create a pipe.
9178
9179Returns a tuple of two file descriptors:
9180 (read_fd, write_fd)
9181[clinic start generated code]*/
9182
Larry Hastings2f936352014-08-05 14:04:04 +10009183static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009184os_pipe_impl(PyObject *module)
9185/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009186{
Victor Stinner8c62be82010-05-06 00:08:46 +00009187 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009188#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009189 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009190 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009191 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009192#else
9193 int res;
9194#endif
9195
9196#ifdef MS_WINDOWS
9197 attr.nLength = sizeof(attr);
9198 attr.lpSecurityDescriptor = NULL;
9199 attr.bInheritHandle = FALSE;
9200
9201 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009202 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009203 ok = CreatePipe(&read, &write, &attr, 0);
9204 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009205 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9206 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009207 if (fds[0] == -1 || fds[1] == -1) {
9208 CloseHandle(read);
9209 CloseHandle(write);
9210 ok = 0;
9211 }
9212 }
Steve Dowerc3630612016-11-19 18:41:16 -08009213 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009214 Py_END_ALLOW_THREADS
9215
Victor Stinner8c62be82010-05-06 00:08:46 +00009216 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009217 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009218#else
9219
9220#ifdef HAVE_PIPE2
9221 Py_BEGIN_ALLOW_THREADS
9222 res = pipe2(fds, O_CLOEXEC);
9223 Py_END_ALLOW_THREADS
9224
9225 if (res != 0 && errno == ENOSYS)
9226 {
9227#endif
9228 Py_BEGIN_ALLOW_THREADS
9229 res = pipe(fds);
9230 Py_END_ALLOW_THREADS
9231
9232 if (res == 0) {
9233 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9234 close(fds[0]);
9235 close(fds[1]);
9236 return NULL;
9237 }
9238 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9239 close(fds[0]);
9240 close(fds[1]);
9241 return NULL;
9242 }
9243 }
9244#ifdef HAVE_PIPE2
9245 }
9246#endif
9247
9248 if (res != 0)
9249 return PyErr_SetFromErrno(PyExc_OSError);
9250#endif /* !MS_WINDOWS */
9251 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009252}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009253#endif /* HAVE_PIPE */
9254
Larry Hastings2f936352014-08-05 14:04:04 +10009255
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009256#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009257/*[clinic input]
9258os.pipe2
9259
9260 flags: int
9261 /
9262
9263Create a pipe with flags set atomically.
9264
9265Returns a tuple of two file descriptors:
9266 (read_fd, write_fd)
9267
9268flags can be constructed by ORing together one or more of these values:
9269O_NONBLOCK, O_CLOEXEC.
9270[clinic start generated code]*/
9271
Larry Hastings2f936352014-08-05 14:04:04 +10009272static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009273os_pipe2_impl(PyObject *module, int flags)
9274/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009275{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009276 int fds[2];
9277 int res;
9278
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009279 res = pipe2(fds, flags);
9280 if (res != 0)
9281 return posix_error();
9282 return Py_BuildValue("(ii)", fds[0], fds[1]);
9283}
9284#endif /* HAVE_PIPE2 */
9285
Larry Hastings2f936352014-08-05 14:04:04 +10009286
Ross Lagerwall7807c352011-03-17 20:20:30 +02009287#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009288/*[clinic input]
9289os.writev -> Py_ssize_t
9290 fd: int
9291 buffers: object
9292 /
9293
9294Iterate over buffers, and write the contents of each to a file descriptor.
9295
9296Returns the total number of bytes written.
9297buffers must be a sequence of bytes-like objects.
9298[clinic start generated code]*/
9299
Larry Hastings2f936352014-08-05 14:04:04 +10009300static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009301os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9302/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009303{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009304 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009305 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009306 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009307 struct iovec *iov;
9308 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009309
9310 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009311 PyErr_SetString(PyExc_TypeError,
9312 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009313 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009314 }
Larry Hastings2f936352014-08-05 14:04:04 +10009315 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009316 if (cnt < 0)
9317 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009318
Larry Hastings2f936352014-08-05 14:04:04 +10009319 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9320 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009321 }
9322
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009323 do {
9324 Py_BEGIN_ALLOW_THREADS
9325 result = writev(fd, iov, cnt);
9326 Py_END_ALLOW_THREADS
9327 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009328
9329 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009330 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009331 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009332
Georg Brandl306336b2012-06-24 12:55:33 +02009333 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009334}
Larry Hastings2f936352014-08-05 14:04:04 +10009335#endif /* HAVE_WRITEV */
9336
9337
9338#ifdef HAVE_PWRITE
9339/*[clinic input]
9340os.pwrite -> Py_ssize_t
9341
9342 fd: int
9343 buffer: Py_buffer
9344 offset: Py_off_t
9345 /
9346
9347Write bytes to a file descriptor starting at a particular offset.
9348
9349Write buffer to fd, starting at offset bytes from the beginning of
9350the file. Returns the number of bytes writte. Does not change the
9351current file offset.
9352[clinic start generated code]*/
9353
Larry Hastings2f936352014-08-05 14:04:04 +10009354static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009355os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9356/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009357{
9358 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009359 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009360
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009361 do {
9362 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009363 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009364 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009365 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009366 Py_END_ALLOW_THREADS
9367 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009368
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009369 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009370 posix_error();
9371 return size;
9372}
9373#endif /* HAVE_PWRITE */
9374
Pablo Galindo4defba32018-01-27 16:16:37 +00009375#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9376/*[clinic input]
9377os.pwritev -> Py_ssize_t
9378
9379 fd: int
9380 buffers: object
9381 offset: Py_off_t
9382 flags: int = 0
9383 /
9384
9385Writes the contents of bytes-like objects to a file descriptor at a given offset.
9386
9387Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9388of bytes-like objects. Buffers are processed in array order. Entire contents of first
9389buffer is written before proceeding to second, and so on. The operating system may
9390set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9391This function writes the contents of each object to the file descriptor and returns
9392the total number of bytes written.
9393
9394The flags argument contains a bitwise OR of zero or more of the following flags:
9395
9396- RWF_DSYNC
9397- RWF_SYNC
9398
9399Using non-zero flags requires Linux 4.7 or newer.
9400[clinic start generated code]*/
9401
9402static Py_ssize_t
9403os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9404 int flags)
9405/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9406{
9407 Py_ssize_t cnt;
9408 Py_ssize_t result;
9409 int async_err = 0;
9410 struct iovec *iov;
9411 Py_buffer *buf;
9412
9413 if (!PySequence_Check(buffers)) {
9414 PyErr_SetString(PyExc_TypeError,
9415 "pwritev() arg 2 must be a sequence");
9416 return -1;
9417 }
9418
9419 cnt = PySequence_Size(buffers);
9420 if (cnt < 0) {
9421 return -1;
9422 }
9423
9424#ifndef HAVE_PWRITEV2
9425 if(flags != 0) {
9426 argument_unavailable_error("pwritev2", "flags");
9427 return -1;
9428 }
9429#endif
9430
9431 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9432 return -1;
9433 }
9434#ifdef HAVE_PWRITEV2
9435 do {
9436 Py_BEGIN_ALLOW_THREADS
9437 _Py_BEGIN_SUPPRESS_IPH
9438 result = pwritev2(fd, iov, cnt, offset, flags);
9439 _Py_END_SUPPRESS_IPH
9440 Py_END_ALLOW_THREADS
9441 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9442#else
9443 do {
9444 Py_BEGIN_ALLOW_THREADS
9445 _Py_BEGIN_SUPPRESS_IPH
9446 result = pwritev(fd, iov, cnt, offset);
9447 _Py_END_SUPPRESS_IPH
9448 Py_END_ALLOW_THREADS
9449 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9450#endif
9451
9452 iov_cleanup(iov, buf, cnt);
9453 if (result < 0) {
9454 if (!async_err) {
9455 posix_error();
9456 }
9457 return -1;
9458 }
9459
9460 return result;
9461}
9462#endif /* HAVE_PWRITEV */
9463
Pablo Galindoaac4d032019-05-31 19:39:47 +01009464#ifdef HAVE_COPY_FILE_RANGE
9465/*[clinic input]
9466
9467os.copy_file_range
9468 src: int
9469 Source file descriptor.
9470 dst: int
9471 Destination file descriptor.
9472 count: Py_ssize_t
9473 Number of bytes to copy.
9474 offset_src: object = None
9475 Starting offset in src.
9476 offset_dst: object = None
9477 Starting offset in dst.
9478
9479Copy count bytes from one file descriptor to another.
9480
9481If offset_src is None, then src is read from the current position;
9482respectively for offset_dst.
9483[clinic start generated code]*/
9484
9485static PyObject *
9486os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
9487 PyObject *offset_src, PyObject *offset_dst)
9488/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
9489{
9490 off_t offset_src_val, offset_dst_val;
9491 off_t *p_offset_src = NULL;
9492 off_t *p_offset_dst = NULL;
9493 Py_ssize_t ret;
9494 int async_err = 0;
9495 /* The flags argument is provided to allow
9496 * for future extensions and currently must be to 0. */
9497 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +00009498
9499
Pablo Galindoaac4d032019-05-31 19:39:47 +01009500 if (count < 0) {
9501 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
9502 return NULL;
9503 }
9504
9505 if (offset_src != Py_None) {
9506 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
9507 return NULL;
9508 }
9509 p_offset_src = &offset_src_val;
9510 }
9511
9512 if (offset_dst != Py_None) {
9513 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
9514 return NULL;
9515 }
9516 p_offset_dst = &offset_dst_val;
9517 }
9518
9519 do {
9520 Py_BEGIN_ALLOW_THREADS
9521 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
9522 Py_END_ALLOW_THREADS
9523 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9524
9525 if (ret < 0) {
9526 return (!async_err) ? posix_error() : NULL;
9527 }
9528
9529 return PyLong_FromSsize_t(ret);
9530}
9531#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +10009532
9533#ifdef HAVE_MKFIFO
9534/*[clinic input]
9535os.mkfifo
9536
9537 path: path_t
9538 mode: int=0o666
9539 *
9540 dir_fd: dir_fd(requires='mkfifoat')=None
9541
9542Create a "fifo" (a POSIX named pipe).
9543
9544If dir_fd is not None, it should be a file descriptor open to a directory,
9545 and path should be relative; path will then be relative to that directory.
9546dir_fd may not be implemented on your platform.
9547 If it is unavailable, using it will raise a NotImplementedError.
9548[clinic start generated code]*/
9549
Larry Hastings2f936352014-08-05 14:04:04 +10009550static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009551os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9552/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009553{
9554 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009555 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009556
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009557 do {
9558 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009559#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009560 if (dir_fd != DEFAULT_DIR_FD)
9561 result = mkfifoat(dir_fd, path->narrow, mode);
9562 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009563#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009564 result = mkfifo(path->narrow, mode);
9565 Py_END_ALLOW_THREADS
9566 } while (result != 0 && errno == EINTR &&
9567 !(async_err = PyErr_CheckSignals()));
9568 if (result != 0)
9569 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009570
9571 Py_RETURN_NONE;
9572}
9573#endif /* HAVE_MKFIFO */
9574
9575
9576#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9577/*[clinic input]
9578os.mknod
9579
9580 path: path_t
9581 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009582 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009583 *
9584 dir_fd: dir_fd(requires='mknodat')=None
9585
9586Create a node in the file system.
9587
9588Create a node in the file system (file, device special file or named pipe)
9589at path. mode specifies both the permissions to use and the
9590type of node to be created, being combined (bitwise OR) with one of
9591S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9592device defines the newly created device special file (probably using
9593os.makedev()). Otherwise device is ignored.
9594
9595If dir_fd is not None, it should be a file descriptor open to a directory,
9596 and path should be relative; path will then be relative to that directory.
9597dir_fd may not be implemented on your platform.
9598 If it is unavailable, using it will raise a NotImplementedError.
9599[clinic start generated code]*/
9600
Larry Hastings2f936352014-08-05 14:04:04 +10009601static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009602os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009603 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009604/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009605{
9606 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009607 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009608
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009609 do {
9610 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009611#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009612 if (dir_fd != DEFAULT_DIR_FD)
9613 result = mknodat(dir_fd, path->narrow, mode, device);
9614 else
Larry Hastings2f936352014-08-05 14:04:04 +10009615#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009616 result = mknod(path->narrow, mode, device);
9617 Py_END_ALLOW_THREADS
9618 } while (result != 0 && errno == EINTR &&
9619 !(async_err = PyErr_CheckSignals()));
9620 if (result != 0)
9621 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009622
9623 Py_RETURN_NONE;
9624}
9625#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9626
9627
9628#ifdef HAVE_DEVICE_MACROS
9629/*[clinic input]
9630os.major -> unsigned_int
9631
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009632 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009633 /
9634
9635Extracts a device major number from a raw device number.
9636[clinic start generated code]*/
9637
Larry Hastings2f936352014-08-05 14:04:04 +10009638static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009639os_major_impl(PyObject *module, dev_t device)
9640/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009641{
9642 return major(device);
9643}
9644
9645
9646/*[clinic input]
9647os.minor -> unsigned_int
9648
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009649 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009650 /
9651
9652Extracts a device minor number from a raw device number.
9653[clinic start generated code]*/
9654
Larry Hastings2f936352014-08-05 14:04:04 +10009655static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009656os_minor_impl(PyObject *module, dev_t device)
9657/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009658{
9659 return minor(device);
9660}
9661
9662
9663/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009664os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009665
9666 major: int
9667 minor: int
9668 /
9669
9670Composes a raw device number from the major and minor device numbers.
9671[clinic start generated code]*/
9672
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009673static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009674os_makedev_impl(PyObject *module, int major, int minor)
9675/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009676{
9677 return makedev(major, minor);
9678}
9679#endif /* HAVE_DEVICE_MACROS */
9680
9681
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009682#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009683/*[clinic input]
9684os.ftruncate
9685
9686 fd: int
9687 length: Py_off_t
9688 /
9689
9690Truncate a file, specified by file descriptor, to a specific length.
9691[clinic start generated code]*/
9692
Larry Hastings2f936352014-08-05 14:04:04 +10009693static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009694os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9695/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009696{
9697 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009698 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009699
Steve Dowerb82e17e2019-05-23 08:45:22 -07009700 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
9701 return NULL;
9702 }
9703
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009704 do {
9705 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009706 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009707#ifdef MS_WINDOWS
9708 result = _chsize_s(fd, length);
9709#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009710 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009711#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009712 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009713 Py_END_ALLOW_THREADS
9714 } while (result != 0 && errno == EINTR &&
9715 !(async_err = PyErr_CheckSignals()));
9716 if (result != 0)
9717 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009718 Py_RETURN_NONE;
9719}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009720#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009721
9722
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009723#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009724/*[clinic input]
9725os.truncate
9726 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9727 length: Py_off_t
9728
9729Truncate a file, specified by path, to a specific length.
9730
9731On some platforms, path may also be specified as an open file descriptor.
9732 If this functionality is unavailable, using it raises an exception.
9733[clinic start generated code]*/
9734
Larry Hastings2f936352014-08-05 14:04:04 +10009735static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009736os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9737/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009738{
9739 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009740#ifdef MS_WINDOWS
9741 int fd;
9742#endif
9743
9744 if (path->fd != -1)
9745 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009746
Steve Dowerb82e17e2019-05-23 08:45:22 -07009747 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
9748 return NULL;
9749 }
9750
Larry Hastings2f936352014-08-05 14:04:04 +10009751 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009752 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009753#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009754 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009755 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009756 result = -1;
9757 else {
9758 result = _chsize_s(fd, length);
9759 close(fd);
9760 if (result < 0)
9761 errno = result;
9762 }
9763#else
9764 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009765#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009766 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009767 Py_END_ALLOW_THREADS
9768 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009769 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009770
9771 Py_RETURN_NONE;
9772}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009773#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009774
Ross Lagerwall7807c352011-03-17 20:20:30 +02009775
Victor Stinnerd6b17692014-09-30 12:20:05 +02009776/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9777 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9778 defined, which is the case in Python on AIX. AIX bug report:
9779 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9780#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9781# define POSIX_FADVISE_AIX_BUG
9782#endif
9783
Victor Stinnerec39e262014-09-30 12:35:58 +02009784
Victor Stinnerd6b17692014-09-30 12:20:05 +02009785#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009786/*[clinic input]
9787os.posix_fallocate
9788
9789 fd: int
9790 offset: Py_off_t
9791 length: Py_off_t
9792 /
9793
9794Ensure a file has allocated at least a particular number of bytes on disk.
9795
9796Ensure that the file specified by fd encompasses a range of bytes
9797starting at offset bytes from the beginning and continuing for length bytes.
9798[clinic start generated code]*/
9799
Larry Hastings2f936352014-08-05 14:04:04 +10009800static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009801os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009802 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009803/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009804{
9805 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009806 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009807
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009808 do {
9809 Py_BEGIN_ALLOW_THREADS
9810 result = posix_fallocate(fd, offset, length);
9811 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009812 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9813
9814 if (result == 0)
9815 Py_RETURN_NONE;
9816
9817 if (async_err)
9818 return NULL;
9819
9820 errno = result;
9821 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009822}
Victor Stinnerec39e262014-09-30 12:35:58 +02009823#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009824
Ross Lagerwall7807c352011-03-17 20:20:30 +02009825
Victor Stinnerd6b17692014-09-30 12:20:05 +02009826#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009827/*[clinic input]
9828os.posix_fadvise
9829
9830 fd: int
9831 offset: Py_off_t
9832 length: Py_off_t
9833 advice: int
9834 /
9835
9836Announce an intention to access data in a specific pattern.
9837
9838Announce an intention to access data in a specific pattern, thus allowing
9839the kernel to make optimizations.
9840The advice applies to the region of the file specified by fd starting at
9841offset and continuing for length bytes.
9842advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9843POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9844POSIX_FADV_DONTNEED.
9845[clinic start generated code]*/
9846
Larry Hastings2f936352014-08-05 14:04:04 +10009847static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009848os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009849 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009850/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009851{
9852 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009853 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009854
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009855 do {
9856 Py_BEGIN_ALLOW_THREADS
9857 result = posix_fadvise(fd, offset, length, advice);
9858 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009859 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9860
9861 if (result == 0)
9862 Py_RETURN_NONE;
9863
9864 if (async_err)
9865 return NULL;
9866
9867 errno = result;
9868 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009869}
Victor Stinnerec39e262014-09-30 12:35:58 +02009870#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009871
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009872#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009873
Fred Drake762e2061999-08-26 17:23:54 +00009874/* Save putenv() parameters as values here, so we can collect them when they
9875 * get re-set with another call for the same key. */
9876static PyObject *posix_putenv_garbage;
9877
Larry Hastings2f936352014-08-05 14:04:04 +10009878static void
9879posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009880{
Larry Hastings2f936352014-08-05 14:04:04 +10009881 /* Install the first arg and newstr in posix_putenv_garbage;
9882 * this will cause previous value to be collected. This has to
9883 * happen after the real putenv() call because the old value
9884 * was still accessible until then. */
9885 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9886 /* really not much we can do; just leak */
9887 PyErr_Clear();
9888 else
9889 Py_DECREF(value);
9890}
9891
9892
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009893#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009894/*[clinic input]
9895os.putenv
9896
9897 name: unicode
9898 value: unicode
9899 /
9900
9901Change or add an environment variable.
9902[clinic start generated code]*/
9903
Larry Hastings2f936352014-08-05 14:04:04 +10009904static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009905os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9906/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009907{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009908 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009909 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009910
Serhiy Storchaka77703942017-06-25 07:33:01 +03009911 /* Search from index 1 because on Windows starting '=' is allowed for
9912 defining hidden environment variables. */
9913 if (PyUnicode_GET_LENGTH(name) == 0 ||
9914 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9915 {
9916 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9917 return NULL;
9918 }
Larry Hastings2f936352014-08-05 14:04:04 +10009919 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9920 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009921 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009922 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009923
9924 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9925 if (env == NULL)
9926 goto error;
9927 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009928 PyErr_Format(PyExc_ValueError,
9929 "the environment variable is longer than %u characters",
9930 _MAX_ENV);
9931 goto error;
9932 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009933 if (wcslen(env) != (size_t)size) {
9934 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009935 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009936 }
9937
Larry Hastings2f936352014-08-05 14:04:04 +10009938 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009940 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009942
Larry Hastings2f936352014-08-05 14:04:04 +10009943 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009944 Py_RETURN_NONE;
9945
9946error:
Larry Hastings2f936352014-08-05 14:04:04 +10009947 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009948 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009949}
Larry Hastings2f936352014-08-05 14:04:04 +10009950#else /* MS_WINDOWS */
9951/*[clinic input]
9952os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009953
Larry Hastings2f936352014-08-05 14:04:04 +10009954 name: FSConverter
9955 value: FSConverter
9956 /
9957
9958Change or add an environment variable.
9959[clinic start generated code]*/
9960
Larry Hastings2f936352014-08-05 14:04:04 +10009961static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009962os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9963/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009964{
9965 PyObject *bytes = NULL;
9966 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009967 const char *name_string = PyBytes_AS_STRING(name);
9968 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009969
Serhiy Storchaka77703942017-06-25 07:33:01 +03009970 if (strchr(name_string, '=') != NULL) {
9971 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9972 return NULL;
9973 }
Larry Hastings2f936352014-08-05 14:04:04 +10009974 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9975 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009976 return NULL;
9977 }
9978
9979 env = PyBytes_AS_STRING(bytes);
9980 if (putenv(env)) {
9981 Py_DECREF(bytes);
9982 return posix_error();
9983 }
9984
9985 posix_putenv_garbage_setitem(name, bytes);
9986 Py_RETURN_NONE;
9987}
9988#endif /* MS_WINDOWS */
9989#endif /* HAVE_PUTENV */
9990
9991
9992#ifdef HAVE_UNSETENV
9993/*[clinic input]
9994os.unsetenv
9995 name: FSConverter
9996 /
9997
9998Delete an environment variable.
9999[clinic start generated code]*/
10000
Larry Hastings2f936352014-08-05 14:04:04 +100010001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010002os_unsetenv_impl(PyObject *module, PyObject *name)
10003/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010004{
Victor Stinner984890f2011-11-24 13:53:38 +010010005#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +010010006 int err;
Victor Stinner984890f2011-11-24 13:53:38 +010010007#endif
Victor Stinner84ae1182010-05-06 22:05:07 +000010008
Victor Stinner984890f2011-11-24 13:53:38 +010010009#ifdef HAVE_BROKEN_UNSETENV
10010 unsetenv(PyBytes_AS_STRING(name));
10011#else
Victor Stinner65170952011-11-22 22:16:17 +010010012 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +100010013 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +010010014 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +010010015#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010016
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 /* Remove the key from posix_putenv_garbage;
10018 * this will cause it to be collected. This has to
10019 * happen after the real unsetenv() call because the
10020 * old value was still accessible until then.
10021 */
Victor Stinner65170952011-11-22 22:16:17 +010010022 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 /* really not much we can do; just leak */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +020010024 if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
10025 return NULL;
10026 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 PyErr_Clear();
10028 }
Victor Stinner84ae1182010-05-06 22:05:07 +000010029 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010030}
Larry Hastings2f936352014-08-05 14:04:04 +100010031#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +000010032
Larry Hastings2f936352014-08-05 14:04:04 +100010033
10034/*[clinic input]
10035os.strerror
10036
10037 code: int
10038 /
10039
10040Translate an error code to a message string.
10041[clinic start generated code]*/
10042
Larry Hastings2f936352014-08-05 14:04:04 +100010043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010044os_strerror_impl(PyObject *module, int code)
10045/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010046{
10047 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 if (message == NULL) {
10049 PyErr_SetString(PyExc_ValueError,
10050 "strerror() argument out of range");
10051 return NULL;
10052 }
Victor Stinner1b579672011-12-17 05:47:23 +010010053 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010054}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010055
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010056
Guido van Rossumc9641791998-08-04 15:26:23 +000010057#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010058#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010059/*[clinic input]
10060os.WCOREDUMP -> bool
10061
10062 status: int
10063 /
10064
10065Return True if the process returning status was dumped to a core file.
10066[clinic start generated code]*/
10067
Larry Hastings2f936352014-08-05 14:04:04 +100010068static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010069os_WCOREDUMP_impl(PyObject *module, int status)
10070/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010071{
10072 WAIT_TYPE wait_status;
10073 WAIT_STATUS_INT(wait_status) = status;
10074 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010075}
10076#endif /* WCOREDUMP */
10077
Larry Hastings2f936352014-08-05 14:04:04 +100010078
Fred Drake106c1a02002-04-23 15:58:02 +000010079#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010080/*[clinic input]
10081os.WIFCONTINUED -> bool
10082
10083 status: int
10084
10085Return True if a particular process was continued from a job control stop.
10086
10087Return True if the process returning status was continued from a
10088job control stop.
10089[clinic start generated code]*/
10090
Larry Hastings2f936352014-08-05 14:04:04 +100010091static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010092os_WIFCONTINUED_impl(PyObject *module, int status)
10093/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010094{
10095 WAIT_TYPE wait_status;
10096 WAIT_STATUS_INT(wait_status) = status;
10097 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010098}
10099#endif /* WIFCONTINUED */
10100
Larry Hastings2f936352014-08-05 14:04:04 +100010101
Guido van Rossumc9641791998-08-04 15:26:23 +000010102#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010103/*[clinic input]
10104os.WIFSTOPPED -> bool
10105
10106 status: int
10107
10108Return True if the process returning status was stopped.
10109[clinic start generated code]*/
10110
Larry Hastings2f936352014-08-05 14:04:04 +100010111static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010112os_WIFSTOPPED_impl(PyObject *module, int status)
10113/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010114{
10115 WAIT_TYPE wait_status;
10116 WAIT_STATUS_INT(wait_status) = status;
10117 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010118}
10119#endif /* WIFSTOPPED */
10120
Larry Hastings2f936352014-08-05 14:04:04 +100010121
Guido van Rossumc9641791998-08-04 15:26:23 +000010122#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010123/*[clinic input]
10124os.WIFSIGNALED -> bool
10125
10126 status: int
10127
10128Return True if the process returning status was terminated by a signal.
10129[clinic start generated code]*/
10130
Larry Hastings2f936352014-08-05 14:04:04 +100010131static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010132os_WIFSIGNALED_impl(PyObject *module, int status)
10133/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010134{
10135 WAIT_TYPE wait_status;
10136 WAIT_STATUS_INT(wait_status) = status;
10137 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010138}
10139#endif /* WIFSIGNALED */
10140
Larry Hastings2f936352014-08-05 14:04:04 +100010141
Guido van Rossumc9641791998-08-04 15:26:23 +000010142#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010143/*[clinic input]
10144os.WIFEXITED -> bool
10145
10146 status: int
10147
10148Return True if the process returning status exited via the exit() system call.
10149[clinic start generated code]*/
10150
Larry Hastings2f936352014-08-05 14:04:04 +100010151static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010152os_WIFEXITED_impl(PyObject *module, int status)
10153/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010154{
10155 WAIT_TYPE wait_status;
10156 WAIT_STATUS_INT(wait_status) = status;
10157 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010158}
10159#endif /* WIFEXITED */
10160
Larry Hastings2f936352014-08-05 14:04:04 +100010161
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010162#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010163/*[clinic input]
10164os.WEXITSTATUS -> int
10165
10166 status: int
10167
10168Return the process return code from status.
10169[clinic start generated code]*/
10170
Larry Hastings2f936352014-08-05 14:04:04 +100010171static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010172os_WEXITSTATUS_impl(PyObject *module, int status)
10173/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010174{
10175 WAIT_TYPE wait_status;
10176 WAIT_STATUS_INT(wait_status) = status;
10177 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010178}
10179#endif /* WEXITSTATUS */
10180
Larry Hastings2f936352014-08-05 14:04:04 +100010181
Guido van Rossumc9641791998-08-04 15:26:23 +000010182#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010183/*[clinic input]
10184os.WTERMSIG -> int
10185
10186 status: int
10187
10188Return the signal that terminated the process that provided the status value.
10189[clinic start generated code]*/
10190
Larry Hastings2f936352014-08-05 14:04:04 +100010191static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010192os_WTERMSIG_impl(PyObject *module, int status)
10193/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010194{
10195 WAIT_TYPE wait_status;
10196 WAIT_STATUS_INT(wait_status) = status;
10197 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010198}
10199#endif /* WTERMSIG */
10200
Larry Hastings2f936352014-08-05 14:04:04 +100010201
Guido van Rossumc9641791998-08-04 15:26:23 +000010202#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010203/*[clinic input]
10204os.WSTOPSIG -> int
10205
10206 status: int
10207
10208Return the signal that stopped the process that provided the status value.
10209[clinic start generated code]*/
10210
Larry Hastings2f936352014-08-05 14:04:04 +100010211static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010212os_WSTOPSIG_impl(PyObject *module, int status)
10213/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010214{
10215 WAIT_TYPE wait_status;
10216 WAIT_STATUS_INT(wait_status) = status;
10217 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010218}
10219#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010220#endif /* HAVE_SYS_WAIT_H */
10221
10222
Thomas Wouters477c8d52006-05-27 19:21:47 +000010223#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010224#ifdef _SCO_DS
10225/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10226 needed definitions in sys/statvfs.h */
10227#define _SVID3
10228#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010229#include <sys/statvfs.h>
10230
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010231static PyObject*
10232_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -080010233 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 if (v == NULL)
10235 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010236
10237#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10239 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10240 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10241 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10242 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10243 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10244 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10245 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10246 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10247 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010248#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010249 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10250 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10251 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010252 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010254 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010256 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010258 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010260 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010262 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10264 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010265#endif
Michael Felt502d5512018-01-05 13:01:58 +010010266/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10267 * (issue #32390). */
10268#if defined(_AIX) && defined(_ALL_SOURCE)
10269 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10270#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010271 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010272#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010273 if (PyErr_Occurred()) {
10274 Py_DECREF(v);
10275 return NULL;
10276 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010277
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010279}
10280
Larry Hastings2f936352014-08-05 14:04:04 +100010281
10282/*[clinic input]
10283os.fstatvfs
10284 fd: int
10285 /
10286
10287Perform an fstatvfs system call on the given fd.
10288
10289Equivalent to statvfs(fd).
10290[clinic start generated code]*/
10291
Larry Hastings2f936352014-08-05 14:04:04 +100010292static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010293os_fstatvfs_impl(PyObject *module, int fd)
10294/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010295{
10296 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010297 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010299
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010300 do {
10301 Py_BEGIN_ALLOW_THREADS
10302 result = fstatvfs(fd, &st);
10303 Py_END_ALLOW_THREADS
10304 } while (result != 0 && errno == EINTR &&
10305 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010306 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010307 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010308
Victor Stinner8c62be82010-05-06 00:08:46 +000010309 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010310}
Larry Hastings2f936352014-08-05 14:04:04 +100010311#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010312
10313
Thomas Wouters477c8d52006-05-27 19:21:47 +000010314#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010315#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010316/*[clinic input]
10317os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010318
Larry Hastings2f936352014-08-05 14:04:04 +100010319 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10320
10321Perform a statvfs system call on the given path.
10322
10323path may always be specified as a string.
10324On some platforms, path may also be specified as an open file descriptor.
10325 If this functionality is unavailable, using it raises an exception.
10326[clinic start generated code]*/
10327
Larry Hastings2f936352014-08-05 14:04:04 +100010328static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010329os_statvfs_impl(PyObject *module, path_t *path)
10330/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010331{
10332 int result;
10333 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010334
10335 Py_BEGIN_ALLOW_THREADS
10336#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010337 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010338#ifdef __APPLE__
10339 /* handle weak-linking on Mac OS X 10.3 */
10340 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010341 fd_specified("statvfs", path->fd);
10342 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010343 }
10344#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010345 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010346 }
10347 else
10348#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010349 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010350 Py_END_ALLOW_THREADS
10351
10352 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010353 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010354 }
10355
Larry Hastings2f936352014-08-05 14:04:04 +100010356 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010357}
Larry Hastings2f936352014-08-05 14:04:04 +100010358#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10359
Guido van Rossum94f6f721999-01-06 18:42:14 +000010360
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010361#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010362/*[clinic input]
10363os._getdiskusage
10364
Steve Dower23ad6d02018-02-22 10:39:10 -080010365 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010366
10367Return disk usage statistics about the given path as a (total, free) tuple.
10368[clinic start generated code]*/
10369
Larry Hastings2f936352014-08-05 14:04:04 +100010370static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010371os__getdiskusage_impl(PyObject *module, path_t *path)
10372/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010373{
10374 BOOL retval;
10375 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010376 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010377
10378 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010379 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010380 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010381 if (retval == 0) {
10382 if (GetLastError() == ERROR_DIRECTORY) {
10383 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010384
Joe Pamerc8c02492018-09-25 10:57:36 -040010385 dir_path = PyMem_New(wchar_t, path->length + 1);
10386 if (dir_path == NULL) {
10387 return PyErr_NoMemory();
10388 }
10389
10390 wcscpy_s(dir_path, path->length + 1, path->wide);
10391
10392 if (_dirnameW(dir_path) != -1) {
10393 Py_BEGIN_ALLOW_THREADS
10394 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10395 Py_END_ALLOW_THREADS
10396 }
10397 /* Record the last error in case it's modified by PyMem_Free. */
10398 err = GetLastError();
10399 PyMem_Free(dir_path);
10400 if (retval) {
10401 goto success;
10402 }
10403 }
10404 return PyErr_SetFromWindowsErr(err);
10405 }
10406
10407success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010408 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10409}
Larry Hastings2f936352014-08-05 14:04:04 +100010410#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010411
10412
Fred Drakec9680921999-12-13 16:37:25 +000010413/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10414 * It maps strings representing configuration variable names to
10415 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010416 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010417 * rarely-used constants. There are three separate tables that use
10418 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010419 *
10420 * This code is always included, even if none of the interfaces that
10421 * need it are included. The #if hackery needed to avoid it would be
10422 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010423 */
10424struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010425 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010426 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010427};
10428
Fred Drake12c6e2d1999-12-14 21:25:03 +000010429static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010430conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010431 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010432{
Christian Heimes217cfd12007-12-02 14:31:20 +000010433 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010434 int value = _PyLong_AsInt(arg);
10435 if (value == -1 && PyErr_Occurred())
10436 return 0;
10437 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010438 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010439 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010440 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010441 /* look up the value in the table using a binary search */
10442 size_t lo = 0;
10443 size_t mid;
10444 size_t hi = tablesize;
10445 int cmp;
10446 const char *confname;
10447 if (!PyUnicode_Check(arg)) {
10448 PyErr_SetString(PyExc_TypeError,
10449 "configuration names must be strings or integers");
10450 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010452 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010453 if (confname == NULL)
10454 return 0;
10455 while (lo < hi) {
10456 mid = (lo + hi) / 2;
10457 cmp = strcmp(confname, table[mid].name);
10458 if (cmp < 0)
10459 hi = mid;
10460 else if (cmp > 0)
10461 lo = mid + 1;
10462 else {
10463 *valuep = table[mid].value;
10464 return 1;
10465 }
10466 }
10467 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10468 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010470}
10471
10472
10473#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10474static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010475#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010477#endif
10478#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010480#endif
Fred Drakec9680921999-12-13 16:37:25 +000010481#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010483#endif
10484#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010486#endif
10487#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010489#endif
10490#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010492#endif
10493#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010494 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010495#endif
10496#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010498#endif
10499#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010500 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010501#endif
10502#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010504#endif
10505#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010506 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010507#endif
10508#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010510#endif
10511#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010513#endif
10514#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010515 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010516#endif
10517#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010518 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010519#endif
10520#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010521 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010522#endif
10523#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010525#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010526#ifdef _PC_ACL_ENABLED
10527 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10528#endif
10529#ifdef _PC_MIN_HOLE_SIZE
10530 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10531#endif
10532#ifdef _PC_ALLOC_SIZE_MIN
10533 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10534#endif
10535#ifdef _PC_REC_INCR_XFER_SIZE
10536 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10537#endif
10538#ifdef _PC_REC_MAX_XFER_SIZE
10539 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10540#endif
10541#ifdef _PC_REC_MIN_XFER_SIZE
10542 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10543#endif
10544#ifdef _PC_REC_XFER_ALIGN
10545 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10546#endif
10547#ifdef _PC_SYMLINK_MAX
10548 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10549#endif
10550#ifdef _PC_XATTR_ENABLED
10551 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10552#endif
10553#ifdef _PC_XATTR_EXISTS
10554 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10555#endif
10556#ifdef _PC_TIMESTAMP_RESOLUTION
10557 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10558#endif
Fred Drakec9680921999-12-13 16:37:25 +000010559};
10560
Fred Drakec9680921999-12-13 16:37:25 +000010561static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010562conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010563{
10564 return conv_confname(arg, valuep, posix_constants_pathconf,
10565 sizeof(posix_constants_pathconf)
10566 / sizeof(struct constdef));
10567}
10568#endif
10569
Larry Hastings2f936352014-08-05 14:04:04 +100010570
Fred Drakec9680921999-12-13 16:37:25 +000010571#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010572/*[clinic input]
10573os.fpathconf -> long
10574
10575 fd: int
10576 name: path_confname
10577 /
10578
10579Return the configuration limit name for the file descriptor fd.
10580
10581If there is no limit, return -1.
10582[clinic start generated code]*/
10583
Larry Hastings2f936352014-08-05 14:04:04 +100010584static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010585os_fpathconf_impl(PyObject *module, int fd, int name)
10586/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010587{
10588 long limit;
10589
10590 errno = 0;
10591 limit = fpathconf(fd, name);
10592 if (limit == -1 && errno != 0)
10593 posix_error();
10594
10595 return limit;
10596}
10597#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010598
10599
10600#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010601/*[clinic input]
10602os.pathconf -> long
10603 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10604 name: path_confname
10605
10606Return the configuration limit name for the file or directory path.
10607
10608If there is no limit, return -1.
10609On some platforms, path may also be specified as an open file descriptor.
10610 If this functionality is unavailable, using it raises an exception.
10611[clinic start generated code]*/
10612
Larry Hastings2f936352014-08-05 14:04:04 +100010613static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010614os_pathconf_impl(PyObject *module, path_t *path, int name)
10615/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010616{
Victor Stinner8c62be82010-05-06 00:08:46 +000010617 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010618
Victor Stinner8c62be82010-05-06 00:08:46 +000010619 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010620#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010621 if (path->fd != -1)
10622 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010623 else
10624#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010625 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010626 if (limit == -1 && errno != 0) {
10627 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010628 /* could be a path or name problem */
10629 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010630 else
Larry Hastings2f936352014-08-05 14:04:04 +100010631 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010632 }
Larry Hastings2f936352014-08-05 14:04:04 +100010633
10634 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010635}
Larry Hastings2f936352014-08-05 14:04:04 +100010636#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010637
10638#ifdef HAVE_CONFSTR
10639static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010640#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010641 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010642#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010643#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010644 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010645#endif
10646#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010647 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010648#endif
Fred Draked86ed291999-12-15 15:34:33 +000010649#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010650 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010651#endif
10652#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010653 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010654#endif
10655#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010657#endif
10658#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010659 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010660#endif
Fred Drakec9680921999-12-13 16:37:25 +000010661#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010662 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010663#endif
10664#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010665 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010666#endif
10667#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010668 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010669#endif
10670#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010671 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010672#endif
10673#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010674 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010675#endif
10676#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010677 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010678#endif
10679#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010680 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010681#endif
10682#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010683 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010684#endif
Fred Draked86ed291999-12-15 15:34:33 +000010685#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010686 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010687#endif
Fred Drakec9680921999-12-13 16:37:25 +000010688#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010689 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010690#endif
Fred Draked86ed291999-12-15 15:34:33 +000010691#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010692 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010693#endif
10694#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010695 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010696#endif
10697#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010698 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010699#endif
10700#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010701 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010702#endif
Fred Drakec9680921999-12-13 16:37:25 +000010703#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010704 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010705#endif
10706#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010707 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010708#endif
10709#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010710 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010711#endif
10712#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010713 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010714#endif
10715#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010716 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010717#endif
10718#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010719 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010720#endif
10721#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010722 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010723#endif
10724#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010725 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010726#endif
10727#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010728 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010729#endif
10730#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010731 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010732#endif
10733#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010734 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010735#endif
10736#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010737 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010738#endif
10739#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010740 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010741#endif
10742#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010743 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010744#endif
10745#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010746 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010747#endif
10748#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010749 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010750#endif
Fred Draked86ed291999-12-15 15:34:33 +000010751#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010752 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010753#endif
10754#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010755 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010756#endif
10757#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010758 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010759#endif
10760#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010761 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010762#endif
10763#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010764 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010765#endif
10766#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010767 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010768#endif
10769#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010770 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010771#endif
10772#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010773 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010774#endif
10775#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010776 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010777#endif
10778#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010779 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010780#endif
10781#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010782 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010783#endif
10784#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010785 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010786#endif
10787#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010788 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010789#endif
Fred Drakec9680921999-12-13 16:37:25 +000010790};
10791
10792static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010793conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010794{
10795 return conv_confname(arg, valuep, posix_constants_confstr,
10796 sizeof(posix_constants_confstr)
10797 / sizeof(struct constdef));
10798}
10799
Larry Hastings2f936352014-08-05 14:04:04 +100010800
10801/*[clinic input]
10802os.confstr
10803
10804 name: confstr_confname
10805 /
10806
10807Return a string-valued system configuration variable.
10808[clinic start generated code]*/
10809
Larry Hastings2f936352014-08-05 14:04:04 +100010810static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010811os_confstr_impl(PyObject *module, int name)
10812/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010813{
10814 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010815 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010816 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010817
Victor Stinnercb043522010-09-10 23:49:04 +000010818 errno = 0;
10819 len = confstr(name, buffer, sizeof(buffer));
10820 if (len == 0) {
10821 if (errno) {
10822 posix_error();
10823 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010824 }
10825 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010826 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010827 }
10828 }
Victor Stinnercb043522010-09-10 23:49:04 +000010829
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010830 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010831 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010832 char *buf = PyMem_Malloc(len);
10833 if (buf == NULL)
10834 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010835 len2 = confstr(name, buf, len);
10836 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010837 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010838 PyMem_Free(buf);
10839 }
10840 else
10841 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010842 return result;
10843}
Larry Hastings2f936352014-08-05 14:04:04 +100010844#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010845
10846
10847#ifdef HAVE_SYSCONF
10848static struct constdef posix_constants_sysconf[] = {
10849#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010851#endif
10852#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010854#endif
10855#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010857#endif
10858#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010859 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010860#endif
10861#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010862 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010863#endif
10864#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010865 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010866#endif
10867#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010868 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010869#endif
10870#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010871 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010872#endif
10873#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010874 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010875#endif
10876#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010877 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010878#endif
Fred Draked86ed291999-12-15 15:34:33 +000010879#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010880 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010881#endif
10882#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010883 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010884#endif
Fred Drakec9680921999-12-13 16:37:25 +000010885#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010886 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010887#endif
Fred Drakec9680921999-12-13 16:37:25 +000010888#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010889 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010890#endif
10891#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010892 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010893#endif
10894#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010895 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010896#endif
10897#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010899#endif
10900#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010901 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010902#endif
Fred Draked86ed291999-12-15 15:34:33 +000010903#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010905#endif
Fred Drakec9680921999-12-13 16:37:25 +000010906#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010908#endif
10909#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010910 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010911#endif
10912#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010914#endif
10915#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010917#endif
10918#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010920#endif
Fred Draked86ed291999-12-15 15:34:33 +000010921#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010923#endif
Fred Drakec9680921999-12-13 16:37:25 +000010924#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010925 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010926#endif
10927#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010928 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010929#endif
10930#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010931 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010932#endif
10933#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010934 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010935#endif
10936#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010937 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010938#endif
10939#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010940 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010941#endif
10942#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010943 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010944#endif
10945#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010946 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010947#endif
10948#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010949 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010950#endif
10951#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010952 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010953#endif
10954#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010955 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010956#endif
10957#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010958 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010959#endif
10960#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010961 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010962#endif
10963#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010964 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010965#endif
10966#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010967 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010968#endif
10969#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010971#endif
10972#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010973 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010974#endif
10975#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010977#endif
10978#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010979 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010980#endif
10981#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010983#endif
10984#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010985 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010986#endif
10987#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010988 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010989#endif
10990#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010991 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010992#endif
Fred Draked86ed291999-12-15 15:34:33 +000010993#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010994 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010995#endif
Fred Drakec9680921999-12-13 16:37:25 +000010996#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010997 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010998#endif
10999#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011000 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011001#endif
11002#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011003 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011004#endif
Fred Draked86ed291999-12-15 15:34:33 +000011005#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011006 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011007#endif
Fred Drakec9680921999-12-13 16:37:25 +000011008#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011009 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011010#endif
Fred Draked86ed291999-12-15 15:34:33 +000011011#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011012 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011013#endif
11014#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011015 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011016#endif
Fred Drakec9680921999-12-13 16:37:25 +000011017#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011018 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011019#endif
11020#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011021 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011022#endif
11023#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011024 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011025#endif
11026#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011027 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011028#endif
Fred Draked86ed291999-12-15 15:34:33 +000011029#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011030 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011031#endif
Fred Drakec9680921999-12-13 16:37:25 +000011032#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011033 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011034#endif
11035#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011036 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011037#endif
11038#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011039 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011040#endif
11041#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011042 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011043#endif
11044#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011045 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011046#endif
11047#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011048 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011049#endif
11050#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011051 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011052#endif
Fred Draked86ed291999-12-15 15:34:33 +000011053#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011054 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011055#endif
Fred Drakec9680921999-12-13 16:37:25 +000011056#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011057 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011058#endif
11059#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011060 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011061#endif
Fred Draked86ed291999-12-15 15:34:33 +000011062#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011063 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011064#endif
Fred Drakec9680921999-12-13 16:37:25 +000011065#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011066 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011067#endif
11068#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011069 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011070#endif
11071#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011072 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011073#endif
11074#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011075 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011076#endif
11077#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011078 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011079#endif
11080#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011081 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011082#endif
11083#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011084 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011085#endif
11086#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011087 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011088#endif
11089#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011090 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011091#endif
Fred Draked86ed291999-12-15 15:34:33 +000011092#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011093 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011094#endif
11095#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011096 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011097#endif
Fred Drakec9680921999-12-13 16:37:25 +000011098#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011099 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011100#endif
11101#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011102 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011103#endif
11104#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011105 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011106#endif
11107#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011108 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011109#endif
11110#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011111 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011112#endif
11113#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011114 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011115#endif
11116#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011117 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011118#endif
11119#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011120 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011121#endif
11122#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011123 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011124#endif
11125#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011126 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011127#endif
11128#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011129 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011130#endif
11131#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011132 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011133#endif
11134#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011135 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011136#endif
11137#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011138 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011139#endif
11140#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011141 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011142#endif
11143#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011144 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011145#endif
11146#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011147 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011148#endif
11149#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011150 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011151#endif
11152#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011153 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011154#endif
11155#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011156 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011157#endif
11158#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011159 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011160#endif
11161#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011162 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011163#endif
11164#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011165 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011166#endif
11167#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011168 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011169#endif
11170#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011171 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011172#endif
11173#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011174 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011175#endif
11176#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011177 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011178#endif
11179#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011180 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011181#endif
11182#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011183 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011184#endif
11185#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011186 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011187#endif
11188#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011189 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011190#endif
11191#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011192 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011193#endif
11194#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011195 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011196#endif
11197#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011198 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011199#endif
11200#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011201 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011202#endif
Fred Draked86ed291999-12-15 15:34:33 +000011203#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011204 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011205#endif
Fred Drakec9680921999-12-13 16:37:25 +000011206#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011207 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011208#endif
11209#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011210 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011211#endif
11212#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011213 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011214#endif
11215#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011216 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011217#endif
11218#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011219 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011220#endif
11221#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011222 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011223#endif
11224#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011225 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011226#endif
11227#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011228 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011229#endif
11230#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011231 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011232#endif
11233#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011234 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011235#endif
11236#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011237 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011238#endif
11239#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011240 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011241#endif
11242#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011243 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011244#endif
11245#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011246 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011247#endif
11248#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011249 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011250#endif
11251#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011252 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011253#endif
11254#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011255 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011256#endif
11257#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011258 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011259#endif
11260#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011261 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011262#endif
11263#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011264 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011265#endif
11266#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011267 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011268#endif
11269#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011270 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011271#endif
11272#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011273 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011274#endif
11275#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011276 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011277#endif
11278#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011279 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011280#endif
11281#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011282 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011283#endif
11284#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011285 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011286#endif
11287#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011288 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011289#endif
11290#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011291 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011292#endif
11293#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011294 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011295#endif
11296#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011297 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011298#endif
11299#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011300 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011301#endif
11302#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011303 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011304#endif
11305#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011306 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011307#endif
11308#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011309 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011310#endif
11311#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011313#endif
11314#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011315 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011316#endif
11317#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011318 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011319#endif
11320#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011321 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011322#endif
11323#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011324 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011325#endif
11326#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011327 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011328#endif
11329#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011330 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011331#endif
11332#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011334#endif
11335#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011336 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011337#endif
11338#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011339 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011340#endif
11341};
11342
11343static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011344conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011345{
11346 return conv_confname(arg, valuep, posix_constants_sysconf,
11347 sizeof(posix_constants_sysconf)
11348 / sizeof(struct constdef));
11349}
11350
Larry Hastings2f936352014-08-05 14:04:04 +100011351
11352/*[clinic input]
11353os.sysconf -> long
11354 name: sysconf_confname
11355 /
11356
11357Return an integer-valued system configuration variable.
11358[clinic start generated code]*/
11359
Larry Hastings2f936352014-08-05 14:04:04 +100011360static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011361os_sysconf_impl(PyObject *module, int name)
11362/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011363{
11364 long value;
11365
11366 errno = 0;
11367 value = sysconf(name);
11368 if (value == -1 && errno != 0)
11369 posix_error();
11370 return value;
11371}
11372#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011373
11374
Fred Drakebec628d1999-12-15 18:31:10 +000011375/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011376 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011377 * the exported dictionaries that are used to publish information about the
11378 * names available on the host platform.
11379 *
11380 * Sorting the table at runtime ensures that the table is properly ordered
11381 * when used, even for platforms we're not able to test on. It also makes
11382 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011383 */
Fred Drakebec628d1999-12-15 18:31:10 +000011384
11385static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011386cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011387{
11388 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011389 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011390 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011392
11393 return strcmp(c1->name, c2->name);
11394}
11395
11396static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011397setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011398 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011399{
Fred Drakebec628d1999-12-15 18:31:10 +000011400 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011401 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011402
11403 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11404 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011405 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011406 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011407
Barry Warsaw3155db32000-04-13 15:20:40 +000011408 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011409 PyObject *o = PyLong_FromLong(table[i].value);
11410 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11411 Py_XDECREF(o);
11412 Py_DECREF(d);
11413 return -1;
11414 }
11415 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011416 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011417 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011418}
11419
Fred Drakebec628d1999-12-15 18:31:10 +000011420/* Return -1 on failure, 0 on success. */
11421static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011422setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011423{
11424#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011425 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011426 sizeof(posix_constants_pathconf)
11427 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011428 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011429 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011430#endif
11431#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011432 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011433 sizeof(posix_constants_confstr)
11434 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011435 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011436 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011437#endif
11438#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011439 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011440 sizeof(posix_constants_sysconf)
11441 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011442 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011443 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011444#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011445 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011446}
Fred Draked86ed291999-12-15 15:34:33 +000011447
11448
Larry Hastings2f936352014-08-05 14:04:04 +100011449/*[clinic input]
11450os.abort
11451
11452Abort the interpreter immediately.
11453
11454This function 'dumps core' or otherwise fails in the hardest way possible
11455on the hosting operating system. This function never returns.
11456[clinic start generated code]*/
11457
Larry Hastings2f936352014-08-05 14:04:04 +100011458static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011459os_abort_impl(PyObject *module)
11460/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011461{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011462 abort();
11463 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011464#ifndef __clang__
11465 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11466 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11467 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011468 Py_FatalError("abort() called from Python code didn't abort!");
11469 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011470#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011471}
Fred Drakebec628d1999-12-15 18:31:10 +000011472
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011473#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011474/* Grab ShellExecute dynamically from shell32 */
11475static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011476static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11477 LPCWSTR, INT);
11478static int
11479check_ShellExecute()
11480{
11481 HINSTANCE hShell32;
11482
11483 /* only recheck */
11484 if (-1 == has_ShellExecute) {
11485 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011486 /* Security note: this call is not vulnerable to "DLL hijacking".
11487 SHELL32 is part of "KnownDLLs" and so Windows always load
11488 the system SHELL32.DLL, even if there is another SHELL32.DLL
11489 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011490 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011491 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011492 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11493 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011494 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011495 } else {
11496 has_ShellExecute = 0;
11497 }
Tony Roberts4860f012019-02-02 18:16:42 +010011498 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011499 }
11500 return has_ShellExecute;
11501}
11502
11503
Steve Dowercc16be82016-09-08 10:35:16 -070011504/*[clinic input]
11505os.startfile
11506 filepath: path_t
11507 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011508
Steve Dowercc16be82016-09-08 10:35:16 -070011509startfile(filepath [, operation])
11510
11511Start a file with its associated application.
11512
11513When "operation" is not specified or "open", this acts like
11514double-clicking the file in Explorer, or giving the file name as an
11515argument to the DOS "start" command: the file is opened with whatever
11516application (if any) its extension is associated.
11517When another "operation" is given, it specifies what should be done with
11518the file. A typical operation is "print".
11519
11520startfile returns as soon as the associated application is launched.
11521There is no option to wait for the application to close, and no way
11522to retrieve the application's exit status.
11523
11524The filepath is relative to the current directory. If you want to use
11525an absolute path, make sure the first character is not a slash ("/");
11526the underlying Win32 ShellExecute function doesn't work if it is.
11527[clinic start generated code]*/
11528
11529static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011530os_startfile_impl(PyObject *module, path_t *filepath,
11531 const Py_UNICODE *operation)
11532/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011533{
11534 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011535
11536 if(!check_ShellExecute()) {
11537 /* If the OS doesn't have ShellExecute, return a
11538 NotImplementedError. */
11539 return PyErr_Format(PyExc_NotImplementedError,
11540 "startfile not available on this platform");
11541 }
11542
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011544 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011545 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 Py_END_ALLOW_THREADS
11547
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011549 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011550 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011551 }
Steve Dowercc16be82016-09-08 10:35:16 -070011552 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011553}
Larry Hastings2f936352014-08-05 14:04:04 +100011554#endif /* MS_WINDOWS */
11555
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011556
Martin v. Löwis438b5342002-12-27 10:16:42 +000011557#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011558/*[clinic input]
11559os.getloadavg
11560
11561Return average recent system load information.
11562
11563Return the number of processes in the system run queue averaged over
11564the last 1, 5, and 15 minutes as a tuple of three floats.
11565Raises OSError if the load average was unobtainable.
11566[clinic start generated code]*/
11567
Larry Hastings2f936352014-08-05 14:04:04 +100011568static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011569os_getloadavg_impl(PyObject *module)
11570/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011571{
11572 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011573 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011574 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11575 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011576 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011577 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011578}
Larry Hastings2f936352014-08-05 14:04:04 +100011579#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011580
Larry Hastings2f936352014-08-05 14:04:04 +100011581
11582/*[clinic input]
11583os.device_encoding
11584 fd: int
11585
11586Return a string describing the encoding of a terminal's file descriptor.
11587
11588The file descriptor must be attached to a terminal.
11589If the device is not a terminal, return None.
11590[clinic start generated code]*/
11591
Larry Hastings2f936352014-08-05 14:04:04 +100011592static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011593os_device_encoding_impl(PyObject *module, int fd)
11594/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011595{
Brett Cannonefb00c02012-02-29 18:31:31 -050011596 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011597}
11598
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011599
Larry Hastings2f936352014-08-05 14:04:04 +100011600#ifdef HAVE_SETRESUID
11601/*[clinic input]
11602os.setresuid
11603
11604 ruid: uid_t
11605 euid: uid_t
11606 suid: uid_t
11607 /
11608
11609Set the current process's real, effective, and saved user ids.
11610[clinic start generated code]*/
11611
Larry Hastings2f936352014-08-05 14:04:04 +100011612static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011613os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11614/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011615{
Victor Stinner8c62be82010-05-06 00:08:46 +000011616 if (setresuid(ruid, euid, suid) < 0)
11617 return posix_error();
11618 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011619}
Larry Hastings2f936352014-08-05 14:04:04 +100011620#endif /* HAVE_SETRESUID */
11621
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011622
11623#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011624/*[clinic input]
11625os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011626
Larry Hastings2f936352014-08-05 14:04:04 +100011627 rgid: gid_t
11628 egid: gid_t
11629 sgid: gid_t
11630 /
11631
11632Set the current process's real, effective, and saved group ids.
11633[clinic start generated code]*/
11634
Larry Hastings2f936352014-08-05 14:04:04 +100011635static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011636os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11637/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011638{
Victor Stinner8c62be82010-05-06 00:08:46 +000011639 if (setresgid(rgid, egid, sgid) < 0)
11640 return posix_error();
11641 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011642}
Larry Hastings2f936352014-08-05 14:04:04 +100011643#endif /* HAVE_SETRESGID */
11644
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011645
11646#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011647/*[clinic input]
11648os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011649
Larry Hastings2f936352014-08-05 14:04:04 +100011650Return a tuple of the current process's real, effective, and saved user ids.
11651[clinic start generated code]*/
11652
Larry Hastings2f936352014-08-05 14:04:04 +100011653static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011654os_getresuid_impl(PyObject *module)
11655/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011656{
Victor Stinner8c62be82010-05-06 00:08:46 +000011657 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011658 if (getresuid(&ruid, &euid, &suid) < 0)
11659 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011660 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11661 _PyLong_FromUid(euid),
11662 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011663}
Larry Hastings2f936352014-08-05 14:04:04 +100011664#endif /* HAVE_GETRESUID */
11665
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011666
11667#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011668/*[clinic input]
11669os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011670
Larry Hastings2f936352014-08-05 14:04:04 +100011671Return a tuple of the current process's real, effective, and saved group ids.
11672[clinic start generated code]*/
11673
Larry Hastings2f936352014-08-05 14:04:04 +100011674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011675os_getresgid_impl(PyObject *module)
11676/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011677{
11678 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011679 if (getresgid(&rgid, &egid, &sgid) < 0)
11680 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011681 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11682 _PyLong_FromGid(egid),
11683 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011684}
Larry Hastings2f936352014-08-05 14:04:04 +100011685#endif /* HAVE_GETRESGID */
11686
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011687
Benjamin Peterson9428d532011-09-14 11:45:52 -040011688#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011689/*[clinic input]
11690os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011691
Larry Hastings2f936352014-08-05 14:04:04 +100011692 path: path_t(allow_fd=True)
11693 attribute: path_t
11694 *
11695 follow_symlinks: bool = True
11696
11697Return the value of extended attribute attribute on path.
11698
BNMetricsb9427072018-11-02 15:20:19 +000011699path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011700If follow_symlinks is False, and the last element of the path is a symbolic
11701 link, getxattr will examine the symbolic link itself instead of the file
11702 the link points to.
11703
11704[clinic start generated code]*/
11705
Larry Hastings2f936352014-08-05 14:04:04 +100011706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011707os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011708 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011709/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011710{
11711 Py_ssize_t i;
11712 PyObject *buffer = NULL;
11713
11714 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11715 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011716
Larry Hastings9cf065c2012-06-22 16:30:09 -070011717 for (i = 0; ; i++) {
11718 void *ptr;
11719 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011720 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011721 Py_ssize_t buffer_size = buffer_sizes[i];
11722 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011723 path_error(path);
11724 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011725 }
11726 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11727 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011728 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011729 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011730
Larry Hastings9cf065c2012-06-22 16:30:09 -070011731 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011732 if (path->fd >= 0)
11733 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011734 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011735 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011736 else
Larry Hastings2f936352014-08-05 14:04:04 +100011737 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011738 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011739
Larry Hastings9cf065c2012-06-22 16:30:09 -070011740 if (result < 0) {
11741 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011742 if (errno == ERANGE)
11743 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011744 path_error(path);
11745 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011746 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011747
Larry Hastings9cf065c2012-06-22 16:30:09 -070011748 if (result != buffer_size) {
11749 /* Can only shrink. */
11750 _PyBytes_Resize(&buffer, result);
11751 }
11752 break;
11753 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011754
Larry Hastings9cf065c2012-06-22 16:30:09 -070011755 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011756}
11757
Larry Hastings2f936352014-08-05 14:04:04 +100011758
11759/*[clinic input]
11760os.setxattr
11761
11762 path: path_t(allow_fd=True)
11763 attribute: path_t
11764 value: Py_buffer
11765 flags: int = 0
11766 *
11767 follow_symlinks: bool = True
11768
11769Set extended attribute attribute on path to value.
11770
BNMetricsb9427072018-11-02 15:20:19 +000011771path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011772If follow_symlinks is False, and the last element of the path is a symbolic
11773 link, setxattr will modify the symbolic link itself instead of the file
11774 the link points to.
11775
11776[clinic start generated code]*/
11777
Benjamin Peterson799bd802011-08-31 22:15:17 -040011778static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011779os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011780 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011781/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011782{
Larry Hastings2f936352014-08-05 14:04:04 +100011783 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011784
Larry Hastings2f936352014-08-05 14:04:04 +100011785 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011786 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011787
Benjamin Peterson799bd802011-08-31 22:15:17 -040011788 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011789 if (path->fd > -1)
11790 result = fsetxattr(path->fd, attribute->narrow,
11791 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011792 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011793 result = setxattr(path->narrow, attribute->narrow,
11794 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011795 else
Larry Hastings2f936352014-08-05 14:04:04 +100011796 result = lsetxattr(path->narrow, attribute->narrow,
11797 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011798 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011799
Larry Hastings9cf065c2012-06-22 16:30:09 -070011800 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011801 path_error(path);
11802 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011803 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011804
Larry Hastings2f936352014-08-05 14:04:04 +100011805 Py_RETURN_NONE;
11806}
11807
11808
11809/*[clinic input]
11810os.removexattr
11811
11812 path: path_t(allow_fd=True)
11813 attribute: path_t
11814 *
11815 follow_symlinks: bool = True
11816
11817Remove extended attribute attribute on path.
11818
BNMetricsb9427072018-11-02 15:20:19 +000011819path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011820If follow_symlinks is False, and the last element of the path is a symbolic
11821 link, removexattr will modify the symbolic link itself instead of the file
11822 the link points to.
11823
11824[clinic start generated code]*/
11825
Larry Hastings2f936352014-08-05 14:04:04 +100011826static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011827os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011828 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011829/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011830{
11831 ssize_t result;
11832
11833 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11834 return NULL;
11835
11836 Py_BEGIN_ALLOW_THREADS;
11837 if (path->fd > -1)
11838 result = fremovexattr(path->fd, attribute->narrow);
11839 else if (follow_symlinks)
11840 result = removexattr(path->narrow, attribute->narrow);
11841 else
11842 result = lremovexattr(path->narrow, attribute->narrow);
11843 Py_END_ALLOW_THREADS;
11844
11845 if (result) {
11846 return path_error(path);
11847 }
11848
11849 Py_RETURN_NONE;
11850}
11851
11852
11853/*[clinic input]
11854os.listxattr
11855
11856 path: path_t(allow_fd=True, nullable=True) = None
11857 *
11858 follow_symlinks: bool = True
11859
11860Return a list of extended attributes on path.
11861
BNMetricsb9427072018-11-02 15:20:19 +000011862path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011863if path is None, listxattr will examine the current directory.
11864If follow_symlinks is False, and the last element of the path is a symbolic
11865 link, listxattr will examine the symbolic link itself instead of the file
11866 the link points to.
11867[clinic start generated code]*/
11868
Larry Hastings2f936352014-08-05 14:04:04 +100011869static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011870os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011871/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011872{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011873 Py_ssize_t i;
11874 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011875 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011876 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011877
Larry Hastings2f936352014-08-05 14:04:04 +100011878 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011879 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011880
Larry Hastings2f936352014-08-05 14:04:04 +100011881 name = path->narrow ? path->narrow : ".";
11882
Larry Hastings9cf065c2012-06-22 16:30:09 -070011883 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011884 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011885 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011886 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011887 Py_ssize_t buffer_size = buffer_sizes[i];
11888 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011889 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011890 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011891 break;
11892 }
11893 buffer = PyMem_MALLOC(buffer_size);
11894 if (!buffer) {
11895 PyErr_NoMemory();
11896 break;
11897 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011898
Larry Hastings9cf065c2012-06-22 16:30:09 -070011899 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011900 if (path->fd > -1)
11901 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011902 else if (follow_symlinks)
11903 length = listxattr(name, buffer, buffer_size);
11904 else
11905 length = llistxattr(name, buffer, buffer_size);
11906 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011907
Larry Hastings9cf065c2012-06-22 16:30:09 -070011908 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011909 if (errno == ERANGE) {
11910 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011911 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011912 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011913 }
Larry Hastings2f936352014-08-05 14:04:04 +100011914 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011915 break;
11916 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011917
Larry Hastings9cf065c2012-06-22 16:30:09 -070011918 result = PyList_New(0);
11919 if (!result) {
11920 goto exit;
11921 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011922
Larry Hastings9cf065c2012-06-22 16:30:09 -070011923 end = buffer + length;
11924 for (trace = start = buffer; trace != end; trace++) {
11925 if (!*trace) {
11926 int error;
11927 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11928 trace - start);
11929 if (!attribute) {
11930 Py_DECREF(result);
11931 result = NULL;
11932 goto exit;
11933 }
11934 error = PyList_Append(result, attribute);
11935 Py_DECREF(attribute);
11936 if (error) {
11937 Py_DECREF(result);
11938 result = NULL;
11939 goto exit;
11940 }
11941 start = trace + 1;
11942 }
11943 }
11944 break;
11945 }
11946exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011947 if (buffer)
11948 PyMem_FREE(buffer);
11949 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011950}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011951#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011952
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011953
Larry Hastings2f936352014-08-05 14:04:04 +100011954/*[clinic input]
11955os.urandom
11956
11957 size: Py_ssize_t
11958 /
11959
11960Return a bytes object containing random bytes suitable for cryptographic use.
11961[clinic start generated code]*/
11962
Larry Hastings2f936352014-08-05 14:04:04 +100011963static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011964os_urandom_impl(PyObject *module, Py_ssize_t size)
11965/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011966{
11967 PyObject *bytes;
11968 int result;
11969
Georg Brandl2fb477c2012-02-21 00:33:36 +010011970 if (size < 0)
11971 return PyErr_Format(PyExc_ValueError,
11972 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011973 bytes = PyBytes_FromStringAndSize(NULL, size);
11974 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011975 return NULL;
11976
Victor Stinnere66987e2016-09-06 16:33:52 -070011977 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011978 if (result == -1) {
11979 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011980 return NULL;
11981 }
Larry Hastings2f936352014-08-05 14:04:04 +100011982 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011983}
11984
Zackery Spytz43fdbd22019-05-29 13:57:07 -060011985#ifdef HAVE_MEMFD_CREATE
11986/*[clinic input]
11987os.memfd_create
11988
11989 name: FSConverter
11990 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
11991
11992[clinic start generated code]*/
11993
11994static PyObject *
11995os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
11996/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
11997{
11998 int fd;
11999 const char *bytes = PyBytes_AS_STRING(name);
12000 Py_BEGIN_ALLOW_THREADS
12001 fd = memfd_create(bytes, flags);
12002 Py_END_ALLOW_THREADS
12003 if (fd == -1) {
12004 return PyErr_SetFromErrno(PyExc_OSError);
12005 }
12006 return PyLong_FromLong(fd);
12007}
12008#endif
12009
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012010/* Terminal size querying */
12011
Eddie Elizondo474eedf2018-11-13 04:09:31 -080012012static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012013
12014PyDoc_STRVAR(TerminalSize_docstring,
12015 "A tuple of (columns, lines) for holding terminal window size");
12016
12017static PyStructSequence_Field TerminalSize_fields[] = {
12018 {"columns", "width of the terminal window in characters"},
12019 {"lines", "height of the terminal window in characters"},
12020 {NULL, NULL}
12021};
12022
12023static PyStructSequence_Desc TerminalSize_desc = {
12024 "os.terminal_size",
12025 TerminalSize_docstring,
12026 TerminalSize_fields,
12027 2,
12028};
12029
12030#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100012031/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012032PyDoc_STRVAR(termsize__doc__,
12033 "Return the size of the terminal window as (columns, lines).\n" \
12034 "\n" \
12035 "The optional argument fd (default standard output) specifies\n" \
12036 "which file descriptor should be queried.\n" \
12037 "\n" \
12038 "If the file descriptor is not connected to a terminal, an OSError\n" \
12039 "is thrown.\n" \
12040 "\n" \
12041 "This function will only be defined if an implementation is\n" \
12042 "available for this system.\n" \
12043 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080012044 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012045 "normally be used, os.get_terminal_size is the low-level implementation.");
12046
12047static PyObject*
12048get_terminal_size(PyObject *self, PyObject *args)
12049{
12050 int columns, lines;
12051 PyObject *termsize;
12052
12053 int fd = fileno(stdout);
12054 /* Under some conditions stdout may not be connected and
12055 * fileno(stdout) may point to an invalid file descriptor. For example
12056 * GUI apps don't have valid standard streams by default.
12057 *
12058 * If this happens, and the optional fd argument is not present,
12059 * the ioctl below will fail returning EBADF. This is what we want.
12060 */
12061
12062 if (!PyArg_ParseTuple(args, "|i", &fd))
12063 return NULL;
12064
12065#ifdef TERMSIZE_USE_IOCTL
12066 {
12067 struct winsize w;
12068 if (ioctl(fd, TIOCGWINSZ, &w))
12069 return PyErr_SetFromErrno(PyExc_OSError);
12070 columns = w.ws_col;
12071 lines = w.ws_row;
12072 }
12073#endif /* TERMSIZE_USE_IOCTL */
12074
12075#ifdef TERMSIZE_USE_CONIO
12076 {
12077 DWORD nhandle;
12078 HANDLE handle;
12079 CONSOLE_SCREEN_BUFFER_INFO csbi;
12080 switch (fd) {
12081 case 0: nhandle = STD_INPUT_HANDLE;
12082 break;
12083 case 1: nhandle = STD_OUTPUT_HANDLE;
12084 break;
12085 case 2: nhandle = STD_ERROR_HANDLE;
12086 break;
12087 default:
12088 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12089 }
12090 handle = GetStdHandle(nhandle);
12091 if (handle == NULL)
12092 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12093 if (handle == INVALID_HANDLE_VALUE)
12094 return PyErr_SetFromWindowsErr(0);
12095
12096 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12097 return PyErr_SetFromWindowsErr(0);
12098
12099 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12100 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12101 }
12102#endif /* TERMSIZE_USE_CONIO */
12103
Eddie Elizondo474eedf2018-11-13 04:09:31 -080012104 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012105 if (termsize == NULL)
12106 return NULL;
12107 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12108 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12109 if (PyErr_Occurred()) {
12110 Py_DECREF(termsize);
12111 return NULL;
12112 }
12113 return termsize;
12114}
12115#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12116
Larry Hastings2f936352014-08-05 14:04:04 +100012117
12118/*[clinic input]
12119os.cpu_count
12120
Charles-François Natali80d62e62015-08-13 20:37:08 +010012121Return the number of CPUs in the system; return None if indeterminable.
12122
12123This number is not equivalent to the number of CPUs the current process can
12124use. The number of usable CPUs can be obtained with
12125``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012126[clinic start generated code]*/
12127
Larry Hastings2f936352014-08-05 14:04:04 +100012128static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012129os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012130/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012131{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012132 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012133#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012134 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
12135 Need to fallback to Vista behavior if this call isn't present */
12136 HINSTANCE hKernel32;
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012137 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
Tony Roberts4860f012019-02-02 18:16:42 +010012138 Py_BEGIN_ALLOW_THREADS
12139 hKernel32 = GetModuleHandleW(L"KERNEL32");
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012140 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
12141 "GetMaximumProcessorCount");
Tony Roberts4860f012019-02-02 18:16:42 +010012142 Py_END_ALLOW_THREADS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012143 if (_GetMaximumProcessorCount != NULL) {
12144 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
12145 }
12146 else {
12147 SYSTEM_INFO sysinfo;
12148 GetSystemInfo(&sysinfo);
12149 ncpu = sysinfo.dwNumberOfProcessors;
12150 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012151#elif defined(__hpux)
12152 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12153#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12154 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012155#elif defined(__DragonFly__) || \
12156 defined(__OpenBSD__) || \
12157 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012158 defined(__NetBSD__) || \
12159 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012160 int mib[2];
12161 size_t len = sizeof(ncpu);
12162 mib[0] = CTL_HW;
12163 mib[1] = HW_NCPU;
12164 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12165 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012166#endif
12167 if (ncpu >= 1)
12168 return PyLong_FromLong(ncpu);
12169 else
12170 Py_RETURN_NONE;
12171}
12172
Victor Stinnerdaf45552013-08-28 00:53:59 +020012173
Larry Hastings2f936352014-08-05 14:04:04 +100012174/*[clinic input]
12175os.get_inheritable -> bool
12176
12177 fd: int
12178 /
12179
12180Get the close-on-exe flag of the specified file descriptor.
12181[clinic start generated code]*/
12182
Larry Hastings2f936352014-08-05 14:04:04 +100012183static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012184os_get_inheritable_impl(PyObject *module, int fd)
12185/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012186{
Steve Dower8fc89802015-04-12 00:26:27 -040012187 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012188 _Py_BEGIN_SUPPRESS_IPH
12189 return_value = _Py_get_inheritable(fd);
12190 _Py_END_SUPPRESS_IPH
12191 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012192}
12193
12194
12195/*[clinic input]
12196os.set_inheritable
12197 fd: int
12198 inheritable: int
12199 /
12200
12201Set the inheritable flag of the specified file descriptor.
12202[clinic start generated code]*/
12203
Larry Hastings2f936352014-08-05 14:04:04 +100012204static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012205os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12206/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012207{
Steve Dower8fc89802015-04-12 00:26:27 -040012208 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012209
Steve Dower8fc89802015-04-12 00:26:27 -040012210 _Py_BEGIN_SUPPRESS_IPH
12211 result = _Py_set_inheritable(fd, inheritable, NULL);
12212 _Py_END_SUPPRESS_IPH
12213 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012214 return NULL;
12215 Py_RETURN_NONE;
12216}
12217
12218
12219#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012220/*[clinic input]
12221os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012222 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012223 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012224
Larry Hastings2f936352014-08-05 14:04:04 +100012225Get the close-on-exe flag of the specified file descriptor.
12226[clinic start generated code]*/
12227
Larry Hastings2f936352014-08-05 14:04:04 +100012228static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012229os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012230/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012231{
12232 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012233
12234 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12235 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012236 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012237 }
12238
Larry Hastings2f936352014-08-05 14:04:04 +100012239 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012240}
12241
Victor Stinnerdaf45552013-08-28 00:53:59 +020012242
Larry Hastings2f936352014-08-05 14:04:04 +100012243/*[clinic input]
12244os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012245 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012246 inheritable: bool
12247 /
12248
12249Set the inheritable flag of the specified handle.
12250[clinic start generated code]*/
12251
Larry Hastings2f936352014-08-05 14:04:04 +100012252static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012253os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012254 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012255/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012256{
12257 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012258 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12259 PyErr_SetFromWindowsErr(0);
12260 return NULL;
12261 }
12262 Py_RETURN_NONE;
12263}
Larry Hastings2f936352014-08-05 14:04:04 +100012264#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012265
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012266#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012267/*[clinic input]
12268os.get_blocking -> bool
12269 fd: int
12270 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012271
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012272Get the blocking mode of the file descriptor.
12273
12274Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12275[clinic start generated code]*/
12276
12277static int
12278os_get_blocking_impl(PyObject *module, int fd)
12279/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012280{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012281 int blocking;
12282
Steve Dower8fc89802015-04-12 00:26:27 -040012283 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012284 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012285 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012286 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012287}
12288
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012289/*[clinic input]
12290os.set_blocking
12291 fd: int
12292 blocking: bool(accept={int})
12293 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012294
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012295Set the blocking mode of the specified file descriptor.
12296
12297Set the O_NONBLOCK flag if blocking is False,
12298clear the O_NONBLOCK flag otherwise.
12299[clinic start generated code]*/
12300
12301static PyObject *
12302os_set_blocking_impl(PyObject *module, int fd, int blocking)
12303/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012304{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012305 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012306
Steve Dower8fc89802015-04-12 00:26:27 -040012307 _Py_BEGIN_SUPPRESS_IPH
12308 result = _Py_set_blocking(fd, blocking);
12309 _Py_END_SUPPRESS_IPH
12310 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012311 return NULL;
12312 Py_RETURN_NONE;
12313}
12314#endif /* !MS_WINDOWS */
12315
12316
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012317/*[clinic input]
12318class os.DirEntry "DirEntry *" "&DirEntryType"
12319[clinic start generated code]*/
12320/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012321
12322typedef struct {
12323 PyObject_HEAD
12324 PyObject *name;
12325 PyObject *path;
12326 PyObject *stat;
12327 PyObject *lstat;
12328#ifdef MS_WINDOWS
12329 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012330 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012331 int got_file_index;
12332#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012333#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012334 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012335#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012336 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012337 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012338#endif
12339} DirEntry;
12340
12341static void
12342DirEntry_dealloc(DirEntry *entry)
12343{
12344 Py_XDECREF(entry->name);
12345 Py_XDECREF(entry->path);
12346 Py_XDECREF(entry->stat);
12347 Py_XDECREF(entry->lstat);
12348 Py_TYPE(entry)->tp_free((PyObject *)entry);
12349}
12350
12351/* Forward reference */
12352static int
12353DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12354
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012355/*[clinic input]
12356os.DirEntry.is_symlink -> bool
12357
12358Return True if the entry is a symbolic link; cached per entry.
12359[clinic start generated code]*/
12360
Victor Stinner6036e442015-03-08 01:58:04 +010012361static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012362os_DirEntry_is_symlink_impl(DirEntry *self)
12363/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012364{
12365#ifdef MS_WINDOWS
12366 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012367#elif defined(HAVE_DIRENT_D_TYPE)
12368 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012369 if (self->d_type != DT_UNKNOWN)
12370 return self->d_type == DT_LNK;
12371 else
12372 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012373#else
12374 /* POSIX without d_type */
12375 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012376#endif
12377}
12378
12379static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012380DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12381{
12382 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012383 STRUCT_STAT st;
12384 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012385
12386#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012387 if (!PyUnicode_FSDecoder(self->path, &ub))
12388 return NULL;
12389 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012390#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012391 if (!PyUnicode_FSConverter(self->path, &ub))
12392 return NULL;
12393 const char *path = PyBytes_AS_STRING(ub);
12394 if (self->dir_fd != DEFAULT_DIR_FD) {
12395#ifdef HAVE_FSTATAT
12396 result = fstatat(self->dir_fd, path, &st,
12397 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12398#else
12399 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12400 return NULL;
12401#endif /* HAVE_FSTATAT */
12402 }
12403 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012404#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012405 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012406 if (follow_symlinks)
12407 result = STAT(path, &st);
12408 else
12409 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012410 }
12411 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012412
12413 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012414 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012415
12416 return _pystat_fromstructstat(&st);
12417}
12418
12419static PyObject *
12420DirEntry_get_lstat(DirEntry *self)
12421{
12422 if (!self->lstat) {
12423#ifdef MS_WINDOWS
12424 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12425#else /* POSIX */
12426 self->lstat = DirEntry_fetch_stat(self, 0);
12427#endif
12428 }
12429 Py_XINCREF(self->lstat);
12430 return self->lstat;
12431}
12432
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012433/*[clinic input]
12434os.DirEntry.stat
12435 *
12436 follow_symlinks: bool = True
12437
12438Return stat_result object for the entry; cached per entry.
12439[clinic start generated code]*/
12440
Victor Stinner6036e442015-03-08 01:58:04 +010012441static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012442os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12443/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012444{
12445 if (!follow_symlinks)
12446 return DirEntry_get_lstat(self);
12447
12448 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012449 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012450 if (result == -1)
12451 return NULL;
12452 else if (result)
12453 self->stat = DirEntry_fetch_stat(self, 1);
12454 else
12455 self->stat = DirEntry_get_lstat(self);
12456 }
12457
12458 Py_XINCREF(self->stat);
12459 return self->stat;
12460}
12461
Victor Stinner6036e442015-03-08 01:58:04 +010012462/* Set exception and return -1 on error, 0 for False, 1 for True */
12463static int
12464DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12465{
12466 PyObject *stat = NULL;
12467 PyObject *st_mode = NULL;
12468 long mode;
12469 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012470#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012471 int is_symlink;
12472 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012473#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012474#ifdef MS_WINDOWS
12475 unsigned long dir_bits;
12476#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012477 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012478
12479#ifdef MS_WINDOWS
12480 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12481 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012482#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012483 is_symlink = self->d_type == DT_LNK;
12484 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12485#endif
12486
Victor Stinner35a97c02015-03-08 02:59:09 +010012487#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012488 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012489#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012490 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012491 if (!stat) {
12492 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12493 /* If file doesn't exist (anymore), then return False
12494 (i.e., say it's not a file/directory) */
12495 PyErr_Clear();
12496 return 0;
12497 }
12498 goto error;
12499 }
12500 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12501 if (!st_mode)
12502 goto error;
12503
12504 mode = PyLong_AsLong(st_mode);
12505 if (mode == -1 && PyErr_Occurred())
12506 goto error;
12507 Py_CLEAR(st_mode);
12508 Py_CLEAR(stat);
12509 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012510#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012511 }
12512 else if (is_symlink) {
12513 assert(mode_bits != S_IFLNK);
12514 result = 0;
12515 }
12516 else {
12517 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12518#ifdef MS_WINDOWS
12519 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12520 if (mode_bits == S_IFDIR)
12521 result = dir_bits != 0;
12522 else
12523 result = dir_bits == 0;
12524#else /* POSIX */
12525 if (mode_bits == S_IFDIR)
12526 result = self->d_type == DT_DIR;
12527 else
12528 result = self->d_type == DT_REG;
12529#endif
12530 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012531#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012532
12533 return result;
12534
12535error:
12536 Py_XDECREF(st_mode);
12537 Py_XDECREF(stat);
12538 return -1;
12539}
12540
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012541/*[clinic input]
12542os.DirEntry.is_dir -> bool
12543 *
12544 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012545
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012546Return True if the entry is a directory; cached per entry.
12547[clinic start generated code]*/
12548
12549static int
12550os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12551/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12552{
12553 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012554}
12555
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012556/*[clinic input]
12557os.DirEntry.is_file -> bool
12558 *
12559 follow_symlinks: bool = True
12560
12561Return True if the entry is a file; cached per entry.
12562[clinic start generated code]*/
12563
12564static int
12565os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12566/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012567{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012568 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012569}
12570
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012571/*[clinic input]
12572os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012573
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012574Return inode of the entry; cached per entry.
12575[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012576
12577static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012578os_DirEntry_inode_impl(DirEntry *self)
12579/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012580{
12581#ifdef MS_WINDOWS
12582 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012583 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012584 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012585 STRUCT_STAT stat;
12586 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012587
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012588 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012589 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012590 path = PyUnicode_AsUnicode(unicode);
12591 result = LSTAT(path, &stat);
12592 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012593
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012594 if (result != 0)
12595 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012596
12597 self->win32_file_index = stat.st_ino;
12598 self->got_file_index = 1;
12599 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012600 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12601 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012602#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012603 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12604 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012605#endif
12606}
12607
12608static PyObject *
12609DirEntry_repr(DirEntry *self)
12610{
12611 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12612}
12613
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012614/*[clinic input]
12615os.DirEntry.__fspath__
12616
12617Returns the path for the entry.
12618[clinic start generated code]*/
12619
Brett Cannon96881cd2016-06-10 14:37:21 -070012620static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012621os_DirEntry___fspath___impl(DirEntry *self)
12622/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012623{
12624 Py_INCREF(self->path);
12625 return self->path;
12626}
12627
Victor Stinner6036e442015-03-08 01:58:04 +010012628static PyMemberDef DirEntry_members[] = {
12629 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12630 "the entry's base filename, relative to scandir() \"path\" argument"},
12631 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12632 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12633 {NULL}
12634};
12635
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012636#include "clinic/posixmodule.c.h"
12637
Victor Stinner6036e442015-03-08 01:58:04 +010012638static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012639 OS_DIRENTRY_IS_DIR_METHODDEF
12640 OS_DIRENTRY_IS_FILE_METHODDEF
12641 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12642 OS_DIRENTRY_STAT_METHODDEF
12643 OS_DIRENTRY_INODE_METHODDEF
12644 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012645 {NULL}
12646};
12647
Benjamin Peterson5646de42015-04-12 17:56:34 -040012648static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012649 PyVarObject_HEAD_INIT(NULL, 0)
12650 MODNAME ".DirEntry", /* tp_name */
12651 sizeof(DirEntry), /* tp_basicsize */
12652 0, /* tp_itemsize */
12653 /* methods */
12654 (destructor)DirEntry_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020012655 0, /* tp_vectorcall_offset */
Victor Stinner6036e442015-03-08 01:58:04 +010012656 0, /* tp_getattr */
12657 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020012658 0, /* tp_as_async */
Victor Stinner6036e442015-03-08 01:58:04 +010012659 (reprfunc)DirEntry_repr, /* tp_repr */
12660 0, /* tp_as_number */
12661 0, /* tp_as_sequence */
12662 0, /* tp_as_mapping */
12663 0, /* tp_hash */
12664 0, /* tp_call */
12665 0, /* tp_str */
12666 0, /* tp_getattro */
12667 0, /* tp_setattro */
12668 0, /* tp_as_buffer */
12669 Py_TPFLAGS_DEFAULT, /* tp_flags */
12670 0, /* tp_doc */
12671 0, /* tp_traverse */
12672 0, /* tp_clear */
12673 0, /* tp_richcompare */
12674 0, /* tp_weaklistoffset */
12675 0, /* tp_iter */
12676 0, /* tp_iternext */
12677 DirEntry_methods, /* tp_methods */
12678 DirEntry_members, /* tp_members */
12679};
12680
12681#ifdef MS_WINDOWS
12682
12683static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012684join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012685{
12686 Py_ssize_t path_len;
12687 Py_ssize_t size;
12688 wchar_t *result;
12689 wchar_t ch;
12690
12691 if (!path_wide) { /* Default arg: "." */
12692 path_wide = L".";
12693 path_len = 1;
12694 }
12695 else {
12696 path_len = wcslen(path_wide);
12697 }
12698
12699 /* The +1's are for the path separator and the NUL */
12700 size = path_len + 1 + wcslen(filename) + 1;
12701 result = PyMem_New(wchar_t, size);
12702 if (!result) {
12703 PyErr_NoMemory();
12704 return NULL;
12705 }
12706 wcscpy(result, path_wide);
12707 if (path_len > 0) {
12708 ch = result[path_len - 1];
12709 if (ch != SEP && ch != ALTSEP && ch != L':')
12710 result[path_len++] = SEP;
12711 wcscpy(result + path_len, filename);
12712 }
12713 return result;
12714}
12715
12716static PyObject *
12717DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12718{
12719 DirEntry *entry;
12720 BY_HANDLE_FILE_INFORMATION file_info;
12721 ULONG reparse_tag;
12722 wchar_t *joined_path;
12723
12724 entry = PyObject_New(DirEntry, &DirEntryType);
12725 if (!entry)
12726 return NULL;
12727 entry->name = NULL;
12728 entry->path = NULL;
12729 entry->stat = NULL;
12730 entry->lstat = NULL;
12731 entry->got_file_index = 0;
12732
12733 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12734 if (!entry->name)
12735 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012736 if (path->narrow) {
12737 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12738 if (!entry->name)
12739 goto error;
12740 }
Victor Stinner6036e442015-03-08 01:58:04 +010012741
12742 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12743 if (!joined_path)
12744 goto error;
12745
12746 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12747 PyMem_Free(joined_path);
12748 if (!entry->path)
12749 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012750 if (path->narrow) {
12751 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12752 if (!entry->path)
12753 goto error;
12754 }
Victor Stinner6036e442015-03-08 01:58:04 +010012755
Steve Dowercc16be82016-09-08 10:35:16 -070012756 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012757 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12758
12759 return (PyObject *)entry;
12760
12761error:
12762 Py_DECREF(entry);
12763 return NULL;
12764}
12765
12766#else /* POSIX */
12767
12768static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012769join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012770{
12771 Py_ssize_t path_len;
12772 Py_ssize_t size;
12773 char *result;
12774
12775 if (!path_narrow) { /* Default arg: "." */
12776 path_narrow = ".";
12777 path_len = 1;
12778 }
12779 else {
12780 path_len = strlen(path_narrow);
12781 }
12782
12783 if (filename_len == -1)
12784 filename_len = strlen(filename);
12785
12786 /* The +1's are for the path separator and the NUL */
12787 size = path_len + 1 + filename_len + 1;
12788 result = PyMem_New(char, size);
12789 if (!result) {
12790 PyErr_NoMemory();
12791 return NULL;
12792 }
12793 strcpy(result, path_narrow);
12794 if (path_len > 0 && result[path_len - 1] != '/')
12795 result[path_len++] = '/';
12796 strcpy(result + path_len, filename);
12797 return result;
12798}
12799
12800static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012801DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012802 ino_t d_ino
12803#ifdef HAVE_DIRENT_D_TYPE
12804 , unsigned char d_type
12805#endif
12806 )
Victor Stinner6036e442015-03-08 01:58:04 +010012807{
12808 DirEntry *entry;
12809 char *joined_path;
12810
12811 entry = PyObject_New(DirEntry, &DirEntryType);
12812 if (!entry)
12813 return NULL;
12814 entry->name = NULL;
12815 entry->path = NULL;
12816 entry->stat = NULL;
12817 entry->lstat = NULL;
12818
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012819 if (path->fd != -1) {
12820 entry->dir_fd = path->fd;
12821 joined_path = NULL;
12822 }
12823 else {
12824 entry->dir_fd = DEFAULT_DIR_FD;
12825 joined_path = join_path_filename(path->narrow, name, name_len);
12826 if (!joined_path)
12827 goto error;
12828 }
Victor Stinner6036e442015-03-08 01:58:04 +010012829
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012830 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012831 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012832 if (joined_path)
12833 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012834 }
12835 else {
12836 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012837 if (joined_path)
12838 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012839 }
12840 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012841 if (!entry->name)
12842 goto error;
12843
12844 if (path->fd != -1) {
12845 entry->path = entry->name;
12846 Py_INCREF(entry->path);
12847 }
12848 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012849 goto error;
12850
Victor Stinner35a97c02015-03-08 02:59:09 +010012851#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012852 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012853#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012854 entry->d_ino = d_ino;
12855
12856 return (PyObject *)entry;
12857
12858error:
12859 Py_XDECREF(entry);
12860 return NULL;
12861}
12862
12863#endif
12864
12865
12866typedef struct {
12867 PyObject_HEAD
12868 path_t path;
12869#ifdef MS_WINDOWS
12870 HANDLE handle;
12871 WIN32_FIND_DATAW file_data;
12872 int first_time;
12873#else /* POSIX */
12874 DIR *dirp;
12875#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012876#ifdef HAVE_FDOPENDIR
12877 int fd;
12878#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012879} ScandirIterator;
12880
12881#ifdef MS_WINDOWS
12882
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012883static int
12884ScandirIterator_is_closed(ScandirIterator *iterator)
12885{
12886 return iterator->handle == INVALID_HANDLE_VALUE;
12887}
12888
Victor Stinner6036e442015-03-08 01:58:04 +010012889static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012890ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012891{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012892 HANDLE handle = iterator->handle;
12893
12894 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012895 return;
12896
Victor Stinner6036e442015-03-08 01:58:04 +010012897 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012898 Py_BEGIN_ALLOW_THREADS
12899 FindClose(handle);
12900 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012901}
12902
12903static PyObject *
12904ScandirIterator_iternext(ScandirIterator *iterator)
12905{
12906 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12907 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012908 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012909
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012910 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012911 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012912 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012913
12914 while (1) {
12915 if (!iterator->first_time) {
12916 Py_BEGIN_ALLOW_THREADS
12917 success = FindNextFileW(iterator->handle, file_data);
12918 Py_END_ALLOW_THREADS
12919 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012920 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012921 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012922 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012923 break;
12924 }
12925 }
12926 iterator->first_time = 0;
12927
12928 /* Skip over . and .. */
12929 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012930 wcscmp(file_data->cFileName, L"..") != 0) {
12931 entry = DirEntry_from_find_data(&iterator->path, file_data);
12932 if (!entry)
12933 break;
12934 return entry;
12935 }
Victor Stinner6036e442015-03-08 01:58:04 +010012936
12937 /* Loop till we get a non-dot directory or finish iterating */
12938 }
12939
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012940 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012941 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012942 return NULL;
12943}
12944
12945#else /* POSIX */
12946
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012947static int
12948ScandirIterator_is_closed(ScandirIterator *iterator)
12949{
12950 return !iterator->dirp;
12951}
12952
Victor Stinner6036e442015-03-08 01:58:04 +010012953static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012954ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012955{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012956 DIR *dirp = iterator->dirp;
12957
12958 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012959 return;
12960
Victor Stinner6036e442015-03-08 01:58:04 +010012961 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012962 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012963#ifdef HAVE_FDOPENDIR
12964 if (iterator->path.fd != -1)
12965 rewinddir(dirp);
12966#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012967 closedir(dirp);
12968 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012969 return;
12970}
12971
12972static PyObject *
12973ScandirIterator_iternext(ScandirIterator *iterator)
12974{
12975 struct dirent *direntp;
12976 Py_ssize_t name_len;
12977 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012978 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012979
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012980 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012981 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012982 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012983
12984 while (1) {
12985 errno = 0;
12986 Py_BEGIN_ALLOW_THREADS
12987 direntp = readdir(iterator->dirp);
12988 Py_END_ALLOW_THREADS
12989
12990 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012991 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012992 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012993 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012994 break;
12995 }
12996
12997 /* Skip over . and .. */
12998 name_len = NAMLEN(direntp);
12999 is_dot = direntp->d_name[0] == '.' &&
13000 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
13001 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013002 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010013003 name_len, direntp->d_ino
13004#ifdef HAVE_DIRENT_D_TYPE
13005 , direntp->d_type
13006#endif
13007 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013008 if (!entry)
13009 break;
13010 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013011 }
13012
13013 /* Loop till we get a non-dot directory or finish iterating */
13014 }
13015
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013016 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013017 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013018 return NULL;
13019}
13020
13021#endif
13022
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013023static PyObject *
13024ScandirIterator_close(ScandirIterator *self, PyObject *args)
13025{
13026 ScandirIterator_closedir(self);
13027 Py_RETURN_NONE;
13028}
13029
13030static PyObject *
13031ScandirIterator_enter(PyObject *self, PyObject *args)
13032{
13033 Py_INCREF(self);
13034 return self;
13035}
13036
13037static PyObject *
13038ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13039{
13040 ScandirIterator_closedir(self);
13041 Py_RETURN_NONE;
13042}
13043
Victor Stinner6036e442015-03-08 01:58:04 +010013044static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013045ScandirIterator_finalize(ScandirIterator *iterator)
13046{
13047 PyObject *error_type, *error_value, *error_traceback;
13048
13049 /* Save the current exception, if any. */
13050 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13051
13052 if (!ScandirIterator_is_closed(iterator)) {
13053 ScandirIterator_closedir(iterator);
13054
13055 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13056 "unclosed scandir iterator %R", iterator)) {
13057 /* Spurious errors can appear at shutdown */
13058 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13059 PyErr_WriteUnraisable((PyObject *) iterator);
13060 }
13061 }
13062 }
13063
Victor Stinner7bfa4092016-03-23 00:43:54 +010013064 path_cleanup(&iterator->path);
13065
13066 /* Restore the saved exception. */
13067 PyErr_Restore(error_type, error_value, error_traceback);
13068}
13069
13070static void
Victor Stinner6036e442015-03-08 01:58:04 +010013071ScandirIterator_dealloc(ScandirIterator *iterator)
13072{
Victor Stinner7bfa4092016-03-23 00:43:54 +010013073 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13074 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013075
Victor Stinner6036e442015-03-08 01:58:04 +010013076 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
13077}
13078
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013079static PyMethodDef ScandirIterator_methods[] = {
13080 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13081 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13082 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13083 {NULL}
13084};
13085
Benjamin Peterson5646de42015-04-12 17:56:34 -040013086static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010013087 PyVarObject_HEAD_INIT(NULL, 0)
13088 MODNAME ".ScandirIterator", /* tp_name */
13089 sizeof(ScandirIterator), /* tp_basicsize */
13090 0, /* tp_itemsize */
13091 /* methods */
13092 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020013093 0, /* tp_vectorcall_offset */
Victor Stinner6036e442015-03-08 01:58:04 +010013094 0, /* tp_getattr */
13095 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020013096 0, /* tp_as_async */
Victor Stinner6036e442015-03-08 01:58:04 +010013097 0, /* tp_repr */
13098 0, /* tp_as_number */
13099 0, /* tp_as_sequence */
13100 0, /* tp_as_mapping */
13101 0, /* tp_hash */
13102 0, /* tp_call */
13103 0, /* tp_str */
13104 0, /* tp_getattro */
13105 0, /* tp_setattro */
13106 0, /* tp_as_buffer */
Antoine Pitrouada319b2019-05-29 22:12:38 +020013107 Py_TPFLAGS_DEFAULT, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010013108 0, /* tp_doc */
13109 0, /* tp_traverse */
13110 0, /* tp_clear */
13111 0, /* tp_richcompare */
13112 0, /* tp_weaklistoffset */
13113 PyObject_SelfIter, /* tp_iter */
13114 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013115 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010013116 0, /* tp_members */
13117 0, /* tp_getset */
13118 0, /* tp_base */
13119 0, /* tp_dict */
13120 0, /* tp_descr_get */
13121 0, /* tp_descr_set */
13122 0, /* tp_dictoffset */
13123 0, /* tp_init */
13124 0, /* tp_alloc */
13125 0, /* tp_new */
13126 0, /* tp_free */
13127 0, /* tp_is_gc */
13128 0, /* tp_bases */
13129 0, /* tp_mro */
13130 0, /* tp_cache */
13131 0, /* tp_subclasses */
13132 0, /* tp_weaklist */
13133 0, /* tp_del */
13134 0, /* tp_version_tag */
13135 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010013136};
13137
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013138/*[clinic input]
13139os.scandir
13140
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013141 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013142
13143Return an iterator of DirEntry objects for given path.
13144
BNMetricsb9427072018-11-02 15:20:19 +000013145path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013146is bytes, the names of yielded DirEntry objects will also be bytes; in
13147all other circumstances they will be str.
13148
13149If path is None, uses the path='.'.
13150[clinic start generated code]*/
13151
Victor Stinner6036e442015-03-08 01:58:04 +010013152static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013153os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013154/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013155{
13156 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013157#ifdef MS_WINDOWS
13158 wchar_t *path_strW;
13159#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013160 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013161#ifdef HAVE_FDOPENDIR
13162 int fd = -1;
13163#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013164#endif
13165
13166 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
13167 if (!iterator)
13168 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013169
13170#ifdef MS_WINDOWS
13171 iterator->handle = INVALID_HANDLE_VALUE;
13172#else
13173 iterator->dirp = NULL;
13174#endif
13175
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013176 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013177 /* Move the ownership to iterator->path */
13178 path->object = NULL;
13179 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013180
13181#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013182 iterator->first_time = 1;
13183
13184 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13185 if (!path_strW)
13186 goto error;
13187
13188 Py_BEGIN_ALLOW_THREADS
13189 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13190 Py_END_ALLOW_THREADS
13191
13192 PyMem_Free(path_strW);
13193
13194 if (iterator->handle == INVALID_HANDLE_VALUE) {
13195 path_error(&iterator->path);
13196 goto error;
13197 }
13198#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013199 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013200#ifdef HAVE_FDOPENDIR
13201 if (path->fd != -1) {
13202 /* closedir() closes the FD, so we duplicate it */
13203 fd = _Py_dup(path->fd);
13204 if (fd == -1)
13205 goto error;
13206
13207 Py_BEGIN_ALLOW_THREADS
13208 iterator->dirp = fdopendir(fd);
13209 Py_END_ALLOW_THREADS
13210 }
13211 else
13212#endif
13213 {
13214 if (iterator->path.narrow)
13215 path_str = iterator->path.narrow;
13216 else
13217 path_str = ".";
13218
13219 Py_BEGIN_ALLOW_THREADS
13220 iterator->dirp = opendir(path_str);
13221 Py_END_ALLOW_THREADS
13222 }
Victor Stinner6036e442015-03-08 01:58:04 +010013223
13224 if (!iterator->dirp) {
13225 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013226#ifdef HAVE_FDOPENDIR
13227 if (fd != -1) {
13228 Py_BEGIN_ALLOW_THREADS
13229 close(fd);
13230 Py_END_ALLOW_THREADS
13231 }
13232#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013233 goto error;
13234 }
13235#endif
13236
13237 return (PyObject *)iterator;
13238
13239error:
13240 Py_DECREF(iterator);
13241 return NULL;
13242}
13243
Ethan Furman410ef8e2016-06-04 12:06:26 -070013244/*
13245 Return the file system path representation of the object.
13246
13247 If the object is str or bytes, then allow it to pass through with
13248 an incremented refcount. If the object defines __fspath__(), then
13249 return the result of that method. All other types raise a TypeError.
13250*/
13251PyObject *
13252PyOS_FSPath(PyObject *path)
13253{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013254 /* For error message reasons, this function is manually inlined in
13255 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013256 _Py_IDENTIFIER(__fspath__);
13257 PyObject *func = NULL;
13258 PyObject *path_repr = NULL;
13259
13260 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13261 Py_INCREF(path);
13262 return path;
13263 }
13264
13265 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13266 if (NULL == func) {
13267 return PyErr_Format(PyExc_TypeError,
13268 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013269 "not %.200s",
13270 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013271 }
13272
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013273 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013274 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013275 if (NULL == path_repr) {
13276 return NULL;
13277 }
13278
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013279 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13280 PyErr_Format(PyExc_TypeError,
13281 "expected %.200s.__fspath__() to return str or bytes, "
13282 "not %.200s", Py_TYPE(path)->tp_name,
13283 Py_TYPE(path_repr)->tp_name);
13284 Py_DECREF(path_repr);
13285 return NULL;
13286 }
13287
Ethan Furman410ef8e2016-06-04 12:06:26 -070013288 return path_repr;
13289}
13290
13291/*[clinic input]
13292os.fspath
13293
13294 path: object
13295
13296Return the file system path representation of the object.
13297
Brett Cannonb4f43e92016-06-09 14:32:08 -070013298If the object is str or bytes, then allow it to pass through as-is. If the
13299object defines __fspath__(), then return the result of that method. All other
13300types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013301[clinic start generated code]*/
13302
13303static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013304os_fspath_impl(PyObject *module, PyObject *path)
13305/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013306{
13307 return PyOS_FSPath(path);
13308}
Victor Stinner6036e442015-03-08 01:58:04 +010013309
Victor Stinner9b1f4742016-09-06 16:18:52 -070013310#ifdef HAVE_GETRANDOM_SYSCALL
13311/*[clinic input]
13312os.getrandom
13313
13314 size: Py_ssize_t
13315 flags: int=0
13316
13317Obtain a series of random bytes.
13318[clinic start generated code]*/
13319
13320static PyObject *
13321os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13322/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13323{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013324 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013325 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013326
13327 if (size < 0) {
13328 errno = EINVAL;
13329 return posix_error();
13330 }
13331
Victor Stinnerec2319c2016-09-20 23:00:59 +020013332 bytes = PyBytes_FromStringAndSize(NULL, size);
13333 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013334 PyErr_NoMemory();
13335 return NULL;
13336 }
13337
13338 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013339 n = syscall(SYS_getrandom,
13340 PyBytes_AS_STRING(bytes),
13341 PyBytes_GET_SIZE(bytes),
13342 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013343 if (n < 0 && errno == EINTR) {
13344 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013345 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013346 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013347
13348 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013349 continue;
13350 }
13351 break;
13352 }
13353
13354 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013355 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013356 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013357 }
13358
Victor Stinnerec2319c2016-09-20 23:00:59 +020013359 if (n != size) {
13360 _PyBytes_Resize(&bytes, n);
13361 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013362
13363 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013364
13365error:
13366 Py_DECREF(bytes);
13367 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013368}
13369#endif /* HAVE_GETRANDOM_SYSCALL */
13370
Steve Dower2438cdf2019-03-29 16:37:16 -070013371#ifdef MS_WINDOWS
13372/* bpo-36085: Helper functions for managing DLL search directories
13373 * on win32
13374 */
13375
13376typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13377typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13378
13379/*[clinic input]
13380os._add_dll_directory
13381
13382 path: path_t
13383
13384Add a path to the DLL search path.
13385
13386This search path is used when resolving dependencies for imported
13387extension modules (the module itself is resolved through sys.path),
13388and also by ctypes.
13389
13390Returns an opaque value that may be passed to os.remove_dll_directory
13391to remove this directory from the search path.
13392[clinic start generated code]*/
13393
13394static PyObject *
13395os__add_dll_directory_impl(PyObject *module, path_t *path)
13396/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13397{
13398 HMODULE hKernel32;
13399 PAddDllDirectory AddDllDirectory;
13400 DLL_DIRECTORY_COOKIE cookie = 0;
13401 DWORD err = 0;
13402
13403 /* For Windows 7, we have to load this. As this will be a fairly
13404 infrequent operation, just do it each time. Kernel32 is always
13405 loaded. */
13406 Py_BEGIN_ALLOW_THREADS
13407 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13408 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13409 hKernel32, "AddDllDirectory")) ||
13410 !(cookie = (*AddDllDirectory)(path->wide))) {
13411 err = GetLastError();
13412 }
13413 Py_END_ALLOW_THREADS
13414
13415 if (err) {
13416 return win32_error_object_err("add_dll_directory",
13417 path->object, err);
13418 }
13419
13420 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13421}
13422
13423/*[clinic input]
13424os._remove_dll_directory
13425
13426 cookie: object
13427
13428Removes a path from the DLL search path.
13429
13430The parameter is an opaque value that was returned from
13431os.add_dll_directory. You can only remove directories that you added
13432yourself.
13433[clinic start generated code]*/
13434
13435static PyObject *
13436os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13437/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13438{
13439 HMODULE hKernel32;
13440 PRemoveDllDirectory RemoveDllDirectory;
13441 DLL_DIRECTORY_COOKIE cookieValue;
13442 DWORD err = 0;
13443
13444 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13445 PyErr_SetString(PyExc_TypeError,
13446 "Provided cookie was not returned from os.add_dll_directory");
13447 return NULL;
13448 }
13449
13450 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13451 cookie, "DLL directory cookie");
13452
13453 /* For Windows 7, we have to load this. As this will be a fairly
13454 infrequent operation, just do it each time. Kernel32 is always
13455 loaded. */
13456 Py_BEGIN_ALLOW_THREADS
13457 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13458 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13459 hKernel32, "RemoveDllDirectory")) ||
13460 !(*RemoveDllDirectory)(cookieValue)) {
13461 err = GetLastError();
13462 }
13463 Py_END_ALLOW_THREADS
13464
13465 if (err) {
13466 return win32_error_object_err("remove_dll_directory",
13467 NULL, err);
13468 }
13469
13470 if (PyCapsule_SetName(cookie, NULL)) {
13471 return NULL;
13472 }
13473
13474 Py_RETURN_NONE;
13475}
13476
13477#endif
Larry Hastings31826802013-10-19 00:09:25 -070013478
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013479static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013480
13481 OS_STAT_METHODDEF
13482 OS_ACCESS_METHODDEF
13483 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013484 OS_CHDIR_METHODDEF
13485 OS_CHFLAGS_METHODDEF
13486 OS_CHMOD_METHODDEF
13487 OS_FCHMOD_METHODDEF
13488 OS_LCHMOD_METHODDEF
13489 OS_CHOWN_METHODDEF
13490 OS_FCHOWN_METHODDEF
13491 OS_LCHOWN_METHODDEF
13492 OS_LCHFLAGS_METHODDEF
13493 OS_CHROOT_METHODDEF
13494 OS_CTERMID_METHODDEF
13495 OS_GETCWD_METHODDEF
13496 OS_GETCWDB_METHODDEF
13497 OS_LINK_METHODDEF
13498 OS_LISTDIR_METHODDEF
13499 OS_LSTAT_METHODDEF
13500 OS_MKDIR_METHODDEF
13501 OS_NICE_METHODDEF
13502 OS_GETPRIORITY_METHODDEF
13503 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013504 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013505 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013506 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010013507 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013508 OS_RENAME_METHODDEF
13509 OS_REPLACE_METHODDEF
13510 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013511 OS_SYMLINK_METHODDEF
13512 OS_SYSTEM_METHODDEF
13513 OS_UMASK_METHODDEF
13514 OS_UNAME_METHODDEF
13515 OS_UNLINK_METHODDEF
13516 OS_REMOVE_METHODDEF
13517 OS_UTIME_METHODDEF
13518 OS_TIMES_METHODDEF
13519 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013520 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013521 OS_EXECV_METHODDEF
13522 OS_EXECVE_METHODDEF
13523 OS_SPAWNV_METHODDEF
13524 OS_SPAWNVE_METHODDEF
13525 OS_FORK1_METHODDEF
13526 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013527 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013528 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13529 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13530 OS_SCHED_GETPARAM_METHODDEF
13531 OS_SCHED_GETSCHEDULER_METHODDEF
13532 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13533 OS_SCHED_SETPARAM_METHODDEF
13534 OS_SCHED_SETSCHEDULER_METHODDEF
13535 OS_SCHED_YIELD_METHODDEF
13536 OS_SCHED_SETAFFINITY_METHODDEF
13537 OS_SCHED_GETAFFINITY_METHODDEF
13538 OS_OPENPTY_METHODDEF
13539 OS_FORKPTY_METHODDEF
13540 OS_GETEGID_METHODDEF
13541 OS_GETEUID_METHODDEF
13542 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013543#ifdef HAVE_GETGROUPLIST
13544 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13545#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013546 OS_GETGROUPS_METHODDEF
13547 OS_GETPID_METHODDEF
13548 OS_GETPGRP_METHODDEF
13549 OS_GETPPID_METHODDEF
13550 OS_GETUID_METHODDEF
13551 OS_GETLOGIN_METHODDEF
13552 OS_KILL_METHODDEF
13553 OS_KILLPG_METHODDEF
13554 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013555#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013556 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013557#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013558 OS_SETUID_METHODDEF
13559 OS_SETEUID_METHODDEF
13560 OS_SETREUID_METHODDEF
13561 OS_SETGID_METHODDEF
13562 OS_SETEGID_METHODDEF
13563 OS_SETREGID_METHODDEF
13564 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013565#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013566 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013567#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013568 OS_GETPGID_METHODDEF
13569 OS_SETPGRP_METHODDEF
13570 OS_WAIT_METHODDEF
13571 OS_WAIT3_METHODDEF
13572 OS_WAIT4_METHODDEF
13573 OS_WAITID_METHODDEF
13574 OS_WAITPID_METHODDEF
13575 OS_GETSID_METHODDEF
13576 OS_SETSID_METHODDEF
13577 OS_SETPGID_METHODDEF
13578 OS_TCGETPGRP_METHODDEF
13579 OS_TCSETPGRP_METHODDEF
13580 OS_OPEN_METHODDEF
13581 OS_CLOSE_METHODDEF
13582 OS_CLOSERANGE_METHODDEF
13583 OS_DEVICE_ENCODING_METHODDEF
13584 OS_DUP_METHODDEF
13585 OS_DUP2_METHODDEF
13586 OS_LOCKF_METHODDEF
13587 OS_LSEEK_METHODDEF
13588 OS_READ_METHODDEF
13589 OS_READV_METHODDEF
13590 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013591 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013592 OS_WRITE_METHODDEF
13593 OS_WRITEV_METHODDEF
13594 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013595 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013596#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013597 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013598 posix_sendfile__doc__},
13599#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013600 OS_FSTAT_METHODDEF
13601 OS_ISATTY_METHODDEF
13602 OS_PIPE_METHODDEF
13603 OS_PIPE2_METHODDEF
13604 OS_MKFIFO_METHODDEF
13605 OS_MKNOD_METHODDEF
13606 OS_MAJOR_METHODDEF
13607 OS_MINOR_METHODDEF
13608 OS_MAKEDEV_METHODDEF
13609 OS_FTRUNCATE_METHODDEF
13610 OS_TRUNCATE_METHODDEF
13611 OS_POSIX_FALLOCATE_METHODDEF
13612 OS_POSIX_FADVISE_METHODDEF
13613 OS_PUTENV_METHODDEF
13614 OS_UNSETENV_METHODDEF
13615 OS_STRERROR_METHODDEF
13616 OS_FCHDIR_METHODDEF
13617 OS_FSYNC_METHODDEF
13618 OS_SYNC_METHODDEF
13619 OS_FDATASYNC_METHODDEF
13620 OS_WCOREDUMP_METHODDEF
13621 OS_WIFCONTINUED_METHODDEF
13622 OS_WIFSTOPPED_METHODDEF
13623 OS_WIFSIGNALED_METHODDEF
13624 OS_WIFEXITED_METHODDEF
13625 OS_WEXITSTATUS_METHODDEF
13626 OS_WTERMSIG_METHODDEF
13627 OS_WSTOPSIG_METHODDEF
13628 OS_FSTATVFS_METHODDEF
13629 OS_STATVFS_METHODDEF
13630 OS_CONFSTR_METHODDEF
13631 OS_SYSCONF_METHODDEF
13632 OS_FPATHCONF_METHODDEF
13633 OS_PATHCONF_METHODDEF
13634 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013635 OS__GETFULLPATHNAME_METHODDEF
13636 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013637 OS__GETDISKUSAGE_METHODDEF
13638 OS__GETFINALPATHNAME_METHODDEF
13639 OS__GETVOLUMEPATHNAME_METHODDEF
13640 OS_GETLOADAVG_METHODDEF
13641 OS_URANDOM_METHODDEF
13642 OS_SETRESUID_METHODDEF
13643 OS_SETRESGID_METHODDEF
13644 OS_GETRESUID_METHODDEF
13645 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013646
Larry Hastings2f936352014-08-05 14:04:04 +100013647 OS_GETXATTR_METHODDEF
13648 OS_SETXATTR_METHODDEF
13649 OS_REMOVEXATTR_METHODDEF
13650 OS_LISTXATTR_METHODDEF
13651
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013652#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13653 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13654#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013655 OS_CPU_COUNT_METHODDEF
13656 OS_GET_INHERITABLE_METHODDEF
13657 OS_SET_INHERITABLE_METHODDEF
13658 OS_GET_HANDLE_INHERITABLE_METHODDEF
13659 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013660#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013661 OS_GET_BLOCKING_METHODDEF
13662 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013663#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013664 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013665 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013666 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060013667 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070013668#ifdef MS_WINDOWS
13669 OS__ADD_DLL_DIRECTORY_METHODDEF
13670 OS__REMOVE_DLL_DIRECTORY_METHODDEF
13671#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013672 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013673};
13674
Barry Warsaw4a342091996-12-19 23:50:02 +000013675static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013676all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013677{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013678#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013679 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013680#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013681#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013682 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013683#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013684#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013685 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013686#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013687#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013688 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013689#endif
Fred Drakec9680921999-12-13 16:37:25 +000013690#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013691 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013692#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013693#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013694 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013695#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013696#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013697 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013698#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013699#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013700 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013701#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013702#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013703 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013704#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013705#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013706 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013707#endif
13708#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013709 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013710#endif
13711#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013712 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013713#endif
13714#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013715 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013716#endif
13717#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013718 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013719#endif
13720#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013721 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013722#endif
13723#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013724 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013725#endif
13726#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013727 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013728#endif
13729#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013730 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013731#endif
13732#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013733 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013734#endif
13735#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013736 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013737#endif
13738#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013739 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013740#endif
13741#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013742 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013743#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013744#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013745 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013746#endif
13747#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013748 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013749#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013750#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013751 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013752#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013753#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013754 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013755#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013756#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013757#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013758 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013759#endif
13760#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013761 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013762#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013763#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013764#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013765 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013766#endif
13767#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013768 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013769#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013770#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013771 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013772#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013773#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013774 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013775#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013776#ifdef O_TMPFILE
13777 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13778#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013779#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013780 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013781#endif
13782#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013783 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013784#endif
13785#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013786 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013787#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013788#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013789 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013790#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013791#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013792 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013793#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013794
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013795
Jesus Cea94363612012-06-22 18:32:07 +020013796#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013797 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013798#endif
13799#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013800 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013801#endif
13802
Tim Peters5aa91602002-01-30 05:46:57 +000013803/* MS Windows */
13804#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013805 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013806 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013807#endif
13808#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013809 /* Optimize for short life (keep in memory). */
13810 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013811 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013812#endif
13813#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013814 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013815 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013816#endif
13817#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013818 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013819 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013820#endif
13821#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013822 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013823 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013824#endif
13825
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013826/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013827#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013828 /* Send a SIGIO signal whenever input or output
13829 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013830 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013831#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013832#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013833 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013834 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013835#endif
13836#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013837 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013838 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013839#endif
13840#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013841 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013842 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013843#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013844#ifdef O_NOLINKS
13845 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013846 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013847#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013848#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013849 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013850 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013851#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013852
Victor Stinner8c62be82010-05-06 00:08:46 +000013853 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013854#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013855 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013856#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013857#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013858 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013859#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013860#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013861 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013862#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013863#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013864 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013865#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013866#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013867 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013868#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013869#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013870 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013871#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013872#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013873 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013874#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013875#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013876 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013877#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013878#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013879 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013880#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013881#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013882 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013883#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013884#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013885 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013886#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013887#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013888 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013889#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013890#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013891 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013892#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013893#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013894 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013895#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013896#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013897 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013898#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013899#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013900 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013901#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013902#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013903 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013904#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013905
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013906 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013907#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013908 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013909#endif /* ST_RDONLY */
13910#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013911 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013912#endif /* ST_NOSUID */
13913
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013914 /* GNU extensions */
13915#ifdef ST_NODEV
13916 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13917#endif /* ST_NODEV */
13918#ifdef ST_NOEXEC
13919 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13920#endif /* ST_NOEXEC */
13921#ifdef ST_SYNCHRONOUS
13922 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13923#endif /* ST_SYNCHRONOUS */
13924#ifdef ST_MANDLOCK
13925 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13926#endif /* ST_MANDLOCK */
13927#ifdef ST_WRITE
13928 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13929#endif /* ST_WRITE */
13930#ifdef ST_APPEND
13931 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13932#endif /* ST_APPEND */
13933#ifdef ST_NOATIME
13934 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13935#endif /* ST_NOATIME */
13936#ifdef ST_NODIRATIME
13937 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13938#endif /* ST_NODIRATIME */
13939#ifdef ST_RELATIME
13940 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13941#endif /* ST_RELATIME */
13942
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013943 /* FreeBSD sendfile() constants */
13944#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013945 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013946#endif
13947#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013948 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013949#endif
13950#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013951 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013952#endif
13953
Ross Lagerwall7807c352011-03-17 20:20:30 +020013954 /* constants for posix_fadvise */
13955#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013956 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013957#endif
13958#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013959 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013960#endif
13961#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013962 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013963#endif
13964#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013965 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013966#endif
13967#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013968 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013969#endif
13970#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013971 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013972#endif
13973
13974 /* constants for waitid */
13975#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013976 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13977 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13978 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013979#endif
13980#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013981 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013982#endif
13983#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013984 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013985#endif
13986#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013987 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013988#endif
13989#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013990 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013991#endif
13992#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013993 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013994#endif
13995#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013996 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013997#endif
13998#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013999 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014000#endif
14001
14002 /* constants for lockf */
14003#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014004 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014005#endif
14006#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014007 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014008#endif
14009#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014010 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014011#endif
14012#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014013 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014014#endif
14015
Pablo Galindo4defba32018-01-27 16:16:37 +000014016#ifdef RWF_DSYNC
14017 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14018#endif
14019#ifdef RWF_HIPRI
14020 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14021#endif
14022#ifdef RWF_SYNC
14023 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14024#endif
14025#ifdef RWF_NOWAIT
14026 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14027#endif
14028
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014029/* constants for posix_spawn */
14030#ifdef HAVE_POSIX_SPAWN
14031 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14032 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14033 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14034#endif
14035
pxinwrf2d7ac72019-05-21 18:46:37 +080014036#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014037 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14038 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014039 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014040#endif
14041#ifdef HAVE_SPAWNV
14042 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014043 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014044#endif
14045
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014046#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014047#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014048 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014049#endif
14050#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014051 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014052#endif
14053#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014054 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014055#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014056#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014057 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014058#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014059#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014060 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014061#endif
14062#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014063 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014064#endif
14065#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014066 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014067#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014068#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014069 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014070#endif
14071#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014072 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014073#endif
14074#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014075 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014076#endif
14077#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014078 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014079#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014080#endif
14081
Benjamin Peterson9428d532011-09-14 11:45:52 -040014082#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014083 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
14084 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
14085 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040014086#endif
14087
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014088#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014089 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014090#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014091#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014092 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014093#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014094#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014095 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014096#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014097#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014098 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014099#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014100#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014101 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014102#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014103#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014104 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014105#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014106#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014107 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014108#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010014109#if HAVE_DECL_RTLD_MEMBER
14110 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
14111#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020014112
Victor Stinner9b1f4742016-09-06 16:18:52 -070014113#ifdef HAVE_GETRANDOM_SYSCALL
14114 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
14115 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
14116#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014117#ifdef HAVE_MEMFD_CREATE
14118 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
14119 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
14120#ifdef MFD_HUGETLB
14121 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014122#endif
14123#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014124 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014125#endif
14126#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014127 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014128#endif
14129#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014130 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014131#endif
14132#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014133 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014134#endif
14135#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014136 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014137#endif
14138#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014139 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014140#endif
14141#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014142 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014143#endif
14144#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014145 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014146#endif
14147#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014148 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014149#endif
14150#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014151 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014152#endif
14153#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014154 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014155#endif
14156#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014157 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014158#endif
14159#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014160 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014161#endif
14162#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014163 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
14164#endif
14165#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070014166
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014167#if defined(__APPLE__)
14168 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
14169#endif
14170
Steve Dower2438cdf2019-03-29 16:37:16 -070014171#ifdef MS_WINDOWS
14172 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
14173 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
14174 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
14175 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
14176 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
14177#endif
14178
Victor Stinner8c62be82010-05-06 00:08:46 +000014179 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000014180}
14181
14182
Martin v. Löwis1a214512008-06-11 05:26:20 +000014183static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000014184 PyModuleDef_HEAD_INIT,
14185 MODNAME,
14186 posix__doc__,
14187 -1,
14188 posix_methods,
14189 NULL,
14190 NULL,
14191 NULL,
14192 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000014193};
14194
14195
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014196static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014197
14198#ifdef HAVE_FACCESSAT
14199 "HAVE_FACCESSAT",
14200#endif
14201
14202#ifdef HAVE_FCHDIR
14203 "HAVE_FCHDIR",
14204#endif
14205
14206#ifdef HAVE_FCHMOD
14207 "HAVE_FCHMOD",
14208#endif
14209
14210#ifdef HAVE_FCHMODAT
14211 "HAVE_FCHMODAT",
14212#endif
14213
14214#ifdef HAVE_FCHOWN
14215 "HAVE_FCHOWN",
14216#endif
14217
Larry Hastings00964ed2013-08-12 13:49:30 -040014218#ifdef HAVE_FCHOWNAT
14219 "HAVE_FCHOWNAT",
14220#endif
14221
Larry Hastings9cf065c2012-06-22 16:30:09 -070014222#ifdef HAVE_FEXECVE
14223 "HAVE_FEXECVE",
14224#endif
14225
14226#ifdef HAVE_FDOPENDIR
14227 "HAVE_FDOPENDIR",
14228#endif
14229
Georg Brandl306336b2012-06-24 12:55:33 +020014230#ifdef HAVE_FPATHCONF
14231 "HAVE_FPATHCONF",
14232#endif
14233
Larry Hastings9cf065c2012-06-22 16:30:09 -070014234#ifdef HAVE_FSTATAT
14235 "HAVE_FSTATAT",
14236#endif
14237
14238#ifdef HAVE_FSTATVFS
14239 "HAVE_FSTATVFS",
14240#endif
14241
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014242#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014243 "HAVE_FTRUNCATE",
14244#endif
14245
Larry Hastings9cf065c2012-06-22 16:30:09 -070014246#ifdef HAVE_FUTIMENS
14247 "HAVE_FUTIMENS",
14248#endif
14249
14250#ifdef HAVE_FUTIMES
14251 "HAVE_FUTIMES",
14252#endif
14253
14254#ifdef HAVE_FUTIMESAT
14255 "HAVE_FUTIMESAT",
14256#endif
14257
14258#ifdef HAVE_LINKAT
14259 "HAVE_LINKAT",
14260#endif
14261
14262#ifdef HAVE_LCHFLAGS
14263 "HAVE_LCHFLAGS",
14264#endif
14265
14266#ifdef HAVE_LCHMOD
14267 "HAVE_LCHMOD",
14268#endif
14269
14270#ifdef HAVE_LCHOWN
14271 "HAVE_LCHOWN",
14272#endif
14273
14274#ifdef HAVE_LSTAT
14275 "HAVE_LSTAT",
14276#endif
14277
14278#ifdef HAVE_LUTIMES
14279 "HAVE_LUTIMES",
14280#endif
14281
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014282#ifdef HAVE_MEMFD_CREATE
14283 "HAVE_MEMFD_CREATE",
14284#endif
14285
Larry Hastings9cf065c2012-06-22 16:30:09 -070014286#ifdef HAVE_MKDIRAT
14287 "HAVE_MKDIRAT",
14288#endif
14289
14290#ifdef HAVE_MKFIFOAT
14291 "HAVE_MKFIFOAT",
14292#endif
14293
14294#ifdef HAVE_MKNODAT
14295 "HAVE_MKNODAT",
14296#endif
14297
14298#ifdef HAVE_OPENAT
14299 "HAVE_OPENAT",
14300#endif
14301
14302#ifdef HAVE_READLINKAT
14303 "HAVE_READLINKAT",
14304#endif
14305
14306#ifdef HAVE_RENAMEAT
14307 "HAVE_RENAMEAT",
14308#endif
14309
14310#ifdef HAVE_SYMLINKAT
14311 "HAVE_SYMLINKAT",
14312#endif
14313
14314#ifdef HAVE_UNLINKAT
14315 "HAVE_UNLINKAT",
14316#endif
14317
14318#ifdef HAVE_UTIMENSAT
14319 "HAVE_UTIMENSAT",
14320#endif
14321
14322#ifdef MS_WINDOWS
14323 "MS_WINDOWS",
14324#endif
14325
14326 NULL
14327};
14328
14329
Mark Hammondfe51c6d2002-08-02 02:27:13 +000014330PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000014331INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014332{
Victor Stinner8c62be82010-05-06 00:08:46 +000014333 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014334 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014335 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000014336
Victor Stinner8c62be82010-05-06 00:08:46 +000014337 m = PyModule_Create(&posixmodule);
14338 if (m == NULL)
14339 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000014340
Victor Stinner8c62be82010-05-06 00:08:46 +000014341 /* Initialize environ dictionary */
14342 v = convertenviron();
14343 Py_XINCREF(v);
14344 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
14345 return NULL;
14346 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014347
Victor Stinner8c62be82010-05-06 00:08:46 +000014348 if (all_ins(m))
14349 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000014350
Victor Stinner8c62be82010-05-06 00:08:46 +000014351 if (setup_confname_tables(m))
14352 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000014353
Victor Stinner8c62be82010-05-06 00:08:46 +000014354 Py_INCREF(PyExc_OSError);
14355 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014356
Guido van Rossumb3d39562000-01-31 18:41:26 +000014357#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000014358 if (posix_putenv_garbage == NULL)
14359 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000014360#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000014361
Victor Stinner8c62be82010-05-06 00:08:46 +000014362 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020014363#if defined(HAVE_WAITID) && !defined(__APPLE__)
14364 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014365 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
14366 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014367 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014368 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014369#endif
14370
Christian Heimes25827622013-10-12 01:27:08 +020014371 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000014372 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14373 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14374 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014375 StatResultType = PyStructSequence_NewType(&stat_result_desc);
14376 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014377 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014378 }
14379 structseq_new = StatResultType->tp_new;
14380 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014381
Christian Heimes25827622013-10-12 01:27:08 +020014382 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014383 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
14384 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014385 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014386 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014387#ifdef NEED_TICKS_PER_SECOND
14388# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000014389 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014390# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000014391 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014392# else
Victor Stinner8c62be82010-05-06 00:08:46 +000014393 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014394# endif
14395#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014396
William Orr81574b82018-10-01 22:19:56 -070014397#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014398 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014399 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
14400 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014401 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014402 }
14403 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014404#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014405
14406 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014407 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
14408 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014409 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014410 }
Victor Stinner6036e442015-03-08 01:58:04 +010014411
14412 /* initialize scandir types */
14413 if (PyType_Ready(&ScandirIteratorType) < 0)
14414 return NULL;
14415 if (PyType_Ready(&DirEntryType) < 0)
14416 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014417 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014418#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014419 Py_INCREF((PyObject*) WaitidResultType);
14420 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020014421#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014422 Py_INCREF((PyObject*) StatResultType);
14423 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
14424 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000014425 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014426 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014427
14428#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014429 Py_INCREF(SchedParamType);
14430 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014431#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014432
Larry Hastings605a62d2012-06-24 04:33:36 -070014433 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014434 TimesResultType = PyStructSequence_NewType(&times_result_desc);
14435 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014436 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014437 }
14438 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014439
14440 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014441 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
14442 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014443 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014444 }
14445 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014446
Thomas Wouters477c8d52006-05-27 19:21:47 +000014447#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014448 /*
14449 * Step 2 of weak-linking support on Mac OS X.
14450 *
14451 * The code below removes functions that are not available on the
14452 * currently active platform.
14453 *
14454 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014455 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014456 * OSX 10.4.
14457 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014458#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014459 if (fstatvfs == NULL) {
14460 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14461 return NULL;
14462 }
14463 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014464#endif /* HAVE_FSTATVFS */
14465
14466#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014467 if (statvfs == NULL) {
14468 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14469 return NULL;
14470 }
14471 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014472#endif /* HAVE_STATVFS */
14473
14474# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014475 if (lchown == NULL) {
14476 if (PyObject_DelAttrString(m, "lchown") == -1) {
14477 return NULL;
14478 }
14479 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014480#endif /* HAVE_LCHOWN */
14481
14482
14483#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014484
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014485 Py_INCREF(TerminalSizeType);
14486 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014487
Larry Hastings6fe20b32012-04-19 15:07:49 -070014488 billion = PyLong_FromLong(1000000000);
14489 if (!billion)
14490 return NULL;
14491
Larry Hastings9cf065c2012-06-22 16:30:09 -070014492 /* suppress "function not used" warnings */
14493 {
14494 int ignored;
14495 fd_specified("", -1);
14496 follow_symlinks_specified("", 1);
14497 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14498 dir_fd_converter(Py_None, &ignored);
14499 dir_fd_unavailable(Py_None, &ignored);
14500 }
14501
14502 /*
14503 * provide list of locally available functions
14504 * so os.py can populate support_* lists
14505 */
14506 list = PyList_New(0);
14507 if (!list)
14508 return NULL;
14509 for (trace = have_functions; *trace; trace++) {
14510 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14511 if (!unicode)
14512 return NULL;
14513 if (PyList_Append(list, unicode))
14514 return NULL;
14515 Py_DECREF(unicode);
14516 }
14517 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014518
14519 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014520 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014521
14522 initialized = 1;
14523
Victor Stinner8c62be82010-05-06 00:08:46 +000014524 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014525}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014526
14527#ifdef __cplusplus
14528}
14529#endif