blob: 8f6cffffcdfbe8d713fd5f81e63d7d4d258cc9d1 [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
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006725#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006726
6727/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006728PyDoc_STRVAR(posix_getgrouplist__doc__,
6729"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6730Returns a list of groups to which a user belongs.\n\n\
6731 user: username to lookup\n\
6732 group: base group id of the user");
6733
6734static PyObject *
6735posix_getgrouplist(PyObject *self, PyObject *args)
6736{
6737#ifdef NGROUPS_MAX
6738#define MAX_GROUPS NGROUPS_MAX
6739#else
6740 /* defined to be 16 on Solaris7, so this should be a small number */
6741#define MAX_GROUPS 64
6742#endif
6743
6744 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
6752 ngroups = MAX_GROUPS;
6753
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006754#ifdef __APPLE__
6755 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006756 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006757#else
6758 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6759 _Py_Gid_Converter, &basegid))
6760 return NULL;
6761#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006762
6763#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006764 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006765#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006766 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006767#endif
6768 if (groups == NULL)
6769 return PyErr_NoMemory();
6770
6771 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6772 PyMem_Del(groups);
6773 return posix_error();
6774 }
6775
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006776#ifdef _Py_MEMORY_SANITIZER
6777 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6778 __msan_unpoison(&ngroups, sizeof(ngroups));
6779 __msan_unpoison(groups, ngroups*sizeof(*groups));
6780#endif
6781
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006782 list = PyList_New(ngroups);
6783 if (list == NULL) {
6784 PyMem_Del(groups);
6785 return NULL;
6786 }
6787
6788 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006789#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006790 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006791#else
6792 PyObject *o = _PyLong_FromGid(groups[i]);
6793#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006794 if (o == NULL) {
6795 Py_DECREF(list);
6796 PyMem_Del(groups);
6797 return NULL;
6798 }
6799 PyList_SET_ITEM(list, i, o);
6800 }
6801
6802 PyMem_Del(groups);
6803
6804 return list;
6805}
Larry Hastings2f936352014-08-05 14:04:04 +10006806#endif /* HAVE_GETGROUPLIST */
6807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006808
Fred Drakec9680921999-12-13 16:37:25 +00006809#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006810/*[clinic input]
6811os.getgroups
6812
6813Return list of supplemental group IDs for the process.
6814[clinic start generated code]*/
6815
Larry Hastings2f936352014-08-05 14:04:04 +10006816static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006817os_getgroups_impl(PyObject *module)
6818/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006819{
6820 PyObject *result = NULL;
6821
Fred Drakec9680921999-12-13 16:37:25 +00006822#ifdef NGROUPS_MAX
6823#define MAX_GROUPS NGROUPS_MAX
6824#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006826#define MAX_GROUPS 64
6827#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006828 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006829
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006830 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006831 * This is a helper variable to store the intermediate result when
6832 * that happens.
6833 *
6834 * To keep the code readable the OSX behaviour is unconditional,
6835 * according to the POSIX spec this should be safe on all unix-y
6836 * systems.
6837 */
6838 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006840
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006841#ifdef __APPLE__
6842 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6843 * there are more groups than can fit in grouplist. Therefore, on OS X
6844 * always first call getgroups with length 0 to get the actual number
6845 * of groups.
6846 */
6847 n = getgroups(0, NULL);
6848 if (n < 0) {
6849 return posix_error();
6850 } else if (n <= MAX_GROUPS) {
6851 /* groups will fit in existing array */
6852 alt_grouplist = grouplist;
6853 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006854 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006855 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006856 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006857 }
6858 }
6859
6860 n = getgroups(n, alt_grouplist);
6861 if (n == -1) {
6862 if (alt_grouplist != grouplist) {
6863 PyMem_Free(alt_grouplist);
6864 }
6865 return posix_error();
6866 }
6867#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006869 if (n < 0) {
6870 if (errno == EINVAL) {
6871 n = getgroups(0, NULL);
6872 if (n == -1) {
6873 return posix_error();
6874 }
6875 if (n == 0) {
6876 /* Avoid malloc(0) */
6877 alt_grouplist = grouplist;
6878 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006879 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006880 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006881 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006882 }
6883 n = getgroups(n, alt_grouplist);
6884 if (n == -1) {
6885 PyMem_Free(alt_grouplist);
6886 return posix_error();
6887 }
6888 }
6889 } else {
6890 return posix_error();
6891 }
6892 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006893#endif
6894
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006895 result = PyList_New(n);
6896 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006897 int i;
6898 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006899 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006900 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006901 Py_DECREF(result);
6902 result = NULL;
6903 break;
Fred Drakec9680921999-12-13 16:37:25 +00006904 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006905 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006906 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006907 }
6908
6909 if (alt_grouplist != grouplist) {
6910 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006912
Fred Drakec9680921999-12-13 16:37:25 +00006913 return result;
6914}
Larry Hastings2f936352014-08-05 14:04:04 +10006915#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006916
Antoine Pitroub7572f02009-12-02 20:46:48 +00006917#ifdef HAVE_INITGROUPS
6918PyDoc_STRVAR(posix_initgroups__doc__,
6919"initgroups(username, gid) -> None\n\n\
6920Call the system initgroups() to initialize the group access list with all of\n\
6921the groups of which the specified username is a member, plus the specified\n\
6922group id.");
6923
Larry Hastings2f936352014-08-05 14:04:04 +10006924/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006925static PyObject *
6926posix_initgroups(PyObject *self, PyObject *args)
6927{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006928 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006929 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006930 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006931#ifdef __APPLE__
6932 int gid;
6933#else
6934 gid_t gid;
6935#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006936
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006937#ifdef __APPLE__
6938 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6939 PyUnicode_FSConverter, &oname,
6940 &gid))
6941#else
6942 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6943 PyUnicode_FSConverter, &oname,
6944 _Py_Gid_Converter, &gid))
6945#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006947 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006948
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006949 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006950 Py_DECREF(oname);
6951 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006953
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006954 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006955}
Larry Hastings2f936352014-08-05 14:04:04 +10006956#endif /* HAVE_INITGROUPS */
6957
Antoine Pitroub7572f02009-12-02 20:46:48 +00006958
Martin v. Löwis606edc12002-06-13 21:09:11 +00006959#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006960/*[clinic input]
6961os.getpgid
6962
6963 pid: pid_t
6964
6965Call the system call getpgid(), and return the result.
6966[clinic start generated code]*/
6967
Larry Hastings2f936352014-08-05 14:04:04 +10006968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006969os_getpgid_impl(PyObject *module, pid_t pid)
6970/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006971{
6972 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 if (pgid < 0)
6974 return posix_error();
6975 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006976}
6977#endif /* HAVE_GETPGID */
6978
6979
Guido van Rossumb6775db1994-08-01 11:34:53 +00006980#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006981/*[clinic input]
6982os.getpgrp
6983
6984Return the current process group id.
6985[clinic start generated code]*/
6986
Larry Hastings2f936352014-08-05 14:04:04 +10006987static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006988os_getpgrp_impl(PyObject *module)
6989/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006990{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006991#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006993#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006995#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006996}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006997#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006998
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006999
Guido van Rossumb6775db1994-08-01 11:34:53 +00007000#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007001/*[clinic input]
7002os.setpgrp
7003
7004Make the current process the leader of its process group.
7005[clinic start generated code]*/
7006
Larry Hastings2f936352014-08-05 14:04:04 +10007007static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007008os_setpgrp_impl(PyObject *module)
7009/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007010{
Guido van Rossum64933891994-10-20 21:56:42 +00007011#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007013#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007014 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007015#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007017 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007018}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007019#endif /* HAVE_SETPGRP */
7020
Guido van Rossumad0ee831995-03-01 10:34:45 +00007021#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007022
7023#ifdef MS_WINDOWS
7024#include <tlhelp32.h>
7025
7026static PyObject*
7027win32_getppid()
7028{
7029 HANDLE snapshot;
7030 pid_t mypid;
7031 PyObject* result = NULL;
7032 BOOL have_record;
7033 PROCESSENTRY32 pe;
7034
7035 mypid = getpid(); /* This function never fails */
7036
7037 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7038 if (snapshot == INVALID_HANDLE_VALUE)
7039 return PyErr_SetFromWindowsErr(GetLastError());
7040
7041 pe.dwSize = sizeof(pe);
7042 have_record = Process32First(snapshot, &pe);
7043 while (have_record) {
7044 if (mypid == (pid_t)pe.th32ProcessID) {
7045 /* We could cache the ulong value in a static variable. */
7046 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7047 break;
7048 }
7049
7050 have_record = Process32Next(snapshot, &pe);
7051 }
7052
7053 /* If our loop exits and our pid was not found (result will be NULL)
7054 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7055 * error anyway, so let's raise it. */
7056 if (!result)
7057 result = PyErr_SetFromWindowsErr(GetLastError());
7058
7059 CloseHandle(snapshot);
7060
7061 return result;
7062}
7063#endif /*MS_WINDOWS*/
7064
Larry Hastings2f936352014-08-05 14:04:04 +10007065
7066/*[clinic input]
7067os.getppid
7068
7069Return the parent's process id.
7070
7071If the parent process has already exited, Windows machines will still
7072return its id; others systems will return the id of the 'init' process (1).
7073[clinic start generated code]*/
7074
Larry Hastings2f936352014-08-05 14:04:04 +10007075static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007076os_getppid_impl(PyObject *module)
7077/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007078{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007079#ifdef MS_WINDOWS
7080 return win32_getppid();
7081#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007082 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007083#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007084}
7085#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007086
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007087
Fred Drake12c6e2d1999-12-14 21:25:03 +00007088#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007089/*[clinic input]
7090os.getlogin
7091
7092Return the actual login name.
7093[clinic start generated code]*/
7094
Larry Hastings2f936352014-08-05 14:04:04 +10007095static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007096os_getlogin_impl(PyObject *module)
7097/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007098{
Victor Stinner8c62be82010-05-06 00:08:46 +00007099 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007100#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007101 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007102 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007103
7104 if (GetUserNameW(user_name, &num_chars)) {
7105 /* num_chars is the number of unicode chars plus null terminator */
7106 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007107 }
7108 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007109 result = PyErr_SetFromWindowsErr(GetLastError());
7110#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 char *name;
7112 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007113
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 errno = 0;
7115 name = getlogin();
7116 if (name == NULL) {
7117 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007118 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007119 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007120 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007121 }
7122 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007123 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007124 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007125#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007126 return result;
7127}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007128#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007129
Larry Hastings2f936352014-08-05 14:04:04 +10007130
Guido van Rossumad0ee831995-03-01 10:34:45 +00007131#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007132/*[clinic input]
7133os.getuid
7134
7135Return the current process's user id.
7136[clinic start generated code]*/
7137
Larry Hastings2f936352014-08-05 14:04:04 +10007138static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007139os_getuid_impl(PyObject *module)
7140/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007141{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007142 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007143}
Larry Hastings2f936352014-08-05 14:04:04 +10007144#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007145
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007146
Brian Curtineb24d742010-04-12 17:16:38 +00007147#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007148#define HAVE_KILL
7149#endif /* MS_WINDOWS */
7150
7151#ifdef HAVE_KILL
7152/*[clinic input]
7153os.kill
7154
7155 pid: pid_t
7156 signal: Py_ssize_t
7157 /
7158
7159Kill a process with a signal.
7160[clinic start generated code]*/
7161
Larry Hastings2f936352014-08-05 14:04:04 +10007162static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007163os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7164/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007165#ifndef MS_WINDOWS
7166{
7167 if (kill(pid, (int)signal) == -1)
7168 return posix_error();
7169 Py_RETURN_NONE;
7170}
7171#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00007172{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007173 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007174 DWORD sig = (DWORD)signal;
7175 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007176 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007177
Victor Stinner8c62be82010-05-06 00:08:46 +00007178 /* Console processes which share a common console can be sent CTRL+C or
7179 CTRL+BREAK events, provided they handle said events. */
7180 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007181 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007182 err = GetLastError();
7183 PyErr_SetFromWindowsErr(err);
7184 }
7185 else
7186 Py_RETURN_NONE;
7187 }
Brian Curtineb24d742010-04-12 17:16:38 +00007188
Victor Stinner8c62be82010-05-06 00:08:46 +00007189 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7190 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007191 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007192 if (handle == NULL) {
7193 err = GetLastError();
7194 return PyErr_SetFromWindowsErr(err);
7195 }
Brian Curtineb24d742010-04-12 17:16:38 +00007196
Victor Stinner8c62be82010-05-06 00:08:46 +00007197 if (TerminateProcess(handle, sig) == 0) {
7198 err = GetLastError();
7199 result = PyErr_SetFromWindowsErr(err);
7200 } else {
7201 Py_INCREF(Py_None);
7202 result = Py_None;
7203 }
Brian Curtineb24d742010-04-12 17:16:38 +00007204
Victor Stinner8c62be82010-05-06 00:08:46 +00007205 CloseHandle(handle);
7206 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00007207}
Larry Hastings2f936352014-08-05 14:04:04 +10007208#endif /* !MS_WINDOWS */
7209#endif /* HAVE_KILL */
7210
7211
7212#ifdef HAVE_KILLPG
7213/*[clinic input]
7214os.killpg
7215
7216 pgid: pid_t
7217 signal: int
7218 /
7219
7220Kill a process group with a signal.
7221[clinic start generated code]*/
7222
Larry Hastings2f936352014-08-05 14:04:04 +10007223static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007224os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7225/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007226{
7227 /* XXX some man pages make the `pgid` parameter an int, others
7228 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7229 take the same type. Moreover, pid_t is always at least as wide as
7230 int (else compilation of this module fails), which is safe. */
7231 if (killpg(pgid, signal) == -1)
7232 return posix_error();
7233 Py_RETURN_NONE;
7234}
7235#endif /* HAVE_KILLPG */
7236
Brian Curtineb24d742010-04-12 17:16:38 +00007237
Guido van Rossumc0125471996-06-28 18:55:32 +00007238#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007239#ifdef HAVE_SYS_LOCK_H
7240#include <sys/lock.h>
7241#endif
7242
Larry Hastings2f936352014-08-05 14:04:04 +10007243/*[clinic input]
7244os.plock
7245 op: int
7246 /
7247
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007248Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007249[clinic start generated code]*/
7250
Larry Hastings2f936352014-08-05 14:04:04 +10007251static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007252os_plock_impl(PyObject *module, int op)
7253/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007254{
Victor Stinner8c62be82010-05-06 00:08:46 +00007255 if (plock(op) == -1)
7256 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007257 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007258}
Larry Hastings2f936352014-08-05 14:04:04 +10007259#endif /* HAVE_PLOCK */
7260
Guido van Rossumc0125471996-06-28 18:55:32 +00007261
Guido van Rossumb6775db1994-08-01 11:34:53 +00007262#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007263/*[clinic input]
7264os.setuid
7265
7266 uid: uid_t
7267 /
7268
7269Set the current process's user id.
7270[clinic start generated code]*/
7271
Larry Hastings2f936352014-08-05 14:04:04 +10007272static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007273os_setuid_impl(PyObject *module, uid_t uid)
7274/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007275{
Victor Stinner8c62be82010-05-06 00:08:46 +00007276 if (setuid(uid) < 0)
7277 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007278 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007279}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007280#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007281
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007282
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007283#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007284/*[clinic input]
7285os.seteuid
7286
7287 euid: uid_t
7288 /
7289
7290Set the current process's effective user id.
7291[clinic start generated code]*/
7292
Larry Hastings2f936352014-08-05 14:04:04 +10007293static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007294os_seteuid_impl(PyObject *module, uid_t euid)
7295/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007296{
7297 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007298 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007299 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007300}
7301#endif /* HAVE_SETEUID */
7302
Larry Hastings2f936352014-08-05 14:04:04 +10007303
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007304#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007305/*[clinic input]
7306os.setegid
7307
7308 egid: gid_t
7309 /
7310
7311Set the current process's effective group id.
7312[clinic start generated code]*/
7313
Larry Hastings2f936352014-08-05 14:04:04 +10007314static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007315os_setegid_impl(PyObject *module, gid_t egid)
7316/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007317{
7318 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007319 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007320 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007321}
7322#endif /* HAVE_SETEGID */
7323
Larry Hastings2f936352014-08-05 14:04:04 +10007324
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007325#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007326/*[clinic input]
7327os.setreuid
7328
7329 ruid: uid_t
7330 euid: uid_t
7331 /
7332
7333Set the current process's real and effective user ids.
7334[clinic start generated code]*/
7335
Larry Hastings2f936352014-08-05 14:04:04 +10007336static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007337os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7338/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007339{
Victor Stinner8c62be82010-05-06 00:08:46 +00007340 if (setreuid(ruid, euid) < 0) {
7341 return posix_error();
7342 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007343 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007344 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007345}
7346#endif /* HAVE_SETREUID */
7347
Larry Hastings2f936352014-08-05 14:04:04 +10007348
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007349#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007350/*[clinic input]
7351os.setregid
7352
7353 rgid: gid_t
7354 egid: gid_t
7355 /
7356
7357Set the current process's real and effective group ids.
7358[clinic start generated code]*/
7359
Larry Hastings2f936352014-08-05 14:04:04 +10007360static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007361os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7362/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007363{
7364 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007365 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007366 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007367}
7368#endif /* HAVE_SETREGID */
7369
Larry Hastings2f936352014-08-05 14:04:04 +10007370
Guido van Rossumb6775db1994-08-01 11:34:53 +00007371#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007372/*[clinic input]
7373os.setgid
7374 gid: gid_t
7375 /
7376
7377Set the current process's group id.
7378[clinic start generated code]*/
7379
Larry Hastings2f936352014-08-05 14:04:04 +10007380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007381os_setgid_impl(PyObject *module, gid_t gid)
7382/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007383{
Victor Stinner8c62be82010-05-06 00:08:46 +00007384 if (setgid(gid) < 0)
7385 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007386 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007387}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007388#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007389
Larry Hastings2f936352014-08-05 14:04:04 +10007390
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007391#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007392/*[clinic input]
7393os.setgroups
7394
7395 groups: object
7396 /
7397
7398Set the groups of the current process to list.
7399[clinic start generated code]*/
7400
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007401static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007402os_setgroups(PyObject *module, PyObject *groups)
7403/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007404{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007405 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007406 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007407
Victor Stinner8c62be82010-05-06 00:08:46 +00007408 if (!PySequence_Check(groups)) {
7409 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7410 return NULL;
7411 }
7412 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007413 if (len < 0) {
7414 return NULL;
7415 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007416 if (len > MAX_GROUPS) {
7417 PyErr_SetString(PyExc_ValueError, "too many groups");
7418 return NULL;
7419 }
7420 for(i = 0; i < len; i++) {
7421 PyObject *elem;
7422 elem = PySequence_GetItem(groups, i);
7423 if (!elem)
7424 return NULL;
7425 if (!PyLong_Check(elem)) {
7426 PyErr_SetString(PyExc_TypeError,
7427 "groups must be integers");
7428 Py_DECREF(elem);
7429 return NULL;
7430 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007431 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007432 Py_DECREF(elem);
7433 return NULL;
7434 }
7435 }
7436 Py_DECREF(elem);
7437 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007438
Victor Stinner8c62be82010-05-06 00:08:46 +00007439 if (setgroups(len, grouplist) < 0)
7440 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007441 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007442}
7443#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007444
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007445#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7446static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007447wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007448{
Victor Stinner8c62be82010-05-06 00:08:46 +00007449 PyObject *result;
7450 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007451 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007452
Victor Stinner8c62be82010-05-06 00:08:46 +00007453 if (pid == -1)
7454 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007455
Victor Stinner8c62be82010-05-06 00:08:46 +00007456 if (struct_rusage == NULL) {
7457 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7458 if (m == NULL)
7459 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007460 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007461 Py_DECREF(m);
7462 if (struct_rusage == NULL)
7463 return NULL;
7464 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007465
Victor Stinner8c62be82010-05-06 00:08:46 +00007466 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7467 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7468 if (!result)
7469 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007470
7471#ifndef doubletime
7472#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7473#endif
7474
Victor Stinner8c62be82010-05-06 00:08:46 +00007475 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007476 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007477 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007478 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007479#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007480 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7481 SET_INT(result, 2, ru->ru_maxrss);
7482 SET_INT(result, 3, ru->ru_ixrss);
7483 SET_INT(result, 4, ru->ru_idrss);
7484 SET_INT(result, 5, ru->ru_isrss);
7485 SET_INT(result, 6, ru->ru_minflt);
7486 SET_INT(result, 7, ru->ru_majflt);
7487 SET_INT(result, 8, ru->ru_nswap);
7488 SET_INT(result, 9, ru->ru_inblock);
7489 SET_INT(result, 10, ru->ru_oublock);
7490 SET_INT(result, 11, ru->ru_msgsnd);
7491 SET_INT(result, 12, ru->ru_msgrcv);
7492 SET_INT(result, 13, ru->ru_nsignals);
7493 SET_INT(result, 14, ru->ru_nvcsw);
7494 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007495#undef SET_INT
7496
Victor Stinner8c62be82010-05-06 00:08:46 +00007497 if (PyErr_Occurred()) {
7498 Py_DECREF(result);
7499 return NULL;
7500 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007501
Victor Stinner8c62be82010-05-06 00:08:46 +00007502 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007503}
7504#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7505
Larry Hastings2f936352014-08-05 14:04:04 +10007506
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007507#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007508/*[clinic input]
7509os.wait3
7510
7511 options: int
7512Wait for completion of a child process.
7513
7514Returns a tuple of information about the child process:
7515 (pid, status, rusage)
7516[clinic start generated code]*/
7517
Larry Hastings2f936352014-08-05 14:04:04 +10007518static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007519os_wait3_impl(PyObject *module, int options)
7520/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007521{
Victor Stinner8c62be82010-05-06 00:08:46 +00007522 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007523 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007524 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007525 WAIT_TYPE status;
7526 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007527
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007528 do {
7529 Py_BEGIN_ALLOW_THREADS
7530 pid = wait3(&status, options, &ru);
7531 Py_END_ALLOW_THREADS
7532 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7533 if (pid < 0)
7534 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007535
Victor Stinner4195b5c2012-02-08 23:03:19 +01007536 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007537}
7538#endif /* HAVE_WAIT3 */
7539
Larry Hastings2f936352014-08-05 14:04:04 +10007540
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007541#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007542/*[clinic input]
7543
7544os.wait4
7545
7546 pid: pid_t
7547 options: int
7548
7549Wait for completion of a specific child process.
7550
7551Returns a tuple of information about the child process:
7552 (pid, status, rusage)
7553[clinic start generated code]*/
7554
Larry Hastings2f936352014-08-05 14:04:04 +10007555static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007556os_wait4_impl(PyObject *module, pid_t pid, int options)
7557/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007558{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007559 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007560 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007561 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 WAIT_TYPE status;
7563 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007564
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007565 do {
7566 Py_BEGIN_ALLOW_THREADS
7567 res = wait4(pid, &status, options, &ru);
7568 Py_END_ALLOW_THREADS
7569 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7570 if (res < 0)
7571 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007572
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007573 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007574}
7575#endif /* HAVE_WAIT4 */
7576
Larry Hastings2f936352014-08-05 14:04:04 +10007577
Ross Lagerwall7807c352011-03-17 20:20:30 +02007578#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007579/*[clinic input]
7580os.waitid
7581
7582 idtype: idtype_t
7583 Must be one of be P_PID, P_PGID or P_ALL.
7584 id: id_t
7585 The id to wait on.
7586 options: int
7587 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7588 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7589 /
7590
7591Returns the result of waiting for a process or processes.
7592
7593Returns either waitid_result or None if WNOHANG is specified and there are
7594no children in a waitable state.
7595[clinic start generated code]*/
7596
Larry Hastings2f936352014-08-05 14:04:04 +10007597static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007598os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7599/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007600{
7601 PyObject *result;
7602 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007603 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007604 siginfo_t si;
7605 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007606
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007607 do {
7608 Py_BEGIN_ALLOW_THREADS
7609 res = waitid(idtype, id, &si, options);
7610 Py_END_ALLOW_THREADS
7611 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7612 if (res < 0)
7613 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007614
7615 if (si.si_pid == 0)
7616 Py_RETURN_NONE;
7617
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007618 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007619 if (!result)
7620 return NULL;
7621
7622 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007623 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007624 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7625 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7626 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7627 if (PyErr_Occurred()) {
7628 Py_DECREF(result);
7629 return NULL;
7630 }
7631
7632 return result;
7633}
Larry Hastings2f936352014-08-05 14:04:04 +10007634#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007635
Larry Hastings2f936352014-08-05 14:04:04 +10007636
7637#if defined(HAVE_WAITPID)
7638/*[clinic input]
7639os.waitpid
7640 pid: pid_t
7641 options: int
7642 /
7643
7644Wait for completion of a given child process.
7645
7646Returns a tuple of information regarding the child process:
7647 (pid, status)
7648
7649The options argument is ignored on Windows.
7650[clinic start generated code]*/
7651
Larry Hastings2f936352014-08-05 14:04:04 +10007652static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007653os_waitpid_impl(PyObject *module, pid_t pid, int options)
7654/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007655{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007656 pid_t res;
7657 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007658 WAIT_TYPE status;
7659 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007660
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007661 do {
7662 Py_BEGIN_ALLOW_THREADS
7663 res = waitpid(pid, &status, options);
7664 Py_END_ALLOW_THREADS
7665 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7666 if (res < 0)
7667 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007668
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007669 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007670}
Tim Petersab034fa2002-02-01 11:27:43 +00007671#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007672/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007673/*[clinic input]
7674os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007675 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007676 options: int
7677 /
7678
7679Wait for completion of a given process.
7680
7681Returns a tuple of information regarding the process:
7682 (pid, status << 8)
7683
7684The options argument is ignored on Windows.
7685[clinic start generated code]*/
7686
Larry Hastings2f936352014-08-05 14:04:04 +10007687static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007688os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007689/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007690{
7691 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007692 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007693 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007694
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007695 do {
7696 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007697 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007698 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007699 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007700 Py_END_ALLOW_THREADS
7701 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007702 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007703 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007704
Victor Stinner8c62be82010-05-06 00:08:46 +00007705 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007706 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007707}
Larry Hastings2f936352014-08-05 14:04:04 +10007708#endif
7709
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007710
Guido van Rossumad0ee831995-03-01 10:34:45 +00007711#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007712/*[clinic input]
7713os.wait
7714
7715Wait for completion of a child process.
7716
7717Returns a tuple of information about the child process:
7718 (pid, status)
7719[clinic start generated code]*/
7720
Larry Hastings2f936352014-08-05 14:04:04 +10007721static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007722os_wait_impl(PyObject *module)
7723/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007724{
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007726 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 WAIT_TYPE status;
7728 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007729
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007730 do {
7731 Py_BEGIN_ALLOW_THREADS
7732 pid = wait(&status);
7733 Py_END_ALLOW_THREADS
7734 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7735 if (pid < 0)
7736 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007737
Victor Stinner8c62be82010-05-06 00:08:46 +00007738 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007739}
Larry Hastings2f936352014-08-05 14:04:04 +10007740#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007741
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007742
Larry Hastings9cf065c2012-06-22 16:30:09 -07007743#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007744/*[clinic input]
7745os.readlink
7746
7747 path: path_t
7748 *
7749 dir_fd: dir_fd(requires='readlinkat') = None
7750
7751Return a string representing the path to which the symbolic link points.
7752
7753If dir_fd is not None, it should be a file descriptor open to a directory,
7754and path should be relative; path will then be relative to that directory.
7755
7756dir_fd may not be implemented on your platform. If it is unavailable,
7757using it will raise a NotImplementedError.
7758[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007759
Barry Warsaw53699e91996-12-10 23:23:01 +00007760static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007761os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7762/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007763{
Berker Peksage0b5b202018-08-15 13:03:41 +03007764#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007765 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007766 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007767
7768 Py_BEGIN_ALLOW_THREADS
7769#ifdef HAVE_READLINKAT
7770 if (dir_fd != DEFAULT_DIR_FD)
7771 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7772 else
7773#endif
7774 length = readlink(path->narrow, buffer, MAXPATHLEN);
7775 Py_END_ALLOW_THREADS
7776
7777 if (length < 0) {
7778 return path_error(path);
7779 }
7780 buffer[length] = '\0';
7781
7782 if (PyUnicode_Check(path->object))
7783 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7784 else
7785 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007786#elif defined(MS_WINDOWS)
7787 DWORD n_bytes_returned;
7788 DWORD io_result;
7789 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007790 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7791 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
7792 const wchar_t *print_name;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007793 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007794
Larry Hastings2f936352014-08-05 14:04:04 +10007795 /* First get a handle to the reparse point */
7796 Py_BEGIN_ALLOW_THREADS
7797 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007798 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007799 0,
7800 0,
7801 0,
7802 OPEN_EXISTING,
7803 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7804 0);
7805 Py_END_ALLOW_THREADS
7806
Berker Peksage0b5b202018-08-15 13:03:41 +03007807 if (reparse_point_handle == INVALID_HANDLE_VALUE) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007808 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007809 }
Larry Hastings2f936352014-08-05 14:04:04 +10007810
7811 Py_BEGIN_ALLOW_THREADS
7812 /* New call DeviceIoControl to read the reparse point */
7813 io_result = DeviceIoControl(
7814 reparse_point_handle,
7815 FSCTL_GET_REPARSE_POINT,
7816 0, 0, /* in buffer */
7817 target_buffer, sizeof(target_buffer),
7818 &n_bytes_returned,
7819 0 /* we're not using OVERLAPPED_IO */
7820 );
7821 CloseHandle(reparse_point_handle);
7822 Py_END_ALLOW_THREADS
7823
Berker Peksage0b5b202018-08-15 13:03:41 +03007824 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007825 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007826 }
Larry Hastings2f936352014-08-05 14:04:04 +10007827
7828 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7829 {
7830 PyErr_SetString(PyExc_ValueError,
7831 "not a symbolic link");
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007832 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007833 }
SSE43c34aad2018-02-13 00:10:35 +07007834 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7835 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007836
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007837 result = PyUnicode_FromWideChar(print_name,
7838 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
7839 if (path->narrow) {
7840 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Berker Peksage0b5b202018-08-15 13:03:41 +03007841 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007842 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007843#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007844}
Berker Peksage0b5b202018-08-15 13:03:41 +03007845#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007846
Larry Hastings9cf065c2012-06-22 16:30:09 -07007847#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007848
7849#if defined(MS_WINDOWS)
7850
Steve Dower6921e732018-03-05 14:26:08 -08007851/* Remove the last portion of the path - return 0 on success */
7852static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007853_dirnameW(WCHAR *path)
7854{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007855 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007856 size_t length = wcsnlen_s(path, MAX_PATH);
7857 if (length == MAX_PATH) {
7858 return -1;
7859 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007860
7861 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007862 for(ptr = path + length; ptr != path; ptr--) {
7863 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007864 break;
Steve Dower6921e732018-03-05 14:26:08 -08007865 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007866 }
7867 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007868 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007869}
7870
Victor Stinner31b3b922013-06-05 01:49:17 +02007871/* Is this path absolute? */
7872static int
7873_is_absW(const WCHAR *path)
7874{
Steve Dower6921e732018-03-05 14:26:08 -08007875 return path[0] == L'\\' || path[0] == L'/' ||
7876 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007877}
7878
Steve Dower6921e732018-03-05 14:26:08 -08007879/* join root and rest with a backslash - return 0 on success */
7880static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007881_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7882{
Victor Stinner31b3b922013-06-05 01:49:17 +02007883 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007884 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007885 }
7886
Steve Dower6921e732018-03-05 14:26:08 -08007887 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7888 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007889 }
Steve Dower6921e732018-03-05 14:26:08 -08007890
7891 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7892 return -1;
7893 }
7894
7895 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007896}
7897
Victor Stinner31b3b922013-06-05 01:49:17 +02007898/* Return True if the path at src relative to dest is a directory */
7899static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007900_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007901{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007902 WIN32_FILE_ATTRIBUTE_DATA src_info;
7903 WCHAR dest_parent[MAX_PATH];
7904 WCHAR src_resolved[MAX_PATH] = L"";
7905
7906 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007907 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7908 _dirnameW(dest_parent)) {
7909 return 0;
7910 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007911 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007912 if (_joinW(src_resolved, dest_parent, src)) {
7913 return 0;
7914 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007915 return (
7916 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7917 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7918 );
7919}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007920#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007921
Larry Hastings2f936352014-08-05 14:04:04 +10007922
7923/*[clinic input]
7924os.symlink
7925 src: path_t
7926 dst: path_t
7927 target_is_directory: bool = False
7928 *
7929 dir_fd: dir_fd(requires='symlinkat')=None
7930
7931# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7932
7933Create a symbolic link pointing to src named dst.
7934
7935target_is_directory is required on Windows if the target is to be
7936 interpreted as a directory. (On Windows, symlink requires
7937 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7938 target_is_directory is ignored on non-Windows platforms.
7939
7940If dir_fd is not None, it should be a file descriptor open to a directory,
7941 and path should be relative; path will then be relative to that directory.
7942dir_fd may not be implemented on your platform.
7943 If it is unavailable, using it will raise a NotImplementedError.
7944
7945[clinic start generated code]*/
7946
Larry Hastings2f936352014-08-05 14:04:04 +10007947static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007948os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007949 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007950/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007951{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007952#ifdef MS_WINDOWS
7953 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007954 DWORD flags = 0;
7955
7956 /* Assumed true, set to false if detected to not be available. */
7957 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007958#else
7959 int result;
7960#endif
7961
Larry Hastings9cf065c2012-06-22 16:30:09 -07007962#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007963
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007964 if (windows_has_symlink_unprivileged_flag) {
7965 /* Allow non-admin symlinks if system allows it. */
7966 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
7967 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007968
Larry Hastings9cf065c2012-06-22 16:30:09 -07007969 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007970 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007971 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
7972 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
7973 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
7974 }
7975
7976 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08007977 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007978 Py_END_ALLOW_THREADS
7979
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007980 if (windows_has_symlink_unprivileged_flag && !result &&
7981 ERROR_INVALID_PARAMETER == GetLastError()) {
7982
7983 Py_BEGIN_ALLOW_THREADS
7984 _Py_BEGIN_SUPPRESS_IPH
7985 /* This error might be caused by
7986 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
7987 Try again, and update windows_has_symlink_unprivileged_flag if we
7988 are successful this time.
7989
7990 NOTE: There is a risk of a race condition here if there are other
7991 conditions than the flag causing ERROR_INVALID_PARAMETER, and
7992 another process (or thread) changes that condition in between our
7993 calls to CreateSymbolicLink.
7994 */
7995 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
7996 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
7997 _Py_END_SUPPRESS_IPH
7998 Py_END_ALLOW_THREADS
7999
8000 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8001 windows_has_symlink_unprivileged_flag = FALSE;
8002 }
8003 }
8004
Larry Hastings2f936352014-08-05 14:04:04 +10008005 if (!result)
8006 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008007
8008#else
8009
Steve Dower6921e732018-03-05 14:26:08 -08008010 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8011 PyErr_SetString(PyExc_ValueError,
8012 "symlink: src and dst must be the same type");
8013 return NULL;
8014 }
8015
Larry Hastings9cf065c2012-06-22 16:30:09 -07008016 Py_BEGIN_ALLOW_THREADS
8017#if HAVE_SYMLINKAT
8018 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10008019 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008020 else
8021#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008022 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008023 Py_END_ALLOW_THREADS
8024
Larry Hastings2f936352014-08-05 14:04:04 +10008025 if (result)
8026 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008027#endif
8028
Larry Hastings2f936352014-08-05 14:04:04 +10008029 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008030}
8031#endif /* HAVE_SYMLINK */
8032
Larry Hastings9cf065c2012-06-22 16:30:09 -07008033
Brian Curtind40e6f72010-07-08 21:39:08 +00008034
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008035
Larry Hastings605a62d2012-06-24 04:33:36 -07008036static PyStructSequence_Field times_result_fields[] = {
8037 {"user", "user time"},
8038 {"system", "system time"},
8039 {"children_user", "user time of children"},
8040 {"children_system", "system time of children"},
8041 {"elapsed", "elapsed time since an arbitrary point in the past"},
8042 {NULL}
8043};
8044
8045PyDoc_STRVAR(times_result__doc__,
8046"times_result: Result from os.times().\n\n\
8047This object may be accessed either as a tuple of\n\
8048 (user, system, children_user, children_system, elapsed),\n\
8049or via the attributes user, system, children_user, children_system,\n\
8050and elapsed.\n\
8051\n\
8052See os.times for more information.");
8053
8054static PyStructSequence_Desc times_result_desc = {
8055 "times_result", /* name */
8056 times_result__doc__, /* doc */
8057 times_result_fields,
8058 5
8059};
8060
Eddie Elizondo474eedf2018-11-13 04:09:31 -08008061static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07008062
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008063#ifdef MS_WINDOWS
8064#define HAVE_TIMES /* mandatory, for the method table */
8065#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008066
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008067#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008068
8069static PyObject *
8070build_times_result(double user, double system,
8071 double children_user, double children_system,
8072 double elapsed)
8073{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08008074 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008075 if (value == NULL)
8076 return NULL;
8077
8078#define SET(i, field) \
8079 { \
8080 PyObject *o = PyFloat_FromDouble(field); \
8081 if (!o) { \
8082 Py_DECREF(value); \
8083 return NULL; \
8084 } \
8085 PyStructSequence_SET_ITEM(value, i, o); \
8086 } \
8087
8088 SET(0, user);
8089 SET(1, system);
8090 SET(2, children_user);
8091 SET(3, children_system);
8092 SET(4, elapsed);
8093
8094#undef SET
8095
8096 return value;
8097}
8098
Larry Hastings605a62d2012-06-24 04:33:36 -07008099
Larry Hastings2f936352014-08-05 14:04:04 +10008100#ifndef MS_WINDOWS
8101#define NEED_TICKS_PER_SECOND
8102static long ticks_per_second = -1;
8103#endif /* MS_WINDOWS */
8104
8105/*[clinic input]
8106os.times
8107
8108Return a collection containing process timing information.
8109
8110The object returned behaves like a named tuple with these fields:
8111 (utime, stime, cutime, cstime, elapsed_time)
8112All fields are floating point numbers.
8113[clinic start generated code]*/
8114
Larry Hastings2f936352014-08-05 14:04:04 +10008115static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008116os_times_impl(PyObject *module)
8117/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008118#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008119{
Victor Stinner8c62be82010-05-06 00:08:46 +00008120 FILETIME create, exit, kernel, user;
8121 HANDLE hProc;
8122 hProc = GetCurrentProcess();
8123 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8124 /* The fields of a FILETIME structure are the hi and lo part
8125 of a 64-bit value expressed in 100 nanosecond units.
8126 1e7 is one second in such units; 1e-7 the inverse.
8127 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8128 */
Larry Hastings605a62d2012-06-24 04:33:36 -07008129 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00008130 (double)(user.dwHighDateTime*429.4967296 +
8131 user.dwLowDateTime*1e-7),
8132 (double)(kernel.dwHighDateTime*429.4967296 +
8133 kernel.dwLowDateTime*1e-7),
8134 (double)0,
8135 (double)0,
8136 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008137}
Larry Hastings2f936352014-08-05 14:04:04 +10008138#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008139{
Larry Hastings2f936352014-08-05 14:04:04 +10008140
8141
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008142 struct tms t;
8143 clock_t c;
8144 errno = 0;
8145 c = times(&t);
8146 if (c == (clock_t) -1)
8147 return posix_error();
8148 return build_times_result(
8149 (double)t.tms_utime / ticks_per_second,
8150 (double)t.tms_stime / ticks_per_second,
8151 (double)t.tms_cutime / ticks_per_second,
8152 (double)t.tms_cstime / ticks_per_second,
8153 (double)c / ticks_per_second);
8154}
Larry Hastings2f936352014-08-05 14:04:04 +10008155#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008156#endif /* HAVE_TIMES */
8157
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008158
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008159#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008160/*[clinic input]
8161os.getsid
8162
8163 pid: pid_t
8164 /
8165
8166Call the system call getsid(pid) and return the result.
8167[clinic start generated code]*/
8168
Larry Hastings2f936352014-08-05 14:04:04 +10008169static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008170os_getsid_impl(PyObject *module, pid_t pid)
8171/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008172{
Victor Stinner8c62be82010-05-06 00:08:46 +00008173 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008174 sid = getsid(pid);
8175 if (sid < 0)
8176 return posix_error();
8177 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008178}
8179#endif /* HAVE_GETSID */
8180
8181
Guido van Rossumb6775db1994-08-01 11:34:53 +00008182#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008183/*[clinic input]
8184os.setsid
8185
8186Call the system call setsid().
8187[clinic start generated code]*/
8188
Larry Hastings2f936352014-08-05 14:04:04 +10008189static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008190os_setsid_impl(PyObject *module)
8191/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008192{
Victor Stinner8c62be82010-05-06 00:08:46 +00008193 if (setsid() < 0)
8194 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008195 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008196}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008197#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008198
Larry Hastings2f936352014-08-05 14:04:04 +10008199
Guido van Rossumb6775db1994-08-01 11:34:53 +00008200#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008201/*[clinic input]
8202os.setpgid
8203
8204 pid: pid_t
8205 pgrp: pid_t
8206 /
8207
8208Call the system call setpgid(pid, pgrp).
8209[clinic start generated code]*/
8210
Larry Hastings2f936352014-08-05 14:04:04 +10008211static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008212os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8213/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008214{
Victor Stinner8c62be82010-05-06 00:08:46 +00008215 if (setpgid(pid, pgrp) < 0)
8216 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008217 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008218}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008219#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008220
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008221
Guido van Rossumb6775db1994-08-01 11:34:53 +00008222#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008223/*[clinic input]
8224os.tcgetpgrp
8225
8226 fd: int
8227 /
8228
8229Return the process group associated with the terminal specified by fd.
8230[clinic start generated code]*/
8231
Larry Hastings2f936352014-08-05 14:04:04 +10008232static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008233os_tcgetpgrp_impl(PyObject *module, int fd)
8234/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008235{
8236 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008237 if (pgid < 0)
8238 return posix_error();
8239 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008240}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008241#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008243
Guido van Rossumb6775db1994-08-01 11:34:53 +00008244#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008245/*[clinic input]
8246os.tcsetpgrp
8247
8248 fd: int
8249 pgid: pid_t
8250 /
8251
8252Set the process group associated with the terminal specified by fd.
8253[clinic start generated code]*/
8254
Larry Hastings2f936352014-08-05 14:04:04 +10008255static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008256os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8257/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008258{
Victor Stinner8c62be82010-05-06 00:08:46 +00008259 if (tcsetpgrp(fd, pgid) < 0)
8260 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008261 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008262}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008263#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008264
Guido van Rossum687dd131993-05-17 08:34:16 +00008265/* Functions acting on file descriptors */
8266
Victor Stinnerdaf45552013-08-28 00:53:59 +02008267#ifdef O_CLOEXEC
8268extern int _Py_open_cloexec_works;
8269#endif
8270
Larry Hastings2f936352014-08-05 14:04:04 +10008271
8272/*[clinic input]
8273os.open -> int
8274 path: path_t
8275 flags: int
8276 mode: int = 0o777
8277 *
8278 dir_fd: dir_fd(requires='openat') = None
8279
8280# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8281
8282Open a file for low level IO. Returns a file descriptor (integer).
8283
8284If dir_fd is not None, it should be a file descriptor open to a directory,
8285 and path should be relative; path will then be relative to that directory.
8286dir_fd may not be implemented on your platform.
8287 If it is unavailable, using it will raise a NotImplementedError.
8288[clinic start generated code]*/
8289
Larry Hastings2f936352014-08-05 14:04:04 +10008290static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008291os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8292/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008293{
8294 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008295 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008296
Victor Stinnerdaf45552013-08-28 00:53:59 +02008297#ifdef O_CLOEXEC
8298 int *atomic_flag_works = &_Py_open_cloexec_works;
8299#elif !defined(MS_WINDOWS)
8300 int *atomic_flag_works = NULL;
8301#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008302
Victor Stinnerdaf45552013-08-28 00:53:59 +02008303#ifdef MS_WINDOWS
8304 flags |= O_NOINHERIT;
8305#elif defined(O_CLOEXEC)
8306 flags |= O_CLOEXEC;
8307#endif
8308
Steve Dowerb82e17e2019-05-23 08:45:22 -07008309 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
8310 return -1;
8311 }
8312
Steve Dower8fc89802015-04-12 00:26:27 -04008313 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008314 do {
8315 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008316#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008317 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008318#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008319#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008320 if (dir_fd != DEFAULT_DIR_FD)
8321 fd = openat(dir_fd, path->narrow, flags, mode);
8322 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008323#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008324 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008325#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008326 Py_END_ALLOW_THREADS
8327 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008328 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008329
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008330 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008331 if (!async_err)
8332 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008333 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008334 }
8335
Victor Stinnerdaf45552013-08-28 00:53:59 +02008336#ifndef MS_WINDOWS
8337 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8338 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008339 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008340 }
8341#endif
8342
Larry Hastings2f936352014-08-05 14:04:04 +10008343 return fd;
8344}
8345
8346
8347/*[clinic input]
8348os.close
8349
8350 fd: int
8351
8352Close a file descriptor.
8353[clinic start generated code]*/
8354
Barry Warsaw53699e91996-12-10 23:23:01 +00008355static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008356os_close_impl(PyObject *module, int fd)
8357/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008358{
Larry Hastings2f936352014-08-05 14:04:04 +10008359 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008360 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8361 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8362 * for more details.
8363 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008364 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008365 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008366 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008367 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008368 Py_END_ALLOW_THREADS
8369 if (res < 0)
8370 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008371 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008372}
8373
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008374
Larry Hastings2f936352014-08-05 14:04:04 +10008375/*[clinic input]
8376os.closerange
8377
8378 fd_low: int
8379 fd_high: int
8380 /
8381
8382Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8383[clinic start generated code]*/
8384
Larry Hastings2f936352014-08-05 14:04:04 +10008385static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008386os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8387/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008388{
8389 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008391 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008392 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008393 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008394 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008395 Py_END_ALLOW_THREADS
8396 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008397}
8398
8399
Larry Hastings2f936352014-08-05 14:04:04 +10008400/*[clinic input]
8401os.dup -> int
8402
8403 fd: int
8404 /
8405
8406Return a duplicate of a file descriptor.
8407[clinic start generated code]*/
8408
Larry Hastings2f936352014-08-05 14:04:04 +10008409static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008410os_dup_impl(PyObject *module, int fd)
8411/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008412{
8413 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008414}
8415
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008416
Larry Hastings2f936352014-08-05 14:04:04 +10008417/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008418os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008419 fd: int
8420 fd2: int
8421 inheritable: bool=True
8422
8423Duplicate file descriptor.
8424[clinic start generated code]*/
8425
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008426static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008427os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008428/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008429{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008430 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008431#if defined(HAVE_DUP3) && \
8432 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8433 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008434 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008435#endif
8436
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008437 if (fd < 0 || fd2 < 0) {
8438 posix_error();
8439 return -1;
8440 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008441
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008442 /* dup2() can fail with EINTR if the target FD is already open, because it
8443 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8444 * upon close(), and therefore below.
8445 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008446#ifdef MS_WINDOWS
8447 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008448 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008449 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008450 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008451 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008452 if (res < 0) {
8453 posix_error();
8454 return -1;
8455 }
8456 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008457
8458 /* Character files like console cannot be make non-inheritable */
8459 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8460 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008461 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008462 }
8463
8464#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8465 Py_BEGIN_ALLOW_THREADS
8466 if (!inheritable)
8467 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8468 else
8469 res = dup2(fd, fd2);
8470 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008471 if (res < 0) {
8472 posix_error();
8473 return -1;
8474 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008475
8476#else
8477
8478#ifdef HAVE_DUP3
8479 if (!inheritable && dup3_works != 0) {
8480 Py_BEGIN_ALLOW_THREADS
8481 res = dup3(fd, fd2, O_CLOEXEC);
8482 Py_END_ALLOW_THREADS
8483 if (res < 0) {
8484 if (dup3_works == -1)
8485 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008486 if (dup3_works) {
8487 posix_error();
8488 return -1;
8489 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008490 }
8491 }
8492
8493 if (inheritable || dup3_works == 0)
8494 {
8495#endif
8496 Py_BEGIN_ALLOW_THREADS
8497 res = dup2(fd, fd2);
8498 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008499 if (res < 0) {
8500 posix_error();
8501 return -1;
8502 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008503
8504 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8505 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008506 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008507 }
8508#ifdef HAVE_DUP3
8509 }
8510#endif
8511
8512#endif
8513
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008514 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008515}
8516
Larry Hastings2f936352014-08-05 14:04:04 +10008517
Ross Lagerwall7807c352011-03-17 20:20:30 +02008518#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008519/*[clinic input]
8520os.lockf
8521
8522 fd: int
8523 An open file descriptor.
8524 command: int
8525 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8526 length: Py_off_t
8527 The number of bytes to lock, starting at the current position.
8528 /
8529
8530Apply, test or remove a POSIX lock on an open file descriptor.
8531
8532[clinic start generated code]*/
8533
Larry Hastings2f936352014-08-05 14:04:04 +10008534static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008535os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8536/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008537{
8538 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008539
8540 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008541 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008542 Py_END_ALLOW_THREADS
8543
8544 if (res < 0)
8545 return posix_error();
8546
8547 Py_RETURN_NONE;
8548}
Larry Hastings2f936352014-08-05 14:04:04 +10008549#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008550
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008551
Larry Hastings2f936352014-08-05 14:04:04 +10008552/*[clinic input]
8553os.lseek -> Py_off_t
8554
8555 fd: int
8556 position: Py_off_t
8557 how: int
8558 /
8559
8560Set the position of a file descriptor. Return the new position.
8561
8562Return the new cursor position in number of bytes
8563relative to the beginning of the file.
8564[clinic start generated code]*/
8565
Larry Hastings2f936352014-08-05 14:04:04 +10008566static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008567os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8568/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008569{
8570 Py_off_t result;
8571
Guido van Rossum687dd131993-05-17 08:34:16 +00008572#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008573 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8574 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008575 case 0: how = SEEK_SET; break;
8576 case 1: how = SEEK_CUR; break;
8577 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008578 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008579#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008580
Victor Stinner8c62be82010-05-06 00:08:46 +00008581 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008582 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008583#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008584 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008585#else
Larry Hastings2f936352014-08-05 14:04:04 +10008586 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008587#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008588 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008589 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008590 if (result < 0)
8591 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008592
Larry Hastings2f936352014-08-05 14:04:04 +10008593 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008594}
8595
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008596
Larry Hastings2f936352014-08-05 14:04:04 +10008597/*[clinic input]
8598os.read
8599 fd: int
8600 length: Py_ssize_t
8601 /
8602
8603Read from a file descriptor. Returns a bytes object.
8604[clinic start generated code]*/
8605
Larry Hastings2f936352014-08-05 14:04:04 +10008606static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008607os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8608/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008609{
Victor Stinner8c62be82010-05-06 00:08:46 +00008610 Py_ssize_t n;
8611 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008612
8613 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008614 errno = EINVAL;
8615 return posix_error();
8616 }
Larry Hastings2f936352014-08-05 14:04:04 +10008617
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008618 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008619
8620 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008621 if (buffer == NULL)
8622 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008623
Victor Stinner66aab0c2015-03-19 22:53:20 +01008624 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8625 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008626 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008627 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008628 }
Larry Hastings2f936352014-08-05 14:04:04 +10008629
8630 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008631 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008632
Victor Stinner8c62be82010-05-06 00:08:46 +00008633 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008634}
8635
Ross Lagerwall7807c352011-03-17 20:20:30 +02008636#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008637 || defined(__APPLE__))) \
8638 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8639 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8640static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008641iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008642{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008643 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008644
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008645 *iov = PyMem_New(struct iovec, cnt);
8646 if (*iov == NULL) {
8647 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008648 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008649 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008650
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008651 *buf = PyMem_New(Py_buffer, cnt);
8652 if (*buf == NULL) {
8653 PyMem_Del(*iov);
8654 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008655 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008656 }
8657
8658 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008659 PyObject *item = PySequence_GetItem(seq, i);
8660 if (item == NULL)
8661 goto fail;
8662 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8663 Py_DECREF(item);
8664 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008665 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008666 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008667 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008668 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008669 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008670 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008671
8672fail:
8673 PyMem_Del(*iov);
8674 for (j = 0; j < i; j++) {
8675 PyBuffer_Release(&(*buf)[j]);
8676 }
8677 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008678 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008679}
8680
8681static void
8682iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8683{
8684 int i;
8685 PyMem_Del(iov);
8686 for (i = 0; i < cnt; i++) {
8687 PyBuffer_Release(&buf[i]);
8688 }
8689 PyMem_Del(buf);
8690}
8691#endif
8692
Larry Hastings2f936352014-08-05 14:04:04 +10008693
Ross Lagerwall7807c352011-03-17 20:20:30 +02008694#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008695/*[clinic input]
8696os.readv -> Py_ssize_t
8697
8698 fd: int
8699 buffers: object
8700 /
8701
8702Read from a file descriptor fd into an iterable of buffers.
8703
8704The buffers should be mutable buffers accepting bytes.
8705readv will transfer data into each buffer until it is full
8706and then move on to the next buffer in the sequence to hold
8707the rest of the data.
8708
8709readv returns the total number of bytes read,
8710which may be less than the total capacity of all the buffers.
8711[clinic start generated code]*/
8712
Larry Hastings2f936352014-08-05 14:04:04 +10008713static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008714os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8715/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008716{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008717 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008718 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008719 struct iovec *iov;
8720 Py_buffer *buf;
8721
Larry Hastings2f936352014-08-05 14:04:04 +10008722 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008723 PyErr_SetString(PyExc_TypeError,
8724 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008725 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008726 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008727
Larry Hastings2f936352014-08-05 14:04:04 +10008728 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008729 if (cnt < 0)
8730 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008731
8732 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8733 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008734
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008735 do {
8736 Py_BEGIN_ALLOW_THREADS
8737 n = readv(fd, iov, cnt);
8738 Py_END_ALLOW_THREADS
8739 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008740
8741 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008742 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008743 if (!async_err)
8744 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008745 return -1;
8746 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008747
Larry Hastings2f936352014-08-05 14:04:04 +10008748 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008749}
Larry Hastings2f936352014-08-05 14:04:04 +10008750#endif /* HAVE_READV */
8751
Ross Lagerwall7807c352011-03-17 20:20:30 +02008752
8753#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008754/*[clinic input]
8755# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8756os.pread
8757
8758 fd: int
8759 length: int
8760 offset: Py_off_t
8761 /
8762
8763Read a number of bytes from a file descriptor starting at a particular offset.
8764
8765Read length bytes from file descriptor fd, starting at offset bytes from
8766the beginning of the file. The file offset remains unchanged.
8767[clinic start generated code]*/
8768
Larry Hastings2f936352014-08-05 14:04:04 +10008769static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008770os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8771/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008772{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008773 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008774 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008775 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008776
Larry Hastings2f936352014-08-05 14:04:04 +10008777 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008778 errno = EINVAL;
8779 return posix_error();
8780 }
Larry Hastings2f936352014-08-05 14:04:04 +10008781 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008782 if (buffer == NULL)
8783 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008784
8785 do {
8786 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008787 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008788 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008789 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008790 Py_END_ALLOW_THREADS
8791 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8792
Ross Lagerwall7807c352011-03-17 20:20:30 +02008793 if (n < 0) {
8794 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008795 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008796 }
Larry Hastings2f936352014-08-05 14:04:04 +10008797 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008798 _PyBytes_Resize(&buffer, n);
8799 return buffer;
8800}
Larry Hastings2f936352014-08-05 14:04:04 +10008801#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008802
Pablo Galindo4defba32018-01-27 16:16:37 +00008803#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8804/*[clinic input]
8805os.preadv -> Py_ssize_t
8806
8807 fd: int
8808 buffers: object
8809 offset: Py_off_t
8810 flags: int = 0
8811 /
8812
8813Reads from a file descriptor into a number of mutable bytes-like objects.
8814
8815Combines the functionality of readv() and pread(). As readv(), it will
8816transfer data into each buffer until it is full and then move on to the next
8817buffer in the sequence to hold the rest of the data. Its fourth argument,
8818specifies the file offset at which the input operation is to be performed. It
8819will return the total number of bytes read (which can be less than the total
8820capacity of all the objects).
8821
8822The flags argument contains a bitwise OR of zero or more of the following flags:
8823
8824- RWF_HIPRI
8825- RWF_NOWAIT
8826
8827Using non-zero flags requires Linux 4.6 or newer.
8828[clinic start generated code]*/
8829
8830static Py_ssize_t
8831os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8832 int flags)
8833/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8834{
8835 Py_ssize_t cnt, n;
8836 int async_err = 0;
8837 struct iovec *iov;
8838 Py_buffer *buf;
8839
8840 if (!PySequence_Check(buffers)) {
8841 PyErr_SetString(PyExc_TypeError,
8842 "preadv2() arg 2 must be a sequence");
8843 return -1;
8844 }
8845
8846 cnt = PySequence_Size(buffers);
8847 if (cnt < 0) {
8848 return -1;
8849 }
8850
8851#ifndef HAVE_PREADV2
8852 if(flags != 0) {
8853 argument_unavailable_error("preadv2", "flags");
8854 return -1;
8855 }
8856#endif
8857
8858 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8859 return -1;
8860 }
8861#ifdef HAVE_PREADV2
8862 do {
8863 Py_BEGIN_ALLOW_THREADS
8864 _Py_BEGIN_SUPPRESS_IPH
8865 n = preadv2(fd, iov, cnt, offset, flags);
8866 _Py_END_SUPPRESS_IPH
8867 Py_END_ALLOW_THREADS
8868 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8869#else
8870 do {
8871 Py_BEGIN_ALLOW_THREADS
8872 _Py_BEGIN_SUPPRESS_IPH
8873 n = preadv(fd, iov, cnt, offset);
8874 _Py_END_SUPPRESS_IPH
8875 Py_END_ALLOW_THREADS
8876 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8877#endif
8878
8879 iov_cleanup(iov, buf, cnt);
8880 if (n < 0) {
8881 if (!async_err) {
8882 posix_error();
8883 }
8884 return -1;
8885 }
8886
8887 return n;
8888}
8889#endif /* HAVE_PREADV */
8890
Larry Hastings2f936352014-08-05 14:04:04 +10008891
8892/*[clinic input]
8893os.write -> Py_ssize_t
8894
8895 fd: int
8896 data: Py_buffer
8897 /
8898
8899Write a bytes object to a file descriptor.
8900[clinic start generated code]*/
8901
Larry Hastings2f936352014-08-05 14:04:04 +10008902static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008903os_write_impl(PyObject *module, int fd, Py_buffer *data)
8904/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008905{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008906 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008907}
8908
8909#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008910PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008911"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008912sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008913 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008914Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008915
Larry Hastings2f936352014-08-05 14:04:04 +10008916/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008917static PyObject *
8918posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8919{
8920 int in, out;
8921 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008922 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008923 off_t offset;
8924
8925#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8926#ifndef __APPLE__
8927 Py_ssize_t len;
8928#endif
8929 PyObject *headers = NULL, *trailers = NULL;
8930 Py_buffer *hbuf, *tbuf;
8931 off_t sbytes;
8932 struct sf_hdtr sf;
8933 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008934 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008935 static char *keywords[] = {"out", "in",
8936 "offset", "count",
8937 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008938
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008939 sf.headers = NULL;
8940 sf.trailers = NULL;
8941
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008942#ifdef __APPLE__
8943 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008944 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008945#else
8946 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008947 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008948#endif
8949 &headers, &trailers, &flags))
8950 return NULL;
8951 if (headers != NULL) {
8952 if (!PySequence_Check(headers)) {
8953 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008954 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008955 return NULL;
8956 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008957 Py_ssize_t i = PySequence_Size(headers);
8958 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008959 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008960 if (i > INT_MAX) {
8961 PyErr_SetString(PyExc_OverflowError,
8962 "sendfile() header is too large");
8963 return NULL;
8964 }
8965 if (i > 0) {
8966 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008967 if (iov_setup(&(sf.headers), &hbuf,
8968 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008969 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008970#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008971 for (i = 0; i < sf.hdr_cnt; i++) {
8972 Py_ssize_t blen = sf.headers[i].iov_len;
8973# define OFF_T_MAX 0x7fffffffffffffff
8974 if (sbytes >= OFF_T_MAX - blen) {
8975 PyErr_SetString(PyExc_OverflowError,
8976 "sendfile() header is too large");
8977 return NULL;
8978 }
8979 sbytes += blen;
8980 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008981#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008982 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008983 }
8984 }
8985 if (trailers != NULL) {
8986 if (!PySequence_Check(trailers)) {
8987 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008988 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008989 return NULL;
8990 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008991 Py_ssize_t i = PySequence_Size(trailers);
8992 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008993 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008994 if (i > INT_MAX) {
8995 PyErr_SetString(PyExc_OverflowError,
8996 "sendfile() trailer is too large");
8997 return NULL;
8998 }
8999 if (i > 0) {
9000 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009001 if (iov_setup(&(sf.trailers), &tbuf,
9002 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009003 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009004 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009005 }
9006 }
9007
Steve Dower8fc89802015-04-12 00:26:27 -04009008 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009009 do {
9010 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009011#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009012 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009013#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009014 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009015#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009016 Py_END_ALLOW_THREADS
9017 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009018 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009019
9020 if (sf.headers != NULL)
9021 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9022 if (sf.trailers != NULL)
9023 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9024
9025 if (ret < 0) {
9026 if ((errno == EAGAIN) || (errno == EBUSY)) {
9027 if (sbytes != 0) {
9028 // some data has been sent
9029 goto done;
9030 }
9031 else {
9032 // no data has been sent; upper application is supposed
9033 // to retry on EAGAIN or EBUSY
9034 return posix_error();
9035 }
9036 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009037 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009038 }
9039 goto done;
9040
9041done:
9042 #if !defined(HAVE_LARGEFILE_SUPPORT)
9043 return Py_BuildValue("l", sbytes);
9044 #else
9045 return Py_BuildValue("L", sbytes);
9046 #endif
9047
9048#else
9049 Py_ssize_t count;
9050 PyObject *offobj;
9051 static char *keywords[] = {"out", "in",
9052 "offset", "count", NULL};
9053 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
9054 keywords, &out, &in, &offobj, &count))
9055 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009056#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009057 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009058 do {
9059 Py_BEGIN_ALLOW_THREADS
9060 ret = sendfile(out, in, NULL, count);
9061 Py_END_ALLOW_THREADS
9062 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009063 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009064 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009065 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009066 }
9067#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009068 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009069 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009070
9071 do {
9072 Py_BEGIN_ALLOW_THREADS
9073 ret = sendfile(out, in, &offset, count);
9074 Py_END_ALLOW_THREADS
9075 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009076 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009077 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009078 return Py_BuildValue("n", ret);
9079#endif
9080}
Larry Hastings2f936352014-08-05 14:04:04 +10009081#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009082
Larry Hastings2f936352014-08-05 14:04:04 +10009083
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009084#if defined(__APPLE__)
9085/*[clinic input]
9086os._fcopyfile
9087
9088 infd: int
9089 outfd: int
9090 flags: int
9091 /
9092
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009093Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009094[clinic start generated code]*/
9095
9096static PyObject *
9097os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009098/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009099{
9100 int ret;
9101
9102 Py_BEGIN_ALLOW_THREADS
9103 ret = fcopyfile(infd, outfd, NULL, flags);
9104 Py_END_ALLOW_THREADS
9105 if (ret < 0)
9106 return posix_error();
9107 Py_RETURN_NONE;
9108}
9109#endif
9110
9111
Larry Hastings2f936352014-08-05 14:04:04 +10009112/*[clinic input]
9113os.fstat
9114
9115 fd : int
9116
9117Perform a stat system call on the given file descriptor.
9118
9119Like stat(), but for an open file descriptor.
9120Equivalent to os.stat(fd).
9121[clinic start generated code]*/
9122
Larry Hastings2f936352014-08-05 14:04:04 +10009123static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009124os_fstat_impl(PyObject *module, int fd)
9125/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009126{
Victor Stinner8c62be82010-05-06 00:08:46 +00009127 STRUCT_STAT st;
9128 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009129 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009130
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009131 do {
9132 Py_BEGIN_ALLOW_THREADS
9133 res = FSTAT(fd, &st);
9134 Py_END_ALLOW_THREADS
9135 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009136 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009137#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009138 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009139#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009140 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009141#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009142 }
Tim Peters5aa91602002-01-30 05:46:57 +00009143
Victor Stinner4195b5c2012-02-08 23:03:19 +01009144 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009145}
9146
Larry Hastings2f936352014-08-05 14:04:04 +10009147
9148/*[clinic input]
9149os.isatty -> bool
9150 fd: int
9151 /
9152
9153Return True if the fd is connected to a terminal.
9154
9155Return True if the file descriptor is an open file descriptor
9156connected to the slave end of a terminal.
9157[clinic start generated code]*/
9158
Larry Hastings2f936352014-08-05 14:04:04 +10009159static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009160os_isatty_impl(PyObject *module, int fd)
9161/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009162{
Steve Dower8fc89802015-04-12 00:26:27 -04009163 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009164 _Py_BEGIN_SUPPRESS_IPH
9165 return_value = isatty(fd);
9166 _Py_END_SUPPRESS_IPH
9167 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009168}
9169
9170
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009171#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009172/*[clinic input]
9173os.pipe
9174
9175Create a pipe.
9176
9177Returns a tuple of two file descriptors:
9178 (read_fd, write_fd)
9179[clinic start generated code]*/
9180
Larry Hastings2f936352014-08-05 14:04:04 +10009181static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009182os_pipe_impl(PyObject *module)
9183/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009184{
Victor Stinner8c62be82010-05-06 00:08:46 +00009185 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009186#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009187 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009188 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009189 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009190#else
9191 int res;
9192#endif
9193
9194#ifdef MS_WINDOWS
9195 attr.nLength = sizeof(attr);
9196 attr.lpSecurityDescriptor = NULL;
9197 attr.bInheritHandle = FALSE;
9198
9199 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009200 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009201 ok = CreatePipe(&read, &write, &attr, 0);
9202 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009203 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9204 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009205 if (fds[0] == -1 || fds[1] == -1) {
9206 CloseHandle(read);
9207 CloseHandle(write);
9208 ok = 0;
9209 }
9210 }
Steve Dowerc3630612016-11-19 18:41:16 -08009211 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009212 Py_END_ALLOW_THREADS
9213
Victor Stinner8c62be82010-05-06 00:08:46 +00009214 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009215 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009216#else
9217
9218#ifdef HAVE_PIPE2
9219 Py_BEGIN_ALLOW_THREADS
9220 res = pipe2(fds, O_CLOEXEC);
9221 Py_END_ALLOW_THREADS
9222
9223 if (res != 0 && errno == ENOSYS)
9224 {
9225#endif
9226 Py_BEGIN_ALLOW_THREADS
9227 res = pipe(fds);
9228 Py_END_ALLOW_THREADS
9229
9230 if (res == 0) {
9231 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9232 close(fds[0]);
9233 close(fds[1]);
9234 return NULL;
9235 }
9236 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9237 close(fds[0]);
9238 close(fds[1]);
9239 return NULL;
9240 }
9241 }
9242#ifdef HAVE_PIPE2
9243 }
9244#endif
9245
9246 if (res != 0)
9247 return PyErr_SetFromErrno(PyExc_OSError);
9248#endif /* !MS_WINDOWS */
9249 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009250}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009251#endif /* HAVE_PIPE */
9252
Larry Hastings2f936352014-08-05 14:04:04 +10009253
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009254#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009255/*[clinic input]
9256os.pipe2
9257
9258 flags: int
9259 /
9260
9261Create a pipe with flags set atomically.
9262
9263Returns a tuple of two file descriptors:
9264 (read_fd, write_fd)
9265
9266flags can be constructed by ORing together one or more of these values:
9267O_NONBLOCK, O_CLOEXEC.
9268[clinic start generated code]*/
9269
Larry Hastings2f936352014-08-05 14:04:04 +10009270static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009271os_pipe2_impl(PyObject *module, int flags)
9272/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009273{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009274 int fds[2];
9275 int res;
9276
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009277 res = pipe2(fds, flags);
9278 if (res != 0)
9279 return posix_error();
9280 return Py_BuildValue("(ii)", fds[0], fds[1]);
9281}
9282#endif /* HAVE_PIPE2 */
9283
Larry Hastings2f936352014-08-05 14:04:04 +10009284
Ross Lagerwall7807c352011-03-17 20:20:30 +02009285#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009286/*[clinic input]
9287os.writev -> Py_ssize_t
9288 fd: int
9289 buffers: object
9290 /
9291
9292Iterate over buffers, and write the contents of each to a file descriptor.
9293
9294Returns the total number of bytes written.
9295buffers must be a sequence of bytes-like objects.
9296[clinic start generated code]*/
9297
Larry Hastings2f936352014-08-05 14:04:04 +10009298static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009299os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9300/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009301{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009302 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009303 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009304 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009305 struct iovec *iov;
9306 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009307
9308 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009309 PyErr_SetString(PyExc_TypeError,
9310 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009311 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009312 }
Larry Hastings2f936352014-08-05 14:04:04 +10009313 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009314 if (cnt < 0)
9315 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009316
Larry Hastings2f936352014-08-05 14:04:04 +10009317 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9318 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009319 }
9320
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009321 do {
9322 Py_BEGIN_ALLOW_THREADS
9323 result = writev(fd, iov, cnt);
9324 Py_END_ALLOW_THREADS
9325 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009326
9327 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009328 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009329 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009330
Georg Brandl306336b2012-06-24 12:55:33 +02009331 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009332}
Larry Hastings2f936352014-08-05 14:04:04 +10009333#endif /* HAVE_WRITEV */
9334
9335
9336#ifdef HAVE_PWRITE
9337/*[clinic input]
9338os.pwrite -> Py_ssize_t
9339
9340 fd: int
9341 buffer: Py_buffer
9342 offset: Py_off_t
9343 /
9344
9345Write bytes to a file descriptor starting at a particular offset.
9346
9347Write buffer to fd, starting at offset bytes from the beginning of
9348the file. Returns the number of bytes writte. Does not change the
9349current file offset.
9350[clinic start generated code]*/
9351
Larry Hastings2f936352014-08-05 14:04:04 +10009352static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009353os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9354/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009355{
9356 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009357 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009358
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009359 do {
9360 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009361 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009362 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009363 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009364 Py_END_ALLOW_THREADS
9365 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009366
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009367 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009368 posix_error();
9369 return size;
9370}
9371#endif /* HAVE_PWRITE */
9372
Pablo Galindo4defba32018-01-27 16:16:37 +00009373#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9374/*[clinic input]
9375os.pwritev -> Py_ssize_t
9376
9377 fd: int
9378 buffers: object
9379 offset: Py_off_t
9380 flags: int = 0
9381 /
9382
9383Writes the contents of bytes-like objects to a file descriptor at a given offset.
9384
9385Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9386of bytes-like objects. Buffers are processed in array order. Entire contents of first
9387buffer is written before proceeding to second, and so on. The operating system may
9388set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9389This function writes the contents of each object to the file descriptor and returns
9390the total number of bytes written.
9391
9392The flags argument contains a bitwise OR of zero or more of the following flags:
9393
9394- RWF_DSYNC
9395- RWF_SYNC
9396
9397Using non-zero flags requires Linux 4.7 or newer.
9398[clinic start generated code]*/
9399
9400static Py_ssize_t
9401os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9402 int flags)
9403/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9404{
9405 Py_ssize_t cnt;
9406 Py_ssize_t result;
9407 int async_err = 0;
9408 struct iovec *iov;
9409 Py_buffer *buf;
9410
9411 if (!PySequence_Check(buffers)) {
9412 PyErr_SetString(PyExc_TypeError,
9413 "pwritev() arg 2 must be a sequence");
9414 return -1;
9415 }
9416
9417 cnt = PySequence_Size(buffers);
9418 if (cnt < 0) {
9419 return -1;
9420 }
9421
9422#ifndef HAVE_PWRITEV2
9423 if(flags != 0) {
9424 argument_unavailable_error("pwritev2", "flags");
9425 return -1;
9426 }
9427#endif
9428
9429 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9430 return -1;
9431 }
9432#ifdef HAVE_PWRITEV2
9433 do {
9434 Py_BEGIN_ALLOW_THREADS
9435 _Py_BEGIN_SUPPRESS_IPH
9436 result = pwritev2(fd, iov, cnt, offset, flags);
9437 _Py_END_SUPPRESS_IPH
9438 Py_END_ALLOW_THREADS
9439 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9440#else
9441 do {
9442 Py_BEGIN_ALLOW_THREADS
9443 _Py_BEGIN_SUPPRESS_IPH
9444 result = pwritev(fd, iov, cnt, offset);
9445 _Py_END_SUPPRESS_IPH
9446 Py_END_ALLOW_THREADS
9447 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9448#endif
9449
9450 iov_cleanup(iov, buf, cnt);
9451 if (result < 0) {
9452 if (!async_err) {
9453 posix_error();
9454 }
9455 return -1;
9456 }
9457
9458 return result;
9459}
9460#endif /* HAVE_PWRITEV */
9461
Pablo Galindoaac4d032019-05-31 19:39:47 +01009462#ifdef HAVE_COPY_FILE_RANGE
9463/*[clinic input]
9464
9465os.copy_file_range
9466 src: int
9467 Source file descriptor.
9468 dst: int
9469 Destination file descriptor.
9470 count: Py_ssize_t
9471 Number of bytes to copy.
9472 offset_src: object = None
9473 Starting offset in src.
9474 offset_dst: object = None
9475 Starting offset in dst.
9476
9477Copy count bytes from one file descriptor to another.
9478
9479If offset_src is None, then src is read from the current position;
9480respectively for offset_dst.
9481[clinic start generated code]*/
9482
9483static PyObject *
9484os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
9485 PyObject *offset_src, PyObject *offset_dst)
9486/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
9487{
9488 off_t offset_src_val, offset_dst_val;
9489 off_t *p_offset_src = NULL;
9490 off_t *p_offset_dst = NULL;
9491 Py_ssize_t ret;
9492 int async_err = 0;
9493 /* The flags argument is provided to allow
9494 * for future extensions and currently must be to 0. */
9495 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +00009496
9497
Pablo Galindoaac4d032019-05-31 19:39:47 +01009498 if (count < 0) {
9499 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
9500 return NULL;
9501 }
9502
9503 if (offset_src != Py_None) {
9504 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
9505 return NULL;
9506 }
9507 p_offset_src = &offset_src_val;
9508 }
9509
9510 if (offset_dst != Py_None) {
9511 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
9512 return NULL;
9513 }
9514 p_offset_dst = &offset_dst_val;
9515 }
9516
9517 do {
9518 Py_BEGIN_ALLOW_THREADS
9519 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
9520 Py_END_ALLOW_THREADS
9521 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9522
9523 if (ret < 0) {
9524 return (!async_err) ? posix_error() : NULL;
9525 }
9526
9527 return PyLong_FromSsize_t(ret);
9528}
9529#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +10009530
9531#ifdef HAVE_MKFIFO
9532/*[clinic input]
9533os.mkfifo
9534
9535 path: path_t
9536 mode: int=0o666
9537 *
9538 dir_fd: dir_fd(requires='mkfifoat')=None
9539
9540Create a "fifo" (a POSIX named pipe).
9541
9542If dir_fd is not None, it should be a file descriptor open to a directory,
9543 and path should be relative; path will then be relative to that directory.
9544dir_fd may not be implemented on your platform.
9545 If it is unavailable, using it will raise a NotImplementedError.
9546[clinic start generated code]*/
9547
Larry Hastings2f936352014-08-05 14:04:04 +10009548static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009549os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9550/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009551{
9552 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009553 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009554
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009555 do {
9556 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009557#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009558 if (dir_fd != DEFAULT_DIR_FD)
9559 result = mkfifoat(dir_fd, path->narrow, mode);
9560 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009561#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009562 result = mkfifo(path->narrow, mode);
9563 Py_END_ALLOW_THREADS
9564 } while (result != 0 && errno == EINTR &&
9565 !(async_err = PyErr_CheckSignals()));
9566 if (result != 0)
9567 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009568
9569 Py_RETURN_NONE;
9570}
9571#endif /* HAVE_MKFIFO */
9572
9573
9574#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9575/*[clinic input]
9576os.mknod
9577
9578 path: path_t
9579 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009580 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009581 *
9582 dir_fd: dir_fd(requires='mknodat')=None
9583
9584Create a node in the file system.
9585
9586Create a node in the file system (file, device special file or named pipe)
9587at path. mode specifies both the permissions to use and the
9588type of node to be created, being combined (bitwise OR) with one of
9589S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9590device defines the newly created device special file (probably using
9591os.makedev()). Otherwise device is ignored.
9592
9593If dir_fd is not None, it should be a file descriptor open to a directory,
9594 and path should be relative; path will then be relative to that directory.
9595dir_fd may not be implemented on your platform.
9596 If it is unavailable, using it will raise a NotImplementedError.
9597[clinic start generated code]*/
9598
Larry Hastings2f936352014-08-05 14:04:04 +10009599static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009600os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009601 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009602/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009603{
9604 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009605 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009606
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009607 do {
9608 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009609#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009610 if (dir_fd != DEFAULT_DIR_FD)
9611 result = mknodat(dir_fd, path->narrow, mode, device);
9612 else
Larry Hastings2f936352014-08-05 14:04:04 +10009613#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009614 result = mknod(path->narrow, mode, device);
9615 Py_END_ALLOW_THREADS
9616 } while (result != 0 && errno == EINTR &&
9617 !(async_err = PyErr_CheckSignals()));
9618 if (result != 0)
9619 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009620
9621 Py_RETURN_NONE;
9622}
9623#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9624
9625
9626#ifdef HAVE_DEVICE_MACROS
9627/*[clinic input]
9628os.major -> unsigned_int
9629
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009630 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009631 /
9632
9633Extracts a device major number from a raw device number.
9634[clinic start generated code]*/
9635
Larry Hastings2f936352014-08-05 14:04:04 +10009636static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009637os_major_impl(PyObject *module, dev_t device)
9638/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009639{
9640 return major(device);
9641}
9642
9643
9644/*[clinic input]
9645os.minor -> unsigned_int
9646
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009647 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009648 /
9649
9650Extracts a device minor number from a raw device number.
9651[clinic start generated code]*/
9652
Larry Hastings2f936352014-08-05 14:04:04 +10009653static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009654os_minor_impl(PyObject *module, dev_t device)
9655/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009656{
9657 return minor(device);
9658}
9659
9660
9661/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009662os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009663
9664 major: int
9665 minor: int
9666 /
9667
9668Composes a raw device number from the major and minor device numbers.
9669[clinic start generated code]*/
9670
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009671static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009672os_makedev_impl(PyObject *module, int major, int minor)
9673/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009674{
9675 return makedev(major, minor);
9676}
9677#endif /* HAVE_DEVICE_MACROS */
9678
9679
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009680#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009681/*[clinic input]
9682os.ftruncate
9683
9684 fd: int
9685 length: Py_off_t
9686 /
9687
9688Truncate a file, specified by file descriptor, to a specific length.
9689[clinic start generated code]*/
9690
Larry Hastings2f936352014-08-05 14:04:04 +10009691static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009692os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9693/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009694{
9695 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009696 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009697
Steve Dowerb82e17e2019-05-23 08:45:22 -07009698 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
9699 return NULL;
9700 }
9701
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009702 do {
9703 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009704 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009705#ifdef MS_WINDOWS
9706 result = _chsize_s(fd, length);
9707#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009708 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009709#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009710 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009711 Py_END_ALLOW_THREADS
9712 } while (result != 0 && errno == EINTR &&
9713 !(async_err = PyErr_CheckSignals()));
9714 if (result != 0)
9715 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009716 Py_RETURN_NONE;
9717}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009718#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009719
9720
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009721#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009722/*[clinic input]
9723os.truncate
9724 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9725 length: Py_off_t
9726
9727Truncate a file, specified by path, to a specific length.
9728
9729On some platforms, path may also be specified as an open file descriptor.
9730 If this functionality is unavailable, using it raises an exception.
9731[clinic start generated code]*/
9732
Larry Hastings2f936352014-08-05 14:04:04 +10009733static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009734os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9735/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009736{
9737 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009738#ifdef MS_WINDOWS
9739 int fd;
9740#endif
9741
9742 if (path->fd != -1)
9743 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009744
Steve Dowerb82e17e2019-05-23 08:45:22 -07009745 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
9746 return NULL;
9747 }
9748
Larry Hastings2f936352014-08-05 14:04:04 +10009749 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009750 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009751#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009752 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009753 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009754 result = -1;
9755 else {
9756 result = _chsize_s(fd, length);
9757 close(fd);
9758 if (result < 0)
9759 errno = result;
9760 }
9761#else
9762 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009763#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009764 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009765 Py_END_ALLOW_THREADS
9766 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009767 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009768
9769 Py_RETURN_NONE;
9770}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009771#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009772
Ross Lagerwall7807c352011-03-17 20:20:30 +02009773
Victor Stinnerd6b17692014-09-30 12:20:05 +02009774/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9775 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9776 defined, which is the case in Python on AIX. AIX bug report:
9777 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9778#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9779# define POSIX_FADVISE_AIX_BUG
9780#endif
9781
Victor Stinnerec39e262014-09-30 12:35:58 +02009782
Victor Stinnerd6b17692014-09-30 12:20:05 +02009783#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009784/*[clinic input]
9785os.posix_fallocate
9786
9787 fd: int
9788 offset: Py_off_t
9789 length: Py_off_t
9790 /
9791
9792Ensure a file has allocated at least a particular number of bytes on disk.
9793
9794Ensure that the file specified by fd encompasses a range of bytes
9795starting at offset bytes from the beginning and continuing for length bytes.
9796[clinic start generated code]*/
9797
Larry Hastings2f936352014-08-05 14:04:04 +10009798static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009799os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009800 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009801/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009802{
9803 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009804 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009805
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009806 do {
9807 Py_BEGIN_ALLOW_THREADS
9808 result = posix_fallocate(fd, offset, length);
9809 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009810 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9811
9812 if (result == 0)
9813 Py_RETURN_NONE;
9814
9815 if (async_err)
9816 return NULL;
9817
9818 errno = result;
9819 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009820}
Victor Stinnerec39e262014-09-30 12:35:58 +02009821#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009822
Ross Lagerwall7807c352011-03-17 20:20:30 +02009823
Victor Stinnerd6b17692014-09-30 12:20:05 +02009824#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009825/*[clinic input]
9826os.posix_fadvise
9827
9828 fd: int
9829 offset: Py_off_t
9830 length: Py_off_t
9831 advice: int
9832 /
9833
9834Announce an intention to access data in a specific pattern.
9835
9836Announce an intention to access data in a specific pattern, thus allowing
9837the kernel to make optimizations.
9838The advice applies to the region of the file specified by fd starting at
9839offset and continuing for length bytes.
9840advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9841POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9842POSIX_FADV_DONTNEED.
9843[clinic start generated code]*/
9844
Larry Hastings2f936352014-08-05 14:04:04 +10009845static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009846os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009847 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009848/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009849{
9850 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009851 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009852
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009853 do {
9854 Py_BEGIN_ALLOW_THREADS
9855 result = posix_fadvise(fd, offset, length, advice);
9856 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009857 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9858
9859 if (result == 0)
9860 Py_RETURN_NONE;
9861
9862 if (async_err)
9863 return NULL;
9864
9865 errno = result;
9866 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009867}
Victor Stinnerec39e262014-09-30 12:35:58 +02009868#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009869
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009870#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009871
Fred Drake762e2061999-08-26 17:23:54 +00009872/* Save putenv() parameters as values here, so we can collect them when they
9873 * get re-set with another call for the same key. */
9874static PyObject *posix_putenv_garbage;
9875
Larry Hastings2f936352014-08-05 14:04:04 +10009876static void
9877posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009878{
Larry Hastings2f936352014-08-05 14:04:04 +10009879 /* Install the first arg and newstr in posix_putenv_garbage;
9880 * this will cause previous value to be collected. This has to
9881 * happen after the real putenv() call because the old value
9882 * was still accessible until then. */
9883 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9884 /* really not much we can do; just leak */
9885 PyErr_Clear();
9886 else
9887 Py_DECREF(value);
9888}
9889
9890
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009891#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009892/*[clinic input]
9893os.putenv
9894
9895 name: unicode
9896 value: unicode
9897 /
9898
9899Change or add an environment variable.
9900[clinic start generated code]*/
9901
Larry Hastings2f936352014-08-05 14:04:04 +10009902static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009903os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9904/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009905{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009906 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009907 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009908
Serhiy Storchaka77703942017-06-25 07:33:01 +03009909 /* Search from index 1 because on Windows starting '=' is allowed for
9910 defining hidden environment variables. */
9911 if (PyUnicode_GET_LENGTH(name) == 0 ||
9912 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9913 {
9914 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9915 return NULL;
9916 }
Larry Hastings2f936352014-08-05 14:04:04 +10009917 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9918 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009919 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009920 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009921
9922 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9923 if (env == NULL)
9924 goto error;
9925 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009926 PyErr_Format(PyExc_ValueError,
9927 "the environment variable is longer than %u characters",
9928 _MAX_ENV);
9929 goto error;
9930 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009931 if (wcslen(env) != (size_t)size) {
9932 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009933 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009934 }
9935
Larry Hastings2f936352014-08-05 14:04:04 +10009936 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009938 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009940
Larry Hastings2f936352014-08-05 14:04:04 +10009941 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009942 Py_RETURN_NONE;
9943
9944error:
Larry Hastings2f936352014-08-05 14:04:04 +10009945 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009946 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009947}
Larry Hastings2f936352014-08-05 14:04:04 +10009948#else /* MS_WINDOWS */
9949/*[clinic input]
9950os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009951
Larry Hastings2f936352014-08-05 14:04:04 +10009952 name: FSConverter
9953 value: FSConverter
9954 /
9955
9956Change or add an environment variable.
9957[clinic start generated code]*/
9958
Larry Hastings2f936352014-08-05 14:04:04 +10009959static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009960os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9961/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009962{
9963 PyObject *bytes = NULL;
9964 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009965 const char *name_string = PyBytes_AS_STRING(name);
9966 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009967
Serhiy Storchaka77703942017-06-25 07:33:01 +03009968 if (strchr(name_string, '=') != NULL) {
9969 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9970 return NULL;
9971 }
Larry Hastings2f936352014-08-05 14:04:04 +10009972 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9973 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009974 return NULL;
9975 }
9976
9977 env = PyBytes_AS_STRING(bytes);
9978 if (putenv(env)) {
9979 Py_DECREF(bytes);
9980 return posix_error();
9981 }
9982
9983 posix_putenv_garbage_setitem(name, bytes);
9984 Py_RETURN_NONE;
9985}
9986#endif /* MS_WINDOWS */
9987#endif /* HAVE_PUTENV */
9988
9989
9990#ifdef HAVE_UNSETENV
9991/*[clinic input]
9992os.unsetenv
9993 name: FSConverter
9994 /
9995
9996Delete an environment variable.
9997[clinic start generated code]*/
9998
Larry Hastings2f936352014-08-05 14:04:04 +10009999static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010000os_unsetenv_impl(PyObject *module, PyObject *name)
10001/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010002{
Victor Stinner984890f2011-11-24 13:53:38 +010010003#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +010010004 int err;
Victor Stinner984890f2011-11-24 13:53:38 +010010005#endif
Victor Stinner84ae1182010-05-06 22:05:07 +000010006
Victor Stinner984890f2011-11-24 13:53:38 +010010007#ifdef HAVE_BROKEN_UNSETENV
10008 unsetenv(PyBytes_AS_STRING(name));
10009#else
Victor Stinner65170952011-11-22 22:16:17 +010010010 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +100010011 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +010010012 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +010010013#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010014
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 /* Remove the key from posix_putenv_garbage;
10016 * this will cause it to be collected. This has to
10017 * happen after the real unsetenv() call because the
10018 * old value was still accessible until then.
10019 */
Victor Stinner65170952011-11-22 22:16:17 +010010020 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 /* really not much we can do; just leak */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +020010022 if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
10023 return NULL;
10024 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 PyErr_Clear();
10026 }
Victor Stinner84ae1182010-05-06 22:05:07 +000010027 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010028}
Larry Hastings2f936352014-08-05 14:04:04 +100010029#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +000010030
Larry Hastings2f936352014-08-05 14:04:04 +100010031
10032/*[clinic input]
10033os.strerror
10034
10035 code: int
10036 /
10037
10038Translate an error code to a message string.
10039[clinic start generated code]*/
10040
Larry Hastings2f936352014-08-05 14:04:04 +100010041static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010042os_strerror_impl(PyObject *module, int code)
10043/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010044{
10045 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 if (message == NULL) {
10047 PyErr_SetString(PyExc_ValueError,
10048 "strerror() argument out of range");
10049 return NULL;
10050 }
Victor Stinner1b579672011-12-17 05:47:23 +010010051 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010052}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010053
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010054
Guido van Rossumc9641791998-08-04 15:26:23 +000010055#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010056#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010057/*[clinic input]
10058os.WCOREDUMP -> bool
10059
10060 status: int
10061 /
10062
10063Return True if the process returning status was dumped to a core file.
10064[clinic start generated code]*/
10065
Larry Hastings2f936352014-08-05 14:04:04 +100010066static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010067os_WCOREDUMP_impl(PyObject *module, int status)
10068/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010069{
10070 WAIT_TYPE wait_status;
10071 WAIT_STATUS_INT(wait_status) = status;
10072 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010073}
10074#endif /* WCOREDUMP */
10075
Larry Hastings2f936352014-08-05 14:04:04 +100010076
Fred Drake106c1a02002-04-23 15:58:02 +000010077#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010078/*[clinic input]
10079os.WIFCONTINUED -> bool
10080
10081 status: int
10082
10083Return True if a particular process was continued from a job control stop.
10084
10085Return True if the process returning status was continued from a
10086job control stop.
10087[clinic start generated code]*/
10088
Larry Hastings2f936352014-08-05 14:04:04 +100010089static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010090os_WIFCONTINUED_impl(PyObject *module, int status)
10091/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010092{
10093 WAIT_TYPE wait_status;
10094 WAIT_STATUS_INT(wait_status) = status;
10095 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010096}
10097#endif /* WIFCONTINUED */
10098
Larry Hastings2f936352014-08-05 14:04:04 +100010099
Guido van Rossumc9641791998-08-04 15:26:23 +000010100#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010101/*[clinic input]
10102os.WIFSTOPPED -> bool
10103
10104 status: int
10105
10106Return True if the process returning status was stopped.
10107[clinic start generated code]*/
10108
Larry Hastings2f936352014-08-05 14:04:04 +100010109static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010110os_WIFSTOPPED_impl(PyObject *module, int status)
10111/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010112{
10113 WAIT_TYPE wait_status;
10114 WAIT_STATUS_INT(wait_status) = status;
10115 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010116}
10117#endif /* WIFSTOPPED */
10118
Larry Hastings2f936352014-08-05 14:04:04 +100010119
Guido van Rossumc9641791998-08-04 15:26:23 +000010120#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010121/*[clinic input]
10122os.WIFSIGNALED -> bool
10123
10124 status: int
10125
10126Return True if the process returning status was terminated by a signal.
10127[clinic start generated code]*/
10128
Larry Hastings2f936352014-08-05 14:04:04 +100010129static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010130os_WIFSIGNALED_impl(PyObject *module, int status)
10131/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010132{
10133 WAIT_TYPE wait_status;
10134 WAIT_STATUS_INT(wait_status) = status;
10135 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010136}
10137#endif /* WIFSIGNALED */
10138
Larry Hastings2f936352014-08-05 14:04:04 +100010139
Guido van Rossumc9641791998-08-04 15:26:23 +000010140#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010141/*[clinic input]
10142os.WIFEXITED -> bool
10143
10144 status: int
10145
10146Return True if the process returning status exited via the exit() system call.
10147[clinic start generated code]*/
10148
Larry Hastings2f936352014-08-05 14:04:04 +100010149static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010150os_WIFEXITED_impl(PyObject *module, int status)
10151/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010152{
10153 WAIT_TYPE wait_status;
10154 WAIT_STATUS_INT(wait_status) = status;
10155 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010156}
10157#endif /* WIFEXITED */
10158
Larry Hastings2f936352014-08-05 14:04:04 +100010159
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010160#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010161/*[clinic input]
10162os.WEXITSTATUS -> int
10163
10164 status: int
10165
10166Return the process return code from status.
10167[clinic start generated code]*/
10168
Larry Hastings2f936352014-08-05 14:04:04 +100010169static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010170os_WEXITSTATUS_impl(PyObject *module, int status)
10171/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010172{
10173 WAIT_TYPE wait_status;
10174 WAIT_STATUS_INT(wait_status) = status;
10175 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010176}
10177#endif /* WEXITSTATUS */
10178
Larry Hastings2f936352014-08-05 14:04:04 +100010179
Guido van Rossumc9641791998-08-04 15:26:23 +000010180#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010181/*[clinic input]
10182os.WTERMSIG -> int
10183
10184 status: int
10185
10186Return the signal that terminated the process that provided the status value.
10187[clinic start generated code]*/
10188
Larry Hastings2f936352014-08-05 14:04:04 +100010189static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010190os_WTERMSIG_impl(PyObject *module, int status)
10191/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010192{
10193 WAIT_TYPE wait_status;
10194 WAIT_STATUS_INT(wait_status) = status;
10195 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010196}
10197#endif /* WTERMSIG */
10198
Larry Hastings2f936352014-08-05 14:04:04 +100010199
Guido van Rossumc9641791998-08-04 15:26:23 +000010200#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010201/*[clinic input]
10202os.WSTOPSIG -> int
10203
10204 status: int
10205
10206Return the signal that stopped the process that provided the status value.
10207[clinic start generated code]*/
10208
Larry Hastings2f936352014-08-05 14:04:04 +100010209static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010210os_WSTOPSIG_impl(PyObject *module, int status)
10211/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010212{
10213 WAIT_TYPE wait_status;
10214 WAIT_STATUS_INT(wait_status) = status;
10215 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010216}
10217#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010218#endif /* HAVE_SYS_WAIT_H */
10219
10220
Thomas Wouters477c8d52006-05-27 19:21:47 +000010221#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010222#ifdef _SCO_DS
10223/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10224 needed definitions in sys/statvfs.h */
10225#define _SVID3
10226#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010227#include <sys/statvfs.h>
10228
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010229static PyObject*
10230_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -080010231 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 if (v == NULL)
10233 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010234
10235#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10237 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10238 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10239 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10240 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10241 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10242 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10243 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10244 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10245 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010246#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10248 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10249 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010250 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010252 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010254 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010256 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010258 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010260 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10262 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010263#endif
Michael Felt502d5512018-01-05 13:01:58 +010010264/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10265 * (issue #32390). */
10266#if defined(_AIX) && defined(_ALL_SOURCE)
10267 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10268#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010269 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010270#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010271 if (PyErr_Occurred()) {
10272 Py_DECREF(v);
10273 return NULL;
10274 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010275
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010277}
10278
Larry Hastings2f936352014-08-05 14:04:04 +100010279
10280/*[clinic input]
10281os.fstatvfs
10282 fd: int
10283 /
10284
10285Perform an fstatvfs system call on the given fd.
10286
10287Equivalent to statvfs(fd).
10288[clinic start generated code]*/
10289
Larry Hastings2f936352014-08-05 14:04:04 +100010290static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010291os_fstatvfs_impl(PyObject *module, int fd)
10292/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010293{
10294 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010295 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010297
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010298 do {
10299 Py_BEGIN_ALLOW_THREADS
10300 result = fstatvfs(fd, &st);
10301 Py_END_ALLOW_THREADS
10302 } while (result != 0 && errno == EINTR &&
10303 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010304 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010305 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010306
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010308}
Larry Hastings2f936352014-08-05 14:04:04 +100010309#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010310
10311
Thomas Wouters477c8d52006-05-27 19:21:47 +000010312#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010313#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010314/*[clinic input]
10315os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010316
Larry Hastings2f936352014-08-05 14:04:04 +100010317 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10318
10319Perform a statvfs system call on the given path.
10320
10321path may always be specified as a string.
10322On some platforms, path may also be specified as an open file descriptor.
10323 If this functionality is unavailable, using it raises an exception.
10324[clinic start generated code]*/
10325
Larry Hastings2f936352014-08-05 14:04:04 +100010326static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010327os_statvfs_impl(PyObject *module, path_t *path)
10328/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010329{
10330 int result;
10331 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010332
10333 Py_BEGIN_ALLOW_THREADS
10334#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010335 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010336#ifdef __APPLE__
10337 /* handle weak-linking on Mac OS X 10.3 */
10338 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010339 fd_specified("statvfs", path->fd);
10340 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010341 }
10342#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010343 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010344 }
10345 else
10346#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010347 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010348 Py_END_ALLOW_THREADS
10349
10350 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010351 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010352 }
10353
Larry Hastings2f936352014-08-05 14:04:04 +100010354 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010355}
Larry Hastings2f936352014-08-05 14:04:04 +100010356#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10357
Guido van Rossum94f6f721999-01-06 18:42:14 +000010358
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010359#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010360/*[clinic input]
10361os._getdiskusage
10362
Steve Dower23ad6d02018-02-22 10:39:10 -080010363 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010364
10365Return disk usage statistics about the given path as a (total, free) tuple.
10366[clinic start generated code]*/
10367
Larry Hastings2f936352014-08-05 14:04:04 +100010368static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010369os__getdiskusage_impl(PyObject *module, path_t *path)
10370/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010371{
10372 BOOL retval;
10373 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010374 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010375
10376 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010377 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010378 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010379 if (retval == 0) {
10380 if (GetLastError() == ERROR_DIRECTORY) {
10381 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010382
Joe Pamerc8c02492018-09-25 10:57:36 -040010383 dir_path = PyMem_New(wchar_t, path->length + 1);
10384 if (dir_path == NULL) {
10385 return PyErr_NoMemory();
10386 }
10387
10388 wcscpy_s(dir_path, path->length + 1, path->wide);
10389
10390 if (_dirnameW(dir_path) != -1) {
10391 Py_BEGIN_ALLOW_THREADS
10392 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10393 Py_END_ALLOW_THREADS
10394 }
10395 /* Record the last error in case it's modified by PyMem_Free. */
10396 err = GetLastError();
10397 PyMem_Free(dir_path);
10398 if (retval) {
10399 goto success;
10400 }
10401 }
10402 return PyErr_SetFromWindowsErr(err);
10403 }
10404
10405success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010406 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10407}
Larry Hastings2f936352014-08-05 14:04:04 +100010408#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010409
10410
Fred Drakec9680921999-12-13 16:37:25 +000010411/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10412 * It maps strings representing configuration variable names to
10413 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010414 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010415 * rarely-used constants. There are three separate tables that use
10416 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010417 *
10418 * This code is always included, even if none of the interfaces that
10419 * need it are included. The #if hackery needed to avoid it would be
10420 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010421 */
10422struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010423 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010424 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010425};
10426
Fred Drake12c6e2d1999-12-14 21:25:03 +000010427static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010428conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010429 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010430{
Christian Heimes217cfd12007-12-02 14:31:20 +000010431 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010432 int value = _PyLong_AsInt(arg);
10433 if (value == -1 && PyErr_Occurred())
10434 return 0;
10435 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010436 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010437 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010438 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010439 /* look up the value in the table using a binary search */
10440 size_t lo = 0;
10441 size_t mid;
10442 size_t hi = tablesize;
10443 int cmp;
10444 const char *confname;
10445 if (!PyUnicode_Check(arg)) {
10446 PyErr_SetString(PyExc_TypeError,
10447 "configuration names must be strings or integers");
10448 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010450 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010451 if (confname == NULL)
10452 return 0;
10453 while (lo < hi) {
10454 mid = (lo + hi) / 2;
10455 cmp = strcmp(confname, table[mid].name);
10456 if (cmp < 0)
10457 hi = mid;
10458 else if (cmp > 0)
10459 lo = mid + 1;
10460 else {
10461 *valuep = table[mid].value;
10462 return 1;
10463 }
10464 }
10465 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10466 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010468}
10469
10470
10471#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10472static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010473#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010474 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010475#endif
10476#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010477 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010478#endif
Fred Drakec9680921999-12-13 16:37:25 +000010479#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010480 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010481#endif
10482#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010483 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010484#endif
10485#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010487#endif
10488#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010489 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010490#endif
10491#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010492 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010493#endif
10494#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010495 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010496#endif
10497#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010498 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010499#endif
10500#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010501 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010502#endif
10503#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010504 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010505#endif
10506#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010507 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010508#endif
10509#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010510 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010511#endif
10512#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010513 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010514#endif
10515#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010516 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010517#endif
10518#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010519 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010520#endif
10521#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010523#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010524#ifdef _PC_ACL_ENABLED
10525 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10526#endif
10527#ifdef _PC_MIN_HOLE_SIZE
10528 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10529#endif
10530#ifdef _PC_ALLOC_SIZE_MIN
10531 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10532#endif
10533#ifdef _PC_REC_INCR_XFER_SIZE
10534 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10535#endif
10536#ifdef _PC_REC_MAX_XFER_SIZE
10537 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10538#endif
10539#ifdef _PC_REC_MIN_XFER_SIZE
10540 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10541#endif
10542#ifdef _PC_REC_XFER_ALIGN
10543 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10544#endif
10545#ifdef _PC_SYMLINK_MAX
10546 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10547#endif
10548#ifdef _PC_XATTR_ENABLED
10549 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10550#endif
10551#ifdef _PC_XATTR_EXISTS
10552 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10553#endif
10554#ifdef _PC_TIMESTAMP_RESOLUTION
10555 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10556#endif
Fred Drakec9680921999-12-13 16:37:25 +000010557};
10558
Fred Drakec9680921999-12-13 16:37:25 +000010559static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010560conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010561{
10562 return conv_confname(arg, valuep, posix_constants_pathconf,
10563 sizeof(posix_constants_pathconf)
10564 / sizeof(struct constdef));
10565}
10566#endif
10567
Larry Hastings2f936352014-08-05 14:04:04 +100010568
Fred Drakec9680921999-12-13 16:37:25 +000010569#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010570/*[clinic input]
10571os.fpathconf -> long
10572
10573 fd: int
10574 name: path_confname
10575 /
10576
10577Return the configuration limit name for the file descriptor fd.
10578
10579If there is no limit, return -1.
10580[clinic start generated code]*/
10581
Larry Hastings2f936352014-08-05 14:04:04 +100010582static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010583os_fpathconf_impl(PyObject *module, int fd, int name)
10584/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010585{
10586 long limit;
10587
10588 errno = 0;
10589 limit = fpathconf(fd, name);
10590 if (limit == -1 && errno != 0)
10591 posix_error();
10592
10593 return limit;
10594}
10595#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010596
10597
10598#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010599/*[clinic input]
10600os.pathconf -> long
10601 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10602 name: path_confname
10603
10604Return the configuration limit name for the file or directory path.
10605
10606If there is no limit, return -1.
10607On some platforms, path may also be specified as an open file descriptor.
10608 If this functionality is unavailable, using it raises an exception.
10609[clinic start generated code]*/
10610
Larry Hastings2f936352014-08-05 14:04:04 +100010611static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010612os_pathconf_impl(PyObject *module, path_t *path, int name)
10613/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010614{
Victor Stinner8c62be82010-05-06 00:08:46 +000010615 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010616
Victor Stinner8c62be82010-05-06 00:08:46 +000010617 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010618#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010619 if (path->fd != -1)
10620 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010621 else
10622#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010623 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010624 if (limit == -1 && errno != 0) {
10625 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010626 /* could be a path or name problem */
10627 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010628 else
Larry Hastings2f936352014-08-05 14:04:04 +100010629 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010630 }
Larry Hastings2f936352014-08-05 14:04:04 +100010631
10632 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010633}
Larry Hastings2f936352014-08-05 14:04:04 +100010634#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010635
10636#ifdef HAVE_CONFSTR
10637static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010638#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010639 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010640#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010641#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010642 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010643#endif
10644#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010645 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010646#endif
Fred Draked86ed291999-12-15 15:34:33 +000010647#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010649#endif
10650#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010651 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010652#endif
10653#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010655#endif
10656#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010657 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010658#endif
Fred Drakec9680921999-12-13 16:37:25 +000010659#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010660 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010661#endif
10662#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010664#endif
10665#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010667#endif
10668#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010670#endif
10671#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010673#endif
10674#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010676#endif
10677#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010679#endif
10680#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010682#endif
Fred Draked86ed291999-12-15 15:34:33 +000010683#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010685#endif
Fred Drakec9680921999-12-13 16:37:25 +000010686#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010688#endif
Fred Draked86ed291999-12-15 15:34:33 +000010689#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010691#endif
10692#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010694#endif
10695#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010697#endif
10698#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010700#endif
Fred Drakec9680921999-12-13 16:37:25 +000010701#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010703#endif
10704#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010706#endif
10707#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010709#endif
10710#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010712#endif
10713#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010715#endif
10716#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010718#endif
10719#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010721#endif
10722#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010724#endif
10725#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010727#endif
10728#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010730#endif
10731#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010732 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010733#endif
10734#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010736#endif
10737#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010739#endif
10740#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010741 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010742#endif
10743#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010745#endif
10746#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010748#endif
Fred Draked86ed291999-12-15 15:34:33 +000010749#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010750 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010751#endif
10752#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010753 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010754#endif
10755#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010756 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010757#endif
10758#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010759 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010760#endif
10761#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010762 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010763#endif
10764#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010766#endif
10767#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010768 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010769#endif
10770#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010771 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010772#endif
10773#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010774 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010775#endif
10776#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010777 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010778#endif
10779#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010780 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010781#endif
10782#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010783 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010784#endif
10785#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010786 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010787#endif
Fred Drakec9680921999-12-13 16:37:25 +000010788};
10789
10790static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010791conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010792{
10793 return conv_confname(arg, valuep, posix_constants_confstr,
10794 sizeof(posix_constants_confstr)
10795 / sizeof(struct constdef));
10796}
10797
Larry Hastings2f936352014-08-05 14:04:04 +100010798
10799/*[clinic input]
10800os.confstr
10801
10802 name: confstr_confname
10803 /
10804
10805Return a string-valued system configuration variable.
10806[clinic start generated code]*/
10807
Larry Hastings2f936352014-08-05 14:04:04 +100010808static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010809os_confstr_impl(PyObject *module, int name)
10810/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010811{
10812 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010813 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010814 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010815
Victor Stinnercb043522010-09-10 23:49:04 +000010816 errno = 0;
10817 len = confstr(name, buffer, sizeof(buffer));
10818 if (len == 0) {
10819 if (errno) {
10820 posix_error();
10821 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010822 }
10823 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010824 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010825 }
10826 }
Victor Stinnercb043522010-09-10 23:49:04 +000010827
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010828 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010829 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010830 char *buf = PyMem_Malloc(len);
10831 if (buf == NULL)
10832 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010833 len2 = confstr(name, buf, len);
10834 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010835 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010836 PyMem_Free(buf);
10837 }
10838 else
10839 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010840 return result;
10841}
Larry Hastings2f936352014-08-05 14:04:04 +100010842#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010843
10844
10845#ifdef HAVE_SYSCONF
10846static struct constdef posix_constants_sysconf[] = {
10847#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010848 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010849#endif
10850#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010851 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010852#endif
10853#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010855#endif
10856#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010857 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010858#endif
10859#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010860 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010861#endif
10862#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010863 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010864#endif
10865#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010866 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010867#endif
10868#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010869 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010870#endif
10871#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010873#endif
10874#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010875 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010876#endif
Fred Draked86ed291999-12-15 15:34:33 +000010877#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010878 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010879#endif
10880#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010881 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010882#endif
Fred Drakec9680921999-12-13 16:37:25 +000010883#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010884 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010885#endif
Fred Drakec9680921999-12-13 16:37:25 +000010886#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010887 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010888#endif
10889#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010890 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010891#endif
10892#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010893 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010894#endif
10895#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010896 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010897#endif
10898#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010899 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010900#endif
Fred Draked86ed291999-12-15 15:34:33 +000010901#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010902 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010903#endif
Fred Drakec9680921999-12-13 16:37:25 +000010904#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010906#endif
10907#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010908 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010909#endif
10910#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010911 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010912#endif
10913#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010914 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010915#endif
10916#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010917 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010918#endif
Fred Draked86ed291999-12-15 15:34:33 +000010919#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010920 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010921#endif
Fred Drakec9680921999-12-13 16:37:25 +000010922#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010923 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010924#endif
10925#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010926 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010927#endif
10928#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010929 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010930#endif
10931#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010932 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010933#endif
10934#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010936#endif
10937#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010939#endif
10940#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010942#endif
10943#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010945#endif
10946#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010947 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010948#endif
10949#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010950 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010951#endif
10952#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010953 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010954#endif
10955#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010957#endif
10958#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010960#endif
10961#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010962 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010963#endif
10964#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010965 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010966#endif
10967#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010968 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010969#endif
10970#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010972#endif
10973#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010975#endif
10976#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010977 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010978#endif
10979#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010981#endif
10982#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010984#endif
10985#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010986 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010987#endif
10988#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010989 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010990#endif
Fred Draked86ed291999-12-15 15:34:33 +000010991#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010992 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010993#endif
Fred Drakec9680921999-12-13 16:37:25 +000010994#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010996#endif
10997#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010998 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010999#endif
11000#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011001 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011002#endif
Fred Draked86ed291999-12-15 15:34:33 +000011003#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011005#endif
Fred Drakec9680921999-12-13 16:37:25 +000011006#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011007 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011008#endif
Fred Draked86ed291999-12-15 15:34:33 +000011009#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011011#endif
11012#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011013 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011014#endif
Fred Drakec9680921999-12-13 16:37:25 +000011015#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011016 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011017#endif
11018#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011019 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011020#endif
11021#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011023#endif
11024#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011025 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011026#endif
Fred Draked86ed291999-12-15 15:34:33 +000011027#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011028 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011029#endif
Fred Drakec9680921999-12-13 16:37:25 +000011030#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011031 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011032#endif
11033#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011034 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011035#endif
11036#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011037 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011038#endif
11039#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011040 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011041#endif
11042#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011043 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011044#endif
11045#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011046 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011047#endif
11048#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011049 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011050#endif
Fred Draked86ed291999-12-15 15:34:33 +000011051#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011052 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011053#endif
Fred Drakec9680921999-12-13 16:37:25 +000011054#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011055 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011056#endif
11057#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011058 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011059#endif
Fred Draked86ed291999-12-15 15:34:33 +000011060#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011061 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011062#endif
Fred Drakec9680921999-12-13 16:37:25 +000011063#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011065#endif
11066#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011068#endif
11069#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011070 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011071#endif
11072#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011073 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011074#endif
11075#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011076 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011077#endif
11078#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011079 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011080#endif
11081#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011082 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011083#endif
11084#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011086#endif
11087#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011088 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011089#endif
Fred Draked86ed291999-12-15 15:34:33 +000011090#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011091 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011092#endif
11093#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011094 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011095#endif
Fred Drakec9680921999-12-13 16:37:25 +000011096#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011097 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011098#endif
11099#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011100 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011101#endif
11102#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011103 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011104#endif
11105#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011106 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011107#endif
11108#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011110#endif
11111#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011112 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011113#endif
11114#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011115 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011116#endif
11117#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011118 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011119#endif
11120#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011121 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011122#endif
11123#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011124 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011125#endif
11126#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011127 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011128#endif
11129#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011130 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011131#endif
11132#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011133 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011134#endif
11135#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011136 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011137#endif
11138#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011139 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011140#endif
11141#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011142 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011143#endif
11144#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011145 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011146#endif
11147#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011149#endif
11150#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011151 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011152#endif
11153#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011155#endif
11156#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011158#endif
11159#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011161#endif
11162#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011164#endif
11165#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011167#endif
11168#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011170#endif
11171#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011173#endif
11174#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011175 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011176#endif
11177#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011178 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011179#endif
11180#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011181 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011182#endif
11183#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011184 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011185#endif
11186#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011187 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011188#endif
11189#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011190 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011191#endif
11192#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011193 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011194#endif
11195#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011196 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011197#endif
11198#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011199 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011200#endif
Fred Draked86ed291999-12-15 15:34:33 +000011201#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011202 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011203#endif
Fred Drakec9680921999-12-13 16:37:25 +000011204#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011205 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011206#endif
11207#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011208 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011209#endif
11210#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011211 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011212#endif
11213#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011215#endif
11216#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011218#endif
11219#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011221#endif
11222#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011223 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011224#endif
11225#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011227#endif
11228#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011230#endif
11231#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011233#endif
11234#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011235 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011236#endif
11237#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011239#endif
11240#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011242#endif
11243#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011245#endif
11246#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011248#endif
11249#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011250 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011251#endif
11252#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011254#endif
11255#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011257#endif
11258#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011260#endif
11261#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011263#endif
11264#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011266#endif
11267#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011268 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011269#endif
11270#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011272#endif
11273#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011274 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011275#endif
11276#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011278#endif
11279#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011281#endif
11282#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011284#endif
11285#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011287#endif
11288#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011290#endif
11291#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011293#endif
11294#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011295 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011296#endif
11297#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011299#endif
11300#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011302#endif
11303#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011305#endif
11306#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011308#endif
11309#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011311#endif
11312#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011314#endif
11315#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011317#endif
11318#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011320#endif
11321#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011323#endif
11324#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011326#endif
11327#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011328 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011329#endif
11330#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011331 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011332#endif
11333#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011334 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011335#endif
11336#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011338#endif
11339};
11340
11341static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011342conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011343{
11344 return conv_confname(arg, valuep, posix_constants_sysconf,
11345 sizeof(posix_constants_sysconf)
11346 / sizeof(struct constdef));
11347}
11348
Larry Hastings2f936352014-08-05 14:04:04 +100011349
11350/*[clinic input]
11351os.sysconf -> long
11352 name: sysconf_confname
11353 /
11354
11355Return an integer-valued system configuration variable.
11356[clinic start generated code]*/
11357
Larry Hastings2f936352014-08-05 14:04:04 +100011358static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011359os_sysconf_impl(PyObject *module, int name)
11360/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011361{
11362 long value;
11363
11364 errno = 0;
11365 value = sysconf(name);
11366 if (value == -1 && errno != 0)
11367 posix_error();
11368 return value;
11369}
11370#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011371
11372
Fred Drakebec628d1999-12-15 18:31:10 +000011373/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011374 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011375 * the exported dictionaries that are used to publish information about the
11376 * names available on the host platform.
11377 *
11378 * Sorting the table at runtime ensures that the table is properly ordered
11379 * when used, even for platforms we're not able to test on. It also makes
11380 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011381 */
Fred Drakebec628d1999-12-15 18:31:10 +000011382
11383static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011384cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011385{
11386 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011388 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011389 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011390
11391 return strcmp(c1->name, c2->name);
11392}
11393
11394static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011395setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011396 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011397{
Fred Drakebec628d1999-12-15 18:31:10 +000011398 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011399 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011400
11401 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11402 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011403 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011404 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011405
Barry Warsaw3155db32000-04-13 15:20:40 +000011406 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011407 PyObject *o = PyLong_FromLong(table[i].value);
11408 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11409 Py_XDECREF(o);
11410 Py_DECREF(d);
11411 return -1;
11412 }
11413 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011414 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011415 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011416}
11417
Fred Drakebec628d1999-12-15 18:31:10 +000011418/* Return -1 on failure, 0 on success. */
11419static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011420setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011421{
11422#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011423 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011424 sizeof(posix_constants_pathconf)
11425 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011426 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011427 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011428#endif
11429#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011430 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011431 sizeof(posix_constants_confstr)
11432 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011433 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011434 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011435#endif
11436#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011437 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011438 sizeof(posix_constants_sysconf)
11439 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011440 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011441 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011442#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011443 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011444}
Fred Draked86ed291999-12-15 15:34:33 +000011445
11446
Larry Hastings2f936352014-08-05 14:04:04 +100011447/*[clinic input]
11448os.abort
11449
11450Abort the interpreter immediately.
11451
11452This function 'dumps core' or otherwise fails in the hardest way possible
11453on the hosting operating system. This function never returns.
11454[clinic start generated code]*/
11455
Larry Hastings2f936352014-08-05 14:04:04 +100011456static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011457os_abort_impl(PyObject *module)
11458/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011459{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011460 abort();
11461 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011462#ifndef __clang__
11463 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11464 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11465 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011466 Py_FatalError("abort() called from Python code didn't abort!");
11467 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011468#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011469}
Fred Drakebec628d1999-12-15 18:31:10 +000011470
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011471#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011472/* Grab ShellExecute dynamically from shell32 */
11473static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011474static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11475 LPCWSTR, INT);
11476static int
11477check_ShellExecute()
11478{
11479 HINSTANCE hShell32;
11480
11481 /* only recheck */
11482 if (-1 == has_ShellExecute) {
11483 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011484 /* Security note: this call is not vulnerable to "DLL hijacking".
11485 SHELL32 is part of "KnownDLLs" and so Windows always load
11486 the system SHELL32.DLL, even if there is another SHELL32.DLL
11487 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011488 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011489 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011490 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11491 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011492 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011493 } else {
11494 has_ShellExecute = 0;
11495 }
Tony Roberts4860f012019-02-02 18:16:42 +010011496 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011497 }
11498 return has_ShellExecute;
11499}
11500
11501
Steve Dowercc16be82016-09-08 10:35:16 -070011502/*[clinic input]
11503os.startfile
11504 filepath: path_t
11505 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011506
Steve Dowercc16be82016-09-08 10:35:16 -070011507startfile(filepath [, operation])
11508
11509Start a file with its associated application.
11510
11511When "operation" is not specified or "open", this acts like
11512double-clicking the file in Explorer, or giving the file name as an
11513argument to the DOS "start" command: the file is opened with whatever
11514application (if any) its extension is associated.
11515When another "operation" is given, it specifies what should be done with
11516the file. A typical operation is "print".
11517
11518startfile returns as soon as the associated application is launched.
11519There is no option to wait for the application to close, and no way
11520to retrieve the application's exit status.
11521
11522The filepath is relative to the current directory. If you want to use
11523an absolute path, make sure the first character is not a slash ("/");
11524the underlying Win32 ShellExecute function doesn't work if it is.
11525[clinic start generated code]*/
11526
11527static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011528os_startfile_impl(PyObject *module, path_t *filepath,
11529 const Py_UNICODE *operation)
11530/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011531{
11532 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011533
11534 if(!check_ShellExecute()) {
11535 /* If the OS doesn't have ShellExecute, return a
11536 NotImplementedError. */
11537 return PyErr_Format(PyExc_NotImplementedError,
11538 "startfile not available on this platform");
11539 }
11540
Victor Stinner8c62be82010-05-06 00:08:46 +000011541 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011542 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011543 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011544 Py_END_ALLOW_THREADS
11545
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011547 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011548 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011549 }
Steve Dowercc16be82016-09-08 10:35:16 -070011550 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011551}
Larry Hastings2f936352014-08-05 14:04:04 +100011552#endif /* MS_WINDOWS */
11553
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011554
Martin v. Löwis438b5342002-12-27 10:16:42 +000011555#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011556/*[clinic input]
11557os.getloadavg
11558
11559Return average recent system load information.
11560
11561Return the number of processes in the system run queue averaged over
11562the last 1, 5, and 15 minutes as a tuple of three floats.
11563Raises OSError if the load average was unobtainable.
11564[clinic start generated code]*/
11565
Larry Hastings2f936352014-08-05 14:04:04 +100011566static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011567os_getloadavg_impl(PyObject *module)
11568/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011569{
11570 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011571 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011572 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11573 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011574 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011575 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011576}
Larry Hastings2f936352014-08-05 14:04:04 +100011577#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011578
Larry Hastings2f936352014-08-05 14:04:04 +100011579
11580/*[clinic input]
11581os.device_encoding
11582 fd: int
11583
11584Return a string describing the encoding of a terminal's file descriptor.
11585
11586The file descriptor must be attached to a terminal.
11587If the device is not a terminal, return None.
11588[clinic start generated code]*/
11589
Larry Hastings2f936352014-08-05 14:04:04 +100011590static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011591os_device_encoding_impl(PyObject *module, int fd)
11592/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011593{
Brett Cannonefb00c02012-02-29 18:31:31 -050011594 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011595}
11596
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011597
Larry Hastings2f936352014-08-05 14:04:04 +100011598#ifdef HAVE_SETRESUID
11599/*[clinic input]
11600os.setresuid
11601
11602 ruid: uid_t
11603 euid: uid_t
11604 suid: uid_t
11605 /
11606
11607Set the current process's real, effective, and saved user ids.
11608[clinic start generated code]*/
11609
Larry Hastings2f936352014-08-05 14:04:04 +100011610static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011611os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11612/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011613{
Victor Stinner8c62be82010-05-06 00:08:46 +000011614 if (setresuid(ruid, euid, suid) < 0)
11615 return posix_error();
11616 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011617}
Larry Hastings2f936352014-08-05 14:04:04 +100011618#endif /* HAVE_SETRESUID */
11619
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011620
11621#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011622/*[clinic input]
11623os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011624
Larry Hastings2f936352014-08-05 14:04:04 +100011625 rgid: gid_t
11626 egid: gid_t
11627 sgid: gid_t
11628 /
11629
11630Set the current process's real, effective, and saved group ids.
11631[clinic start generated code]*/
11632
Larry Hastings2f936352014-08-05 14:04:04 +100011633static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011634os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11635/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011636{
Victor Stinner8c62be82010-05-06 00:08:46 +000011637 if (setresgid(rgid, egid, sgid) < 0)
11638 return posix_error();
11639 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011640}
Larry Hastings2f936352014-08-05 14:04:04 +100011641#endif /* HAVE_SETRESGID */
11642
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011643
11644#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011645/*[clinic input]
11646os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011647
Larry Hastings2f936352014-08-05 14:04:04 +100011648Return a tuple of the current process's real, effective, and saved user ids.
11649[clinic start generated code]*/
11650
Larry Hastings2f936352014-08-05 14:04:04 +100011651static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011652os_getresuid_impl(PyObject *module)
11653/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011654{
Victor Stinner8c62be82010-05-06 00:08:46 +000011655 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011656 if (getresuid(&ruid, &euid, &suid) < 0)
11657 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011658 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11659 _PyLong_FromUid(euid),
11660 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011661}
Larry Hastings2f936352014-08-05 14:04:04 +100011662#endif /* HAVE_GETRESUID */
11663
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011664
11665#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011666/*[clinic input]
11667os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011668
Larry Hastings2f936352014-08-05 14:04:04 +100011669Return a tuple of the current process's real, effective, and saved group ids.
11670[clinic start generated code]*/
11671
Larry Hastings2f936352014-08-05 14:04:04 +100011672static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011673os_getresgid_impl(PyObject *module)
11674/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011675{
11676 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011677 if (getresgid(&rgid, &egid, &sgid) < 0)
11678 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011679 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11680 _PyLong_FromGid(egid),
11681 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011682}
Larry Hastings2f936352014-08-05 14:04:04 +100011683#endif /* HAVE_GETRESGID */
11684
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011685
Benjamin Peterson9428d532011-09-14 11:45:52 -040011686#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011687/*[clinic input]
11688os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011689
Larry Hastings2f936352014-08-05 14:04:04 +100011690 path: path_t(allow_fd=True)
11691 attribute: path_t
11692 *
11693 follow_symlinks: bool = True
11694
11695Return the value of extended attribute attribute on path.
11696
BNMetricsb9427072018-11-02 15:20:19 +000011697path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011698If follow_symlinks is False, and the last element of the path is a symbolic
11699 link, getxattr will examine the symbolic link itself instead of the file
11700 the link points to.
11701
11702[clinic start generated code]*/
11703
Larry Hastings2f936352014-08-05 14:04:04 +100011704static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011705os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011706 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011707/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011708{
11709 Py_ssize_t i;
11710 PyObject *buffer = NULL;
11711
11712 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11713 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011714
Larry Hastings9cf065c2012-06-22 16:30:09 -070011715 for (i = 0; ; i++) {
11716 void *ptr;
11717 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011718 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011719 Py_ssize_t buffer_size = buffer_sizes[i];
11720 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011721 path_error(path);
11722 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011723 }
11724 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11725 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011726 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011727 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011728
Larry Hastings9cf065c2012-06-22 16:30:09 -070011729 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011730 if (path->fd >= 0)
11731 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011732 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011733 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011734 else
Larry Hastings2f936352014-08-05 14:04:04 +100011735 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011736 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011737
Larry Hastings9cf065c2012-06-22 16:30:09 -070011738 if (result < 0) {
11739 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011740 if (errno == ERANGE)
11741 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011742 path_error(path);
11743 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011744 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011745
Larry Hastings9cf065c2012-06-22 16:30:09 -070011746 if (result != buffer_size) {
11747 /* Can only shrink. */
11748 _PyBytes_Resize(&buffer, result);
11749 }
11750 break;
11751 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011752
Larry Hastings9cf065c2012-06-22 16:30:09 -070011753 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011754}
11755
Larry Hastings2f936352014-08-05 14:04:04 +100011756
11757/*[clinic input]
11758os.setxattr
11759
11760 path: path_t(allow_fd=True)
11761 attribute: path_t
11762 value: Py_buffer
11763 flags: int = 0
11764 *
11765 follow_symlinks: bool = True
11766
11767Set extended attribute attribute on path to value.
11768
BNMetricsb9427072018-11-02 15:20:19 +000011769path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011770If follow_symlinks is False, and the last element of the path is a symbolic
11771 link, setxattr will modify the symbolic link itself instead of the file
11772 the link points to.
11773
11774[clinic start generated code]*/
11775
Benjamin Peterson799bd802011-08-31 22:15:17 -040011776static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011777os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011778 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011779/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011780{
Larry Hastings2f936352014-08-05 14:04:04 +100011781 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011782
Larry Hastings2f936352014-08-05 14:04:04 +100011783 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011784 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011785
Benjamin Peterson799bd802011-08-31 22:15:17 -040011786 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011787 if (path->fd > -1)
11788 result = fsetxattr(path->fd, attribute->narrow,
11789 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011790 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011791 result = setxattr(path->narrow, attribute->narrow,
11792 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011793 else
Larry Hastings2f936352014-08-05 14:04:04 +100011794 result = lsetxattr(path->narrow, attribute->narrow,
11795 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011796 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011797
Larry Hastings9cf065c2012-06-22 16:30:09 -070011798 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011799 path_error(path);
11800 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011801 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011802
Larry Hastings2f936352014-08-05 14:04:04 +100011803 Py_RETURN_NONE;
11804}
11805
11806
11807/*[clinic input]
11808os.removexattr
11809
11810 path: path_t(allow_fd=True)
11811 attribute: path_t
11812 *
11813 follow_symlinks: bool = True
11814
11815Remove extended attribute attribute on path.
11816
BNMetricsb9427072018-11-02 15:20:19 +000011817path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011818If follow_symlinks is False, and the last element of the path is a symbolic
11819 link, removexattr will modify the symbolic link itself instead of the file
11820 the link points to.
11821
11822[clinic start generated code]*/
11823
Larry Hastings2f936352014-08-05 14:04:04 +100011824static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011825os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011826 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011827/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011828{
11829 ssize_t result;
11830
11831 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11832 return NULL;
11833
11834 Py_BEGIN_ALLOW_THREADS;
11835 if (path->fd > -1)
11836 result = fremovexattr(path->fd, attribute->narrow);
11837 else if (follow_symlinks)
11838 result = removexattr(path->narrow, attribute->narrow);
11839 else
11840 result = lremovexattr(path->narrow, attribute->narrow);
11841 Py_END_ALLOW_THREADS;
11842
11843 if (result) {
11844 return path_error(path);
11845 }
11846
11847 Py_RETURN_NONE;
11848}
11849
11850
11851/*[clinic input]
11852os.listxattr
11853
11854 path: path_t(allow_fd=True, nullable=True) = None
11855 *
11856 follow_symlinks: bool = True
11857
11858Return a list of extended attributes on path.
11859
BNMetricsb9427072018-11-02 15:20:19 +000011860path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011861if path is None, listxattr will examine the current directory.
11862If follow_symlinks is False, and the last element of the path is a symbolic
11863 link, listxattr will examine the symbolic link itself instead of the file
11864 the link points to.
11865[clinic start generated code]*/
11866
Larry Hastings2f936352014-08-05 14:04:04 +100011867static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011868os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011869/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011870{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011871 Py_ssize_t i;
11872 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011873 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011874 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011875
Larry Hastings2f936352014-08-05 14:04:04 +100011876 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011877 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011878
Larry Hastings2f936352014-08-05 14:04:04 +100011879 name = path->narrow ? path->narrow : ".";
11880
Larry Hastings9cf065c2012-06-22 16:30:09 -070011881 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011882 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011883 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011884 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011885 Py_ssize_t buffer_size = buffer_sizes[i];
11886 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011887 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011888 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011889 break;
11890 }
11891 buffer = PyMem_MALLOC(buffer_size);
11892 if (!buffer) {
11893 PyErr_NoMemory();
11894 break;
11895 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011896
Larry Hastings9cf065c2012-06-22 16:30:09 -070011897 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011898 if (path->fd > -1)
11899 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011900 else if (follow_symlinks)
11901 length = listxattr(name, buffer, buffer_size);
11902 else
11903 length = llistxattr(name, buffer, buffer_size);
11904 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011905
Larry Hastings9cf065c2012-06-22 16:30:09 -070011906 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011907 if (errno == ERANGE) {
11908 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011909 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011910 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011911 }
Larry Hastings2f936352014-08-05 14:04:04 +100011912 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011913 break;
11914 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011915
Larry Hastings9cf065c2012-06-22 16:30:09 -070011916 result = PyList_New(0);
11917 if (!result) {
11918 goto exit;
11919 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011920
Larry Hastings9cf065c2012-06-22 16:30:09 -070011921 end = buffer + length;
11922 for (trace = start = buffer; trace != end; trace++) {
11923 if (!*trace) {
11924 int error;
11925 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11926 trace - start);
11927 if (!attribute) {
11928 Py_DECREF(result);
11929 result = NULL;
11930 goto exit;
11931 }
11932 error = PyList_Append(result, attribute);
11933 Py_DECREF(attribute);
11934 if (error) {
11935 Py_DECREF(result);
11936 result = NULL;
11937 goto exit;
11938 }
11939 start = trace + 1;
11940 }
11941 }
11942 break;
11943 }
11944exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011945 if (buffer)
11946 PyMem_FREE(buffer);
11947 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011948}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011949#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011950
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011951
Larry Hastings2f936352014-08-05 14:04:04 +100011952/*[clinic input]
11953os.urandom
11954
11955 size: Py_ssize_t
11956 /
11957
11958Return a bytes object containing random bytes suitable for cryptographic use.
11959[clinic start generated code]*/
11960
Larry Hastings2f936352014-08-05 14:04:04 +100011961static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011962os_urandom_impl(PyObject *module, Py_ssize_t size)
11963/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011964{
11965 PyObject *bytes;
11966 int result;
11967
Georg Brandl2fb477c2012-02-21 00:33:36 +010011968 if (size < 0)
11969 return PyErr_Format(PyExc_ValueError,
11970 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011971 bytes = PyBytes_FromStringAndSize(NULL, size);
11972 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011973 return NULL;
11974
Victor Stinnere66987e2016-09-06 16:33:52 -070011975 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011976 if (result == -1) {
11977 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011978 return NULL;
11979 }
Larry Hastings2f936352014-08-05 14:04:04 +100011980 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011981}
11982
Zackery Spytz43fdbd22019-05-29 13:57:07 -060011983#ifdef HAVE_MEMFD_CREATE
11984/*[clinic input]
11985os.memfd_create
11986
11987 name: FSConverter
11988 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
11989
11990[clinic start generated code]*/
11991
11992static PyObject *
11993os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
11994/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
11995{
11996 int fd;
11997 const char *bytes = PyBytes_AS_STRING(name);
11998 Py_BEGIN_ALLOW_THREADS
11999 fd = memfd_create(bytes, flags);
12000 Py_END_ALLOW_THREADS
12001 if (fd == -1) {
12002 return PyErr_SetFromErrno(PyExc_OSError);
12003 }
12004 return PyLong_FromLong(fd);
12005}
12006#endif
12007
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012008/* Terminal size querying */
12009
Eddie Elizondo474eedf2018-11-13 04:09:31 -080012010static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012011
12012PyDoc_STRVAR(TerminalSize_docstring,
12013 "A tuple of (columns, lines) for holding terminal window size");
12014
12015static PyStructSequence_Field TerminalSize_fields[] = {
12016 {"columns", "width of the terminal window in characters"},
12017 {"lines", "height of the terminal window in characters"},
12018 {NULL, NULL}
12019};
12020
12021static PyStructSequence_Desc TerminalSize_desc = {
12022 "os.terminal_size",
12023 TerminalSize_docstring,
12024 TerminalSize_fields,
12025 2,
12026};
12027
12028#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100012029/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012030PyDoc_STRVAR(termsize__doc__,
12031 "Return the size of the terminal window as (columns, lines).\n" \
12032 "\n" \
12033 "The optional argument fd (default standard output) specifies\n" \
12034 "which file descriptor should be queried.\n" \
12035 "\n" \
12036 "If the file descriptor is not connected to a terminal, an OSError\n" \
12037 "is thrown.\n" \
12038 "\n" \
12039 "This function will only be defined if an implementation is\n" \
12040 "available for this system.\n" \
12041 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080012042 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012043 "normally be used, os.get_terminal_size is the low-level implementation.");
12044
12045static PyObject*
12046get_terminal_size(PyObject *self, PyObject *args)
12047{
12048 int columns, lines;
12049 PyObject *termsize;
12050
12051 int fd = fileno(stdout);
12052 /* Under some conditions stdout may not be connected and
12053 * fileno(stdout) may point to an invalid file descriptor. For example
12054 * GUI apps don't have valid standard streams by default.
12055 *
12056 * If this happens, and the optional fd argument is not present,
12057 * the ioctl below will fail returning EBADF. This is what we want.
12058 */
12059
12060 if (!PyArg_ParseTuple(args, "|i", &fd))
12061 return NULL;
12062
12063#ifdef TERMSIZE_USE_IOCTL
12064 {
12065 struct winsize w;
12066 if (ioctl(fd, TIOCGWINSZ, &w))
12067 return PyErr_SetFromErrno(PyExc_OSError);
12068 columns = w.ws_col;
12069 lines = w.ws_row;
12070 }
12071#endif /* TERMSIZE_USE_IOCTL */
12072
12073#ifdef TERMSIZE_USE_CONIO
12074 {
12075 DWORD nhandle;
12076 HANDLE handle;
12077 CONSOLE_SCREEN_BUFFER_INFO csbi;
12078 switch (fd) {
12079 case 0: nhandle = STD_INPUT_HANDLE;
12080 break;
12081 case 1: nhandle = STD_OUTPUT_HANDLE;
12082 break;
12083 case 2: nhandle = STD_ERROR_HANDLE;
12084 break;
12085 default:
12086 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12087 }
12088 handle = GetStdHandle(nhandle);
12089 if (handle == NULL)
12090 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12091 if (handle == INVALID_HANDLE_VALUE)
12092 return PyErr_SetFromWindowsErr(0);
12093
12094 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12095 return PyErr_SetFromWindowsErr(0);
12096
12097 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12098 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12099 }
12100#endif /* TERMSIZE_USE_CONIO */
12101
Eddie Elizondo474eedf2018-11-13 04:09:31 -080012102 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012103 if (termsize == NULL)
12104 return NULL;
12105 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12106 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12107 if (PyErr_Occurred()) {
12108 Py_DECREF(termsize);
12109 return NULL;
12110 }
12111 return termsize;
12112}
12113#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12114
Larry Hastings2f936352014-08-05 14:04:04 +100012115
12116/*[clinic input]
12117os.cpu_count
12118
Charles-François Natali80d62e62015-08-13 20:37:08 +010012119Return the number of CPUs in the system; return None if indeterminable.
12120
12121This number is not equivalent to the number of CPUs the current process can
12122use. The number of usable CPUs can be obtained with
12123``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012124[clinic start generated code]*/
12125
Larry Hastings2f936352014-08-05 14:04:04 +100012126static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012127os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012128/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012129{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012130 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012131#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012132 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
12133 Need to fallback to Vista behavior if this call isn't present */
12134 HINSTANCE hKernel32;
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012135 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
Tony Roberts4860f012019-02-02 18:16:42 +010012136 Py_BEGIN_ALLOW_THREADS
12137 hKernel32 = GetModuleHandleW(L"KERNEL32");
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012138 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
12139 "GetMaximumProcessorCount");
Tony Roberts4860f012019-02-02 18:16:42 +010012140 Py_END_ALLOW_THREADS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012141 if (_GetMaximumProcessorCount != NULL) {
12142 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
12143 }
12144 else {
12145 SYSTEM_INFO sysinfo;
12146 GetSystemInfo(&sysinfo);
12147 ncpu = sysinfo.dwNumberOfProcessors;
12148 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012149#elif defined(__hpux)
12150 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12151#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12152 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012153#elif defined(__DragonFly__) || \
12154 defined(__OpenBSD__) || \
12155 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012156 defined(__NetBSD__) || \
12157 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012158 int mib[2];
12159 size_t len = sizeof(ncpu);
12160 mib[0] = CTL_HW;
12161 mib[1] = HW_NCPU;
12162 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12163 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012164#endif
12165 if (ncpu >= 1)
12166 return PyLong_FromLong(ncpu);
12167 else
12168 Py_RETURN_NONE;
12169}
12170
Victor Stinnerdaf45552013-08-28 00:53:59 +020012171
Larry Hastings2f936352014-08-05 14:04:04 +100012172/*[clinic input]
12173os.get_inheritable -> bool
12174
12175 fd: int
12176 /
12177
12178Get the close-on-exe flag of the specified file descriptor.
12179[clinic start generated code]*/
12180
Larry Hastings2f936352014-08-05 14:04:04 +100012181static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012182os_get_inheritable_impl(PyObject *module, int fd)
12183/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012184{
Steve Dower8fc89802015-04-12 00:26:27 -040012185 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012186 _Py_BEGIN_SUPPRESS_IPH
12187 return_value = _Py_get_inheritable(fd);
12188 _Py_END_SUPPRESS_IPH
12189 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012190}
12191
12192
12193/*[clinic input]
12194os.set_inheritable
12195 fd: int
12196 inheritable: int
12197 /
12198
12199Set the inheritable flag of the specified file descriptor.
12200[clinic start generated code]*/
12201
Larry Hastings2f936352014-08-05 14:04:04 +100012202static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012203os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12204/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012205{
Steve Dower8fc89802015-04-12 00:26:27 -040012206 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012207
Steve Dower8fc89802015-04-12 00:26:27 -040012208 _Py_BEGIN_SUPPRESS_IPH
12209 result = _Py_set_inheritable(fd, inheritable, NULL);
12210 _Py_END_SUPPRESS_IPH
12211 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012212 return NULL;
12213 Py_RETURN_NONE;
12214}
12215
12216
12217#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012218/*[clinic input]
12219os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012220 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012221 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012222
Larry Hastings2f936352014-08-05 14:04:04 +100012223Get the close-on-exe flag of the specified file descriptor.
12224[clinic start generated code]*/
12225
Larry Hastings2f936352014-08-05 14:04:04 +100012226static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012227os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012228/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012229{
12230 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012231
12232 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12233 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012234 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012235 }
12236
Larry Hastings2f936352014-08-05 14:04:04 +100012237 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012238}
12239
Victor Stinnerdaf45552013-08-28 00:53:59 +020012240
Larry Hastings2f936352014-08-05 14:04:04 +100012241/*[clinic input]
12242os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012243 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012244 inheritable: bool
12245 /
12246
12247Set the inheritable flag of the specified handle.
12248[clinic start generated code]*/
12249
Larry Hastings2f936352014-08-05 14:04:04 +100012250static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012251os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012252 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012253/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012254{
12255 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012256 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12257 PyErr_SetFromWindowsErr(0);
12258 return NULL;
12259 }
12260 Py_RETURN_NONE;
12261}
Larry Hastings2f936352014-08-05 14:04:04 +100012262#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012263
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012264#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012265/*[clinic input]
12266os.get_blocking -> bool
12267 fd: int
12268 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012269
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012270Get the blocking mode of the file descriptor.
12271
12272Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12273[clinic start generated code]*/
12274
12275static int
12276os_get_blocking_impl(PyObject *module, int fd)
12277/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012278{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012279 int blocking;
12280
Steve Dower8fc89802015-04-12 00:26:27 -040012281 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012282 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012283 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012284 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012285}
12286
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012287/*[clinic input]
12288os.set_blocking
12289 fd: int
12290 blocking: bool(accept={int})
12291 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012292
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012293Set the blocking mode of the specified file descriptor.
12294
12295Set the O_NONBLOCK flag if blocking is False,
12296clear the O_NONBLOCK flag otherwise.
12297[clinic start generated code]*/
12298
12299static PyObject *
12300os_set_blocking_impl(PyObject *module, int fd, int blocking)
12301/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012302{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012303 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012304
Steve Dower8fc89802015-04-12 00:26:27 -040012305 _Py_BEGIN_SUPPRESS_IPH
12306 result = _Py_set_blocking(fd, blocking);
12307 _Py_END_SUPPRESS_IPH
12308 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012309 return NULL;
12310 Py_RETURN_NONE;
12311}
12312#endif /* !MS_WINDOWS */
12313
12314
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012315/*[clinic input]
12316class os.DirEntry "DirEntry *" "&DirEntryType"
12317[clinic start generated code]*/
12318/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012319
12320typedef struct {
12321 PyObject_HEAD
12322 PyObject *name;
12323 PyObject *path;
12324 PyObject *stat;
12325 PyObject *lstat;
12326#ifdef MS_WINDOWS
12327 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012328 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012329 int got_file_index;
12330#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012331#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012332 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012333#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012334 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012335 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012336#endif
12337} DirEntry;
12338
12339static void
12340DirEntry_dealloc(DirEntry *entry)
12341{
12342 Py_XDECREF(entry->name);
12343 Py_XDECREF(entry->path);
12344 Py_XDECREF(entry->stat);
12345 Py_XDECREF(entry->lstat);
12346 Py_TYPE(entry)->tp_free((PyObject *)entry);
12347}
12348
12349/* Forward reference */
12350static int
12351DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12352
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012353/*[clinic input]
12354os.DirEntry.is_symlink -> bool
12355
12356Return True if the entry is a symbolic link; cached per entry.
12357[clinic start generated code]*/
12358
Victor Stinner6036e442015-03-08 01:58:04 +010012359static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012360os_DirEntry_is_symlink_impl(DirEntry *self)
12361/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012362{
12363#ifdef MS_WINDOWS
12364 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012365#elif defined(HAVE_DIRENT_D_TYPE)
12366 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012367 if (self->d_type != DT_UNKNOWN)
12368 return self->d_type == DT_LNK;
12369 else
12370 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012371#else
12372 /* POSIX without d_type */
12373 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012374#endif
12375}
12376
12377static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012378DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12379{
12380 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012381 STRUCT_STAT st;
12382 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012383
12384#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012385 if (!PyUnicode_FSDecoder(self->path, &ub))
12386 return NULL;
12387 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012388#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012389 if (!PyUnicode_FSConverter(self->path, &ub))
12390 return NULL;
12391 const char *path = PyBytes_AS_STRING(ub);
12392 if (self->dir_fd != DEFAULT_DIR_FD) {
12393#ifdef HAVE_FSTATAT
12394 result = fstatat(self->dir_fd, path, &st,
12395 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12396#else
12397 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12398 return NULL;
12399#endif /* HAVE_FSTATAT */
12400 }
12401 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012402#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012403 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012404 if (follow_symlinks)
12405 result = STAT(path, &st);
12406 else
12407 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012408 }
12409 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012410
12411 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012412 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012413
12414 return _pystat_fromstructstat(&st);
12415}
12416
12417static PyObject *
12418DirEntry_get_lstat(DirEntry *self)
12419{
12420 if (!self->lstat) {
12421#ifdef MS_WINDOWS
12422 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12423#else /* POSIX */
12424 self->lstat = DirEntry_fetch_stat(self, 0);
12425#endif
12426 }
12427 Py_XINCREF(self->lstat);
12428 return self->lstat;
12429}
12430
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012431/*[clinic input]
12432os.DirEntry.stat
12433 *
12434 follow_symlinks: bool = True
12435
12436Return stat_result object for the entry; cached per entry.
12437[clinic start generated code]*/
12438
Victor Stinner6036e442015-03-08 01:58:04 +010012439static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012440os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12441/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012442{
12443 if (!follow_symlinks)
12444 return DirEntry_get_lstat(self);
12445
12446 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012447 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012448 if (result == -1)
12449 return NULL;
12450 else if (result)
12451 self->stat = DirEntry_fetch_stat(self, 1);
12452 else
12453 self->stat = DirEntry_get_lstat(self);
12454 }
12455
12456 Py_XINCREF(self->stat);
12457 return self->stat;
12458}
12459
Victor Stinner6036e442015-03-08 01:58:04 +010012460/* Set exception and return -1 on error, 0 for False, 1 for True */
12461static int
12462DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12463{
12464 PyObject *stat = NULL;
12465 PyObject *st_mode = NULL;
12466 long mode;
12467 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012468#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012469 int is_symlink;
12470 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012471#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012472#ifdef MS_WINDOWS
12473 unsigned long dir_bits;
12474#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012475 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012476
12477#ifdef MS_WINDOWS
12478 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12479 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012480#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012481 is_symlink = self->d_type == DT_LNK;
12482 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12483#endif
12484
Victor Stinner35a97c02015-03-08 02:59:09 +010012485#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012486 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012487#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012488 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012489 if (!stat) {
12490 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12491 /* If file doesn't exist (anymore), then return False
12492 (i.e., say it's not a file/directory) */
12493 PyErr_Clear();
12494 return 0;
12495 }
12496 goto error;
12497 }
12498 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12499 if (!st_mode)
12500 goto error;
12501
12502 mode = PyLong_AsLong(st_mode);
12503 if (mode == -1 && PyErr_Occurred())
12504 goto error;
12505 Py_CLEAR(st_mode);
12506 Py_CLEAR(stat);
12507 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012508#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012509 }
12510 else if (is_symlink) {
12511 assert(mode_bits != S_IFLNK);
12512 result = 0;
12513 }
12514 else {
12515 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12516#ifdef MS_WINDOWS
12517 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12518 if (mode_bits == S_IFDIR)
12519 result = dir_bits != 0;
12520 else
12521 result = dir_bits == 0;
12522#else /* POSIX */
12523 if (mode_bits == S_IFDIR)
12524 result = self->d_type == DT_DIR;
12525 else
12526 result = self->d_type == DT_REG;
12527#endif
12528 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012529#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012530
12531 return result;
12532
12533error:
12534 Py_XDECREF(st_mode);
12535 Py_XDECREF(stat);
12536 return -1;
12537}
12538
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012539/*[clinic input]
12540os.DirEntry.is_dir -> bool
12541 *
12542 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012543
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012544Return True if the entry is a directory; cached per entry.
12545[clinic start generated code]*/
12546
12547static int
12548os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12549/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12550{
12551 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012552}
12553
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012554/*[clinic input]
12555os.DirEntry.is_file -> bool
12556 *
12557 follow_symlinks: bool = True
12558
12559Return True if the entry is a file; cached per entry.
12560[clinic start generated code]*/
12561
12562static int
12563os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12564/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012565{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012566 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012567}
12568
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012569/*[clinic input]
12570os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012571
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012572Return inode of the entry; cached per entry.
12573[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012574
12575static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012576os_DirEntry_inode_impl(DirEntry *self)
12577/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012578{
12579#ifdef MS_WINDOWS
12580 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012581 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012582 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012583 STRUCT_STAT stat;
12584 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012585
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012586 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012587 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012588 path = PyUnicode_AsUnicode(unicode);
12589 result = LSTAT(path, &stat);
12590 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012591
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012592 if (result != 0)
12593 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012594
12595 self->win32_file_index = stat.st_ino;
12596 self->got_file_index = 1;
12597 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012598 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12599 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012600#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012601 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12602 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012603#endif
12604}
12605
12606static PyObject *
12607DirEntry_repr(DirEntry *self)
12608{
12609 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12610}
12611
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012612/*[clinic input]
12613os.DirEntry.__fspath__
12614
12615Returns the path for the entry.
12616[clinic start generated code]*/
12617
Brett Cannon96881cd2016-06-10 14:37:21 -070012618static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012619os_DirEntry___fspath___impl(DirEntry *self)
12620/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012621{
12622 Py_INCREF(self->path);
12623 return self->path;
12624}
12625
Victor Stinner6036e442015-03-08 01:58:04 +010012626static PyMemberDef DirEntry_members[] = {
12627 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12628 "the entry's base filename, relative to scandir() \"path\" argument"},
12629 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12630 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12631 {NULL}
12632};
12633
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012634#include "clinic/posixmodule.c.h"
12635
Victor Stinner6036e442015-03-08 01:58:04 +010012636static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012637 OS_DIRENTRY_IS_DIR_METHODDEF
12638 OS_DIRENTRY_IS_FILE_METHODDEF
12639 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12640 OS_DIRENTRY_STAT_METHODDEF
12641 OS_DIRENTRY_INODE_METHODDEF
12642 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012643 {NULL}
12644};
12645
Benjamin Peterson5646de42015-04-12 17:56:34 -040012646static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012647 PyVarObject_HEAD_INIT(NULL, 0)
12648 MODNAME ".DirEntry", /* tp_name */
12649 sizeof(DirEntry), /* tp_basicsize */
12650 0, /* tp_itemsize */
12651 /* methods */
12652 (destructor)DirEntry_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020012653 0, /* tp_vectorcall_offset */
Victor Stinner6036e442015-03-08 01:58:04 +010012654 0, /* tp_getattr */
12655 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020012656 0, /* tp_as_async */
Victor Stinner6036e442015-03-08 01:58:04 +010012657 (reprfunc)DirEntry_repr, /* tp_repr */
12658 0, /* tp_as_number */
12659 0, /* tp_as_sequence */
12660 0, /* tp_as_mapping */
12661 0, /* tp_hash */
12662 0, /* tp_call */
12663 0, /* tp_str */
12664 0, /* tp_getattro */
12665 0, /* tp_setattro */
12666 0, /* tp_as_buffer */
12667 Py_TPFLAGS_DEFAULT, /* tp_flags */
12668 0, /* tp_doc */
12669 0, /* tp_traverse */
12670 0, /* tp_clear */
12671 0, /* tp_richcompare */
12672 0, /* tp_weaklistoffset */
12673 0, /* tp_iter */
12674 0, /* tp_iternext */
12675 DirEntry_methods, /* tp_methods */
12676 DirEntry_members, /* tp_members */
12677};
12678
12679#ifdef MS_WINDOWS
12680
12681static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012682join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012683{
12684 Py_ssize_t path_len;
12685 Py_ssize_t size;
12686 wchar_t *result;
12687 wchar_t ch;
12688
12689 if (!path_wide) { /* Default arg: "." */
12690 path_wide = L".";
12691 path_len = 1;
12692 }
12693 else {
12694 path_len = wcslen(path_wide);
12695 }
12696
12697 /* The +1's are for the path separator and the NUL */
12698 size = path_len + 1 + wcslen(filename) + 1;
12699 result = PyMem_New(wchar_t, size);
12700 if (!result) {
12701 PyErr_NoMemory();
12702 return NULL;
12703 }
12704 wcscpy(result, path_wide);
12705 if (path_len > 0) {
12706 ch = result[path_len - 1];
12707 if (ch != SEP && ch != ALTSEP && ch != L':')
12708 result[path_len++] = SEP;
12709 wcscpy(result + path_len, filename);
12710 }
12711 return result;
12712}
12713
12714static PyObject *
12715DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12716{
12717 DirEntry *entry;
12718 BY_HANDLE_FILE_INFORMATION file_info;
12719 ULONG reparse_tag;
12720 wchar_t *joined_path;
12721
12722 entry = PyObject_New(DirEntry, &DirEntryType);
12723 if (!entry)
12724 return NULL;
12725 entry->name = NULL;
12726 entry->path = NULL;
12727 entry->stat = NULL;
12728 entry->lstat = NULL;
12729 entry->got_file_index = 0;
12730
12731 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12732 if (!entry->name)
12733 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012734 if (path->narrow) {
12735 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12736 if (!entry->name)
12737 goto error;
12738 }
Victor Stinner6036e442015-03-08 01:58:04 +010012739
12740 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12741 if (!joined_path)
12742 goto error;
12743
12744 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12745 PyMem_Free(joined_path);
12746 if (!entry->path)
12747 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012748 if (path->narrow) {
12749 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12750 if (!entry->path)
12751 goto error;
12752 }
Victor Stinner6036e442015-03-08 01:58:04 +010012753
Steve Dowercc16be82016-09-08 10:35:16 -070012754 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012755 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12756
12757 return (PyObject *)entry;
12758
12759error:
12760 Py_DECREF(entry);
12761 return NULL;
12762}
12763
12764#else /* POSIX */
12765
12766static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012767join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012768{
12769 Py_ssize_t path_len;
12770 Py_ssize_t size;
12771 char *result;
12772
12773 if (!path_narrow) { /* Default arg: "." */
12774 path_narrow = ".";
12775 path_len = 1;
12776 }
12777 else {
12778 path_len = strlen(path_narrow);
12779 }
12780
12781 if (filename_len == -1)
12782 filename_len = strlen(filename);
12783
12784 /* The +1's are for the path separator and the NUL */
12785 size = path_len + 1 + filename_len + 1;
12786 result = PyMem_New(char, size);
12787 if (!result) {
12788 PyErr_NoMemory();
12789 return NULL;
12790 }
12791 strcpy(result, path_narrow);
12792 if (path_len > 0 && result[path_len - 1] != '/')
12793 result[path_len++] = '/';
12794 strcpy(result + path_len, filename);
12795 return result;
12796}
12797
12798static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012799DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012800 ino_t d_ino
12801#ifdef HAVE_DIRENT_D_TYPE
12802 , unsigned char d_type
12803#endif
12804 )
Victor Stinner6036e442015-03-08 01:58:04 +010012805{
12806 DirEntry *entry;
12807 char *joined_path;
12808
12809 entry = PyObject_New(DirEntry, &DirEntryType);
12810 if (!entry)
12811 return NULL;
12812 entry->name = NULL;
12813 entry->path = NULL;
12814 entry->stat = NULL;
12815 entry->lstat = NULL;
12816
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012817 if (path->fd != -1) {
12818 entry->dir_fd = path->fd;
12819 joined_path = NULL;
12820 }
12821 else {
12822 entry->dir_fd = DEFAULT_DIR_FD;
12823 joined_path = join_path_filename(path->narrow, name, name_len);
12824 if (!joined_path)
12825 goto error;
12826 }
Victor Stinner6036e442015-03-08 01:58:04 +010012827
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012828 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012829 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012830 if (joined_path)
12831 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012832 }
12833 else {
12834 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012835 if (joined_path)
12836 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012837 }
12838 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012839 if (!entry->name)
12840 goto error;
12841
12842 if (path->fd != -1) {
12843 entry->path = entry->name;
12844 Py_INCREF(entry->path);
12845 }
12846 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012847 goto error;
12848
Victor Stinner35a97c02015-03-08 02:59:09 +010012849#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012850 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012851#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012852 entry->d_ino = d_ino;
12853
12854 return (PyObject *)entry;
12855
12856error:
12857 Py_XDECREF(entry);
12858 return NULL;
12859}
12860
12861#endif
12862
12863
12864typedef struct {
12865 PyObject_HEAD
12866 path_t path;
12867#ifdef MS_WINDOWS
12868 HANDLE handle;
12869 WIN32_FIND_DATAW file_data;
12870 int first_time;
12871#else /* POSIX */
12872 DIR *dirp;
12873#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012874#ifdef HAVE_FDOPENDIR
12875 int fd;
12876#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012877} ScandirIterator;
12878
12879#ifdef MS_WINDOWS
12880
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012881static int
12882ScandirIterator_is_closed(ScandirIterator *iterator)
12883{
12884 return iterator->handle == INVALID_HANDLE_VALUE;
12885}
12886
Victor Stinner6036e442015-03-08 01:58:04 +010012887static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012888ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012889{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012890 HANDLE handle = iterator->handle;
12891
12892 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012893 return;
12894
Victor Stinner6036e442015-03-08 01:58:04 +010012895 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012896 Py_BEGIN_ALLOW_THREADS
12897 FindClose(handle);
12898 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012899}
12900
12901static PyObject *
12902ScandirIterator_iternext(ScandirIterator *iterator)
12903{
12904 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12905 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012906 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012907
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012908 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012909 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012910 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012911
12912 while (1) {
12913 if (!iterator->first_time) {
12914 Py_BEGIN_ALLOW_THREADS
12915 success = FindNextFileW(iterator->handle, file_data);
12916 Py_END_ALLOW_THREADS
12917 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012918 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012919 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012920 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012921 break;
12922 }
12923 }
12924 iterator->first_time = 0;
12925
12926 /* Skip over . and .. */
12927 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012928 wcscmp(file_data->cFileName, L"..") != 0) {
12929 entry = DirEntry_from_find_data(&iterator->path, file_data);
12930 if (!entry)
12931 break;
12932 return entry;
12933 }
Victor Stinner6036e442015-03-08 01:58:04 +010012934
12935 /* Loop till we get a non-dot directory or finish iterating */
12936 }
12937
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012938 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012939 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012940 return NULL;
12941}
12942
12943#else /* POSIX */
12944
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012945static int
12946ScandirIterator_is_closed(ScandirIterator *iterator)
12947{
12948 return !iterator->dirp;
12949}
12950
Victor Stinner6036e442015-03-08 01:58:04 +010012951static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012952ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012953{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012954 DIR *dirp = iterator->dirp;
12955
12956 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012957 return;
12958
Victor Stinner6036e442015-03-08 01:58:04 +010012959 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012960 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012961#ifdef HAVE_FDOPENDIR
12962 if (iterator->path.fd != -1)
12963 rewinddir(dirp);
12964#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012965 closedir(dirp);
12966 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012967 return;
12968}
12969
12970static PyObject *
12971ScandirIterator_iternext(ScandirIterator *iterator)
12972{
12973 struct dirent *direntp;
12974 Py_ssize_t name_len;
12975 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012976 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012977
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012978 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012979 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012980 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012981
12982 while (1) {
12983 errno = 0;
12984 Py_BEGIN_ALLOW_THREADS
12985 direntp = readdir(iterator->dirp);
12986 Py_END_ALLOW_THREADS
12987
12988 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012989 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012990 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012991 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012992 break;
12993 }
12994
12995 /* Skip over . and .. */
12996 name_len = NAMLEN(direntp);
12997 is_dot = direntp->d_name[0] == '.' &&
12998 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12999 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013000 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010013001 name_len, direntp->d_ino
13002#ifdef HAVE_DIRENT_D_TYPE
13003 , direntp->d_type
13004#endif
13005 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013006 if (!entry)
13007 break;
13008 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013009 }
13010
13011 /* Loop till we get a non-dot directory or finish iterating */
13012 }
13013
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013014 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013015 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013016 return NULL;
13017}
13018
13019#endif
13020
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013021static PyObject *
13022ScandirIterator_close(ScandirIterator *self, PyObject *args)
13023{
13024 ScandirIterator_closedir(self);
13025 Py_RETURN_NONE;
13026}
13027
13028static PyObject *
13029ScandirIterator_enter(PyObject *self, PyObject *args)
13030{
13031 Py_INCREF(self);
13032 return self;
13033}
13034
13035static PyObject *
13036ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13037{
13038 ScandirIterator_closedir(self);
13039 Py_RETURN_NONE;
13040}
13041
Victor Stinner6036e442015-03-08 01:58:04 +010013042static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013043ScandirIterator_finalize(ScandirIterator *iterator)
13044{
13045 PyObject *error_type, *error_value, *error_traceback;
13046
13047 /* Save the current exception, if any. */
13048 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13049
13050 if (!ScandirIterator_is_closed(iterator)) {
13051 ScandirIterator_closedir(iterator);
13052
13053 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13054 "unclosed scandir iterator %R", iterator)) {
13055 /* Spurious errors can appear at shutdown */
13056 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13057 PyErr_WriteUnraisable((PyObject *) iterator);
13058 }
13059 }
13060 }
13061
Victor Stinner7bfa4092016-03-23 00:43:54 +010013062 path_cleanup(&iterator->path);
13063
13064 /* Restore the saved exception. */
13065 PyErr_Restore(error_type, error_value, error_traceback);
13066}
13067
13068static void
Victor Stinner6036e442015-03-08 01:58:04 +010013069ScandirIterator_dealloc(ScandirIterator *iterator)
13070{
Victor Stinner7bfa4092016-03-23 00:43:54 +010013071 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13072 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013073
Victor Stinner6036e442015-03-08 01:58:04 +010013074 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
13075}
13076
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013077static PyMethodDef ScandirIterator_methods[] = {
13078 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13079 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13080 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13081 {NULL}
13082};
13083
Benjamin Peterson5646de42015-04-12 17:56:34 -040013084static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010013085 PyVarObject_HEAD_INIT(NULL, 0)
13086 MODNAME ".ScandirIterator", /* tp_name */
13087 sizeof(ScandirIterator), /* tp_basicsize */
13088 0, /* tp_itemsize */
13089 /* methods */
13090 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020013091 0, /* tp_vectorcall_offset */
Victor Stinner6036e442015-03-08 01:58:04 +010013092 0, /* tp_getattr */
13093 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020013094 0, /* tp_as_async */
Victor Stinner6036e442015-03-08 01:58:04 +010013095 0, /* tp_repr */
13096 0, /* tp_as_number */
13097 0, /* tp_as_sequence */
13098 0, /* tp_as_mapping */
13099 0, /* tp_hash */
13100 0, /* tp_call */
13101 0, /* tp_str */
13102 0, /* tp_getattro */
13103 0, /* tp_setattro */
13104 0, /* tp_as_buffer */
Antoine Pitrouada319b2019-05-29 22:12:38 +020013105 Py_TPFLAGS_DEFAULT, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010013106 0, /* tp_doc */
13107 0, /* tp_traverse */
13108 0, /* tp_clear */
13109 0, /* tp_richcompare */
13110 0, /* tp_weaklistoffset */
13111 PyObject_SelfIter, /* tp_iter */
13112 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013113 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010013114 0, /* tp_members */
13115 0, /* tp_getset */
13116 0, /* tp_base */
13117 0, /* tp_dict */
13118 0, /* tp_descr_get */
13119 0, /* tp_descr_set */
13120 0, /* tp_dictoffset */
13121 0, /* tp_init */
13122 0, /* tp_alloc */
13123 0, /* tp_new */
13124 0, /* tp_free */
13125 0, /* tp_is_gc */
13126 0, /* tp_bases */
13127 0, /* tp_mro */
13128 0, /* tp_cache */
13129 0, /* tp_subclasses */
13130 0, /* tp_weaklist */
13131 0, /* tp_del */
13132 0, /* tp_version_tag */
13133 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010013134};
13135
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013136/*[clinic input]
13137os.scandir
13138
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013139 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013140
13141Return an iterator of DirEntry objects for given path.
13142
BNMetricsb9427072018-11-02 15:20:19 +000013143path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013144is bytes, the names of yielded DirEntry objects will also be bytes; in
13145all other circumstances they will be str.
13146
13147If path is None, uses the path='.'.
13148[clinic start generated code]*/
13149
Victor Stinner6036e442015-03-08 01:58:04 +010013150static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013151os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013152/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013153{
13154 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013155#ifdef MS_WINDOWS
13156 wchar_t *path_strW;
13157#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013158 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013159#ifdef HAVE_FDOPENDIR
13160 int fd = -1;
13161#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013162#endif
13163
13164 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
13165 if (!iterator)
13166 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013167
13168#ifdef MS_WINDOWS
13169 iterator->handle = INVALID_HANDLE_VALUE;
13170#else
13171 iterator->dirp = NULL;
13172#endif
13173
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013174 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013175 /* Move the ownership to iterator->path */
13176 path->object = NULL;
13177 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013178
13179#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013180 iterator->first_time = 1;
13181
13182 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13183 if (!path_strW)
13184 goto error;
13185
13186 Py_BEGIN_ALLOW_THREADS
13187 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13188 Py_END_ALLOW_THREADS
13189
13190 PyMem_Free(path_strW);
13191
13192 if (iterator->handle == INVALID_HANDLE_VALUE) {
13193 path_error(&iterator->path);
13194 goto error;
13195 }
13196#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013197 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013198#ifdef HAVE_FDOPENDIR
13199 if (path->fd != -1) {
13200 /* closedir() closes the FD, so we duplicate it */
13201 fd = _Py_dup(path->fd);
13202 if (fd == -1)
13203 goto error;
13204
13205 Py_BEGIN_ALLOW_THREADS
13206 iterator->dirp = fdopendir(fd);
13207 Py_END_ALLOW_THREADS
13208 }
13209 else
13210#endif
13211 {
13212 if (iterator->path.narrow)
13213 path_str = iterator->path.narrow;
13214 else
13215 path_str = ".";
13216
13217 Py_BEGIN_ALLOW_THREADS
13218 iterator->dirp = opendir(path_str);
13219 Py_END_ALLOW_THREADS
13220 }
Victor Stinner6036e442015-03-08 01:58:04 +010013221
13222 if (!iterator->dirp) {
13223 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013224#ifdef HAVE_FDOPENDIR
13225 if (fd != -1) {
13226 Py_BEGIN_ALLOW_THREADS
13227 close(fd);
13228 Py_END_ALLOW_THREADS
13229 }
13230#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013231 goto error;
13232 }
13233#endif
13234
13235 return (PyObject *)iterator;
13236
13237error:
13238 Py_DECREF(iterator);
13239 return NULL;
13240}
13241
Ethan Furman410ef8e2016-06-04 12:06:26 -070013242/*
13243 Return the file system path representation of the object.
13244
13245 If the object is str or bytes, then allow it to pass through with
13246 an incremented refcount. If the object defines __fspath__(), then
13247 return the result of that method. All other types raise a TypeError.
13248*/
13249PyObject *
13250PyOS_FSPath(PyObject *path)
13251{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013252 /* For error message reasons, this function is manually inlined in
13253 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013254 _Py_IDENTIFIER(__fspath__);
13255 PyObject *func = NULL;
13256 PyObject *path_repr = NULL;
13257
13258 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13259 Py_INCREF(path);
13260 return path;
13261 }
13262
13263 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13264 if (NULL == func) {
13265 return PyErr_Format(PyExc_TypeError,
13266 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013267 "not %.200s",
13268 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013269 }
13270
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013271 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013272 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013273 if (NULL == path_repr) {
13274 return NULL;
13275 }
13276
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013277 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13278 PyErr_Format(PyExc_TypeError,
13279 "expected %.200s.__fspath__() to return str or bytes, "
13280 "not %.200s", Py_TYPE(path)->tp_name,
13281 Py_TYPE(path_repr)->tp_name);
13282 Py_DECREF(path_repr);
13283 return NULL;
13284 }
13285
Ethan Furman410ef8e2016-06-04 12:06:26 -070013286 return path_repr;
13287}
13288
13289/*[clinic input]
13290os.fspath
13291
13292 path: object
13293
13294Return the file system path representation of the object.
13295
Brett Cannonb4f43e92016-06-09 14:32:08 -070013296If the object is str or bytes, then allow it to pass through as-is. If the
13297object defines __fspath__(), then return the result of that method. All other
13298types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013299[clinic start generated code]*/
13300
13301static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013302os_fspath_impl(PyObject *module, PyObject *path)
13303/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013304{
13305 return PyOS_FSPath(path);
13306}
Victor Stinner6036e442015-03-08 01:58:04 +010013307
Victor Stinner9b1f4742016-09-06 16:18:52 -070013308#ifdef HAVE_GETRANDOM_SYSCALL
13309/*[clinic input]
13310os.getrandom
13311
13312 size: Py_ssize_t
13313 flags: int=0
13314
13315Obtain a series of random bytes.
13316[clinic start generated code]*/
13317
13318static PyObject *
13319os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13320/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13321{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013322 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013323 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013324
13325 if (size < 0) {
13326 errno = EINVAL;
13327 return posix_error();
13328 }
13329
Victor Stinnerec2319c2016-09-20 23:00:59 +020013330 bytes = PyBytes_FromStringAndSize(NULL, size);
13331 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013332 PyErr_NoMemory();
13333 return NULL;
13334 }
13335
13336 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013337 n = syscall(SYS_getrandom,
13338 PyBytes_AS_STRING(bytes),
13339 PyBytes_GET_SIZE(bytes),
13340 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013341 if (n < 0 && errno == EINTR) {
13342 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013343 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013344 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013345
13346 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013347 continue;
13348 }
13349 break;
13350 }
13351
13352 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013353 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013354 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013355 }
13356
Victor Stinnerec2319c2016-09-20 23:00:59 +020013357 if (n != size) {
13358 _PyBytes_Resize(&bytes, n);
13359 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013360
13361 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013362
13363error:
13364 Py_DECREF(bytes);
13365 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013366}
13367#endif /* HAVE_GETRANDOM_SYSCALL */
13368
Steve Dower2438cdf2019-03-29 16:37:16 -070013369#ifdef MS_WINDOWS
13370/* bpo-36085: Helper functions for managing DLL search directories
13371 * on win32
13372 */
13373
13374typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13375typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13376
13377/*[clinic input]
13378os._add_dll_directory
13379
13380 path: path_t
13381
13382Add a path to the DLL search path.
13383
13384This search path is used when resolving dependencies for imported
13385extension modules (the module itself is resolved through sys.path),
13386and also by ctypes.
13387
13388Returns an opaque value that may be passed to os.remove_dll_directory
13389to remove this directory from the search path.
13390[clinic start generated code]*/
13391
13392static PyObject *
13393os__add_dll_directory_impl(PyObject *module, path_t *path)
13394/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13395{
13396 HMODULE hKernel32;
13397 PAddDllDirectory AddDllDirectory;
13398 DLL_DIRECTORY_COOKIE cookie = 0;
13399 DWORD err = 0;
13400
13401 /* For Windows 7, we have to load this. As this will be a fairly
13402 infrequent operation, just do it each time. Kernel32 is always
13403 loaded. */
13404 Py_BEGIN_ALLOW_THREADS
13405 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13406 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13407 hKernel32, "AddDllDirectory")) ||
13408 !(cookie = (*AddDllDirectory)(path->wide))) {
13409 err = GetLastError();
13410 }
13411 Py_END_ALLOW_THREADS
13412
13413 if (err) {
13414 return win32_error_object_err("add_dll_directory",
13415 path->object, err);
13416 }
13417
13418 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13419}
13420
13421/*[clinic input]
13422os._remove_dll_directory
13423
13424 cookie: object
13425
13426Removes a path from the DLL search path.
13427
13428The parameter is an opaque value that was returned from
13429os.add_dll_directory. You can only remove directories that you added
13430yourself.
13431[clinic start generated code]*/
13432
13433static PyObject *
13434os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13435/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13436{
13437 HMODULE hKernel32;
13438 PRemoveDllDirectory RemoveDllDirectory;
13439 DLL_DIRECTORY_COOKIE cookieValue;
13440 DWORD err = 0;
13441
13442 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13443 PyErr_SetString(PyExc_TypeError,
13444 "Provided cookie was not returned from os.add_dll_directory");
13445 return NULL;
13446 }
13447
13448 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13449 cookie, "DLL directory cookie");
13450
13451 /* For Windows 7, we have to load this. As this will be a fairly
13452 infrequent operation, just do it each time. Kernel32 is always
13453 loaded. */
13454 Py_BEGIN_ALLOW_THREADS
13455 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13456 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13457 hKernel32, "RemoveDllDirectory")) ||
13458 !(*RemoveDllDirectory)(cookieValue)) {
13459 err = GetLastError();
13460 }
13461 Py_END_ALLOW_THREADS
13462
13463 if (err) {
13464 return win32_error_object_err("remove_dll_directory",
13465 NULL, err);
13466 }
13467
13468 if (PyCapsule_SetName(cookie, NULL)) {
13469 return NULL;
13470 }
13471
13472 Py_RETURN_NONE;
13473}
13474
13475#endif
Larry Hastings31826802013-10-19 00:09:25 -070013476
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013477static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013478
13479 OS_STAT_METHODDEF
13480 OS_ACCESS_METHODDEF
13481 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013482 OS_CHDIR_METHODDEF
13483 OS_CHFLAGS_METHODDEF
13484 OS_CHMOD_METHODDEF
13485 OS_FCHMOD_METHODDEF
13486 OS_LCHMOD_METHODDEF
13487 OS_CHOWN_METHODDEF
13488 OS_FCHOWN_METHODDEF
13489 OS_LCHOWN_METHODDEF
13490 OS_LCHFLAGS_METHODDEF
13491 OS_CHROOT_METHODDEF
13492 OS_CTERMID_METHODDEF
13493 OS_GETCWD_METHODDEF
13494 OS_GETCWDB_METHODDEF
13495 OS_LINK_METHODDEF
13496 OS_LISTDIR_METHODDEF
13497 OS_LSTAT_METHODDEF
13498 OS_MKDIR_METHODDEF
13499 OS_NICE_METHODDEF
13500 OS_GETPRIORITY_METHODDEF
13501 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013502 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013503 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013504 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010013505 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013506 OS_RENAME_METHODDEF
13507 OS_REPLACE_METHODDEF
13508 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013509 OS_SYMLINK_METHODDEF
13510 OS_SYSTEM_METHODDEF
13511 OS_UMASK_METHODDEF
13512 OS_UNAME_METHODDEF
13513 OS_UNLINK_METHODDEF
13514 OS_REMOVE_METHODDEF
13515 OS_UTIME_METHODDEF
13516 OS_TIMES_METHODDEF
13517 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013518 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013519 OS_EXECV_METHODDEF
13520 OS_EXECVE_METHODDEF
13521 OS_SPAWNV_METHODDEF
13522 OS_SPAWNVE_METHODDEF
13523 OS_FORK1_METHODDEF
13524 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013525 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013526 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13527 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13528 OS_SCHED_GETPARAM_METHODDEF
13529 OS_SCHED_GETSCHEDULER_METHODDEF
13530 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13531 OS_SCHED_SETPARAM_METHODDEF
13532 OS_SCHED_SETSCHEDULER_METHODDEF
13533 OS_SCHED_YIELD_METHODDEF
13534 OS_SCHED_SETAFFINITY_METHODDEF
13535 OS_SCHED_GETAFFINITY_METHODDEF
13536 OS_OPENPTY_METHODDEF
13537 OS_FORKPTY_METHODDEF
13538 OS_GETEGID_METHODDEF
13539 OS_GETEUID_METHODDEF
13540 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013541#ifdef HAVE_GETGROUPLIST
13542 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13543#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013544 OS_GETGROUPS_METHODDEF
13545 OS_GETPID_METHODDEF
13546 OS_GETPGRP_METHODDEF
13547 OS_GETPPID_METHODDEF
13548 OS_GETUID_METHODDEF
13549 OS_GETLOGIN_METHODDEF
13550 OS_KILL_METHODDEF
13551 OS_KILLPG_METHODDEF
13552 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013553#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013554 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013555#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013556 OS_SETUID_METHODDEF
13557 OS_SETEUID_METHODDEF
13558 OS_SETREUID_METHODDEF
13559 OS_SETGID_METHODDEF
13560 OS_SETEGID_METHODDEF
13561 OS_SETREGID_METHODDEF
13562 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013563#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013564 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013565#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013566 OS_GETPGID_METHODDEF
13567 OS_SETPGRP_METHODDEF
13568 OS_WAIT_METHODDEF
13569 OS_WAIT3_METHODDEF
13570 OS_WAIT4_METHODDEF
13571 OS_WAITID_METHODDEF
13572 OS_WAITPID_METHODDEF
13573 OS_GETSID_METHODDEF
13574 OS_SETSID_METHODDEF
13575 OS_SETPGID_METHODDEF
13576 OS_TCGETPGRP_METHODDEF
13577 OS_TCSETPGRP_METHODDEF
13578 OS_OPEN_METHODDEF
13579 OS_CLOSE_METHODDEF
13580 OS_CLOSERANGE_METHODDEF
13581 OS_DEVICE_ENCODING_METHODDEF
13582 OS_DUP_METHODDEF
13583 OS_DUP2_METHODDEF
13584 OS_LOCKF_METHODDEF
13585 OS_LSEEK_METHODDEF
13586 OS_READ_METHODDEF
13587 OS_READV_METHODDEF
13588 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013589 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013590 OS_WRITE_METHODDEF
13591 OS_WRITEV_METHODDEF
13592 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013593 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013594#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013595 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013596 posix_sendfile__doc__},
13597#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013598 OS_FSTAT_METHODDEF
13599 OS_ISATTY_METHODDEF
13600 OS_PIPE_METHODDEF
13601 OS_PIPE2_METHODDEF
13602 OS_MKFIFO_METHODDEF
13603 OS_MKNOD_METHODDEF
13604 OS_MAJOR_METHODDEF
13605 OS_MINOR_METHODDEF
13606 OS_MAKEDEV_METHODDEF
13607 OS_FTRUNCATE_METHODDEF
13608 OS_TRUNCATE_METHODDEF
13609 OS_POSIX_FALLOCATE_METHODDEF
13610 OS_POSIX_FADVISE_METHODDEF
13611 OS_PUTENV_METHODDEF
13612 OS_UNSETENV_METHODDEF
13613 OS_STRERROR_METHODDEF
13614 OS_FCHDIR_METHODDEF
13615 OS_FSYNC_METHODDEF
13616 OS_SYNC_METHODDEF
13617 OS_FDATASYNC_METHODDEF
13618 OS_WCOREDUMP_METHODDEF
13619 OS_WIFCONTINUED_METHODDEF
13620 OS_WIFSTOPPED_METHODDEF
13621 OS_WIFSIGNALED_METHODDEF
13622 OS_WIFEXITED_METHODDEF
13623 OS_WEXITSTATUS_METHODDEF
13624 OS_WTERMSIG_METHODDEF
13625 OS_WSTOPSIG_METHODDEF
13626 OS_FSTATVFS_METHODDEF
13627 OS_STATVFS_METHODDEF
13628 OS_CONFSTR_METHODDEF
13629 OS_SYSCONF_METHODDEF
13630 OS_FPATHCONF_METHODDEF
13631 OS_PATHCONF_METHODDEF
13632 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013633 OS__GETFULLPATHNAME_METHODDEF
13634 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013635 OS__GETDISKUSAGE_METHODDEF
13636 OS__GETFINALPATHNAME_METHODDEF
13637 OS__GETVOLUMEPATHNAME_METHODDEF
13638 OS_GETLOADAVG_METHODDEF
13639 OS_URANDOM_METHODDEF
13640 OS_SETRESUID_METHODDEF
13641 OS_SETRESGID_METHODDEF
13642 OS_GETRESUID_METHODDEF
13643 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013644
Larry Hastings2f936352014-08-05 14:04:04 +100013645 OS_GETXATTR_METHODDEF
13646 OS_SETXATTR_METHODDEF
13647 OS_REMOVEXATTR_METHODDEF
13648 OS_LISTXATTR_METHODDEF
13649
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013650#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13651 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13652#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013653 OS_CPU_COUNT_METHODDEF
13654 OS_GET_INHERITABLE_METHODDEF
13655 OS_SET_INHERITABLE_METHODDEF
13656 OS_GET_HANDLE_INHERITABLE_METHODDEF
13657 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013658#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013659 OS_GET_BLOCKING_METHODDEF
13660 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013661#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013662 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013663 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013664 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060013665 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070013666#ifdef MS_WINDOWS
13667 OS__ADD_DLL_DIRECTORY_METHODDEF
13668 OS__REMOVE_DLL_DIRECTORY_METHODDEF
13669#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013670 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013671};
13672
Barry Warsaw4a342091996-12-19 23:50:02 +000013673static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013674all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013675{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013676#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013677 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013678#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013679#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013680 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013681#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013682#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013683 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013684#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013685#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013686 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013687#endif
Fred Drakec9680921999-12-13 16:37:25 +000013688#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013689 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013690#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013691#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013692 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013693#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013694#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013695 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013696#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013697#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013698 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013699#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013700#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013701 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013702#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013703#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013704 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013705#endif
13706#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013707 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013708#endif
13709#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013710 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013711#endif
13712#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013713 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013714#endif
13715#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013716 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013717#endif
13718#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013719 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013720#endif
13721#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013722 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013723#endif
13724#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013725 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013726#endif
13727#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013728 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013729#endif
13730#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013731 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013732#endif
13733#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013734 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013735#endif
13736#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013737 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013738#endif
13739#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013740 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013741#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013742#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013743 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013744#endif
13745#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013746 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013747#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013748#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013749 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013750#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013751#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013752 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013753#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013754#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013755#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013756 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013757#endif
13758#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013759 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013760#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013761#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013762#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013763 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013764#endif
13765#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013766 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013767#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013768#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013769 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013770#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013771#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013772 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013773#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013774#ifdef O_TMPFILE
13775 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13776#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013777#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013778 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013779#endif
13780#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013781 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013782#endif
13783#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013784 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013785#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013786#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013787 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013788#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013789#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013790 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013791#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013792
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013793
Jesus Cea94363612012-06-22 18:32:07 +020013794#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013795 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013796#endif
13797#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013798 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013799#endif
13800
Tim Peters5aa91602002-01-30 05:46:57 +000013801/* MS Windows */
13802#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013803 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013804 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013805#endif
13806#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013807 /* Optimize for short life (keep in memory). */
13808 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013809 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013810#endif
13811#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013812 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013813 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013814#endif
13815#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013816 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013817 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013818#endif
13819#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013820 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013821 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013822#endif
13823
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013824/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013825#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013826 /* Send a SIGIO signal whenever input or output
13827 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013828 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013829#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013830#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013831 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013832 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013833#endif
13834#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013835 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013836 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013837#endif
13838#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013839 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013840 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013841#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013842#ifdef O_NOLINKS
13843 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013844 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013845#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013846#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013847 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013848 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013849#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013850
Victor Stinner8c62be82010-05-06 00:08:46 +000013851 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013852#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013853 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013854#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013855#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013856 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013857#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013858#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013859 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013860#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013861#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013862 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013863#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013864#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013865 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013866#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013867#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013868 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013869#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013870#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013871 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013872#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013873#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013874 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013875#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013876#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013877 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013878#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013879#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013880 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013881#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013882#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013883 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013884#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013885#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013886 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013887#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013888#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013889 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013890#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013891#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013892 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013893#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013894#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013895 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013896#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013897#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013898 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013899#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013900#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013901 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013902#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013903
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013904 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013905#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013906 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013907#endif /* ST_RDONLY */
13908#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013909 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013910#endif /* ST_NOSUID */
13911
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013912 /* GNU extensions */
13913#ifdef ST_NODEV
13914 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13915#endif /* ST_NODEV */
13916#ifdef ST_NOEXEC
13917 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13918#endif /* ST_NOEXEC */
13919#ifdef ST_SYNCHRONOUS
13920 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13921#endif /* ST_SYNCHRONOUS */
13922#ifdef ST_MANDLOCK
13923 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13924#endif /* ST_MANDLOCK */
13925#ifdef ST_WRITE
13926 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13927#endif /* ST_WRITE */
13928#ifdef ST_APPEND
13929 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13930#endif /* ST_APPEND */
13931#ifdef ST_NOATIME
13932 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13933#endif /* ST_NOATIME */
13934#ifdef ST_NODIRATIME
13935 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13936#endif /* ST_NODIRATIME */
13937#ifdef ST_RELATIME
13938 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13939#endif /* ST_RELATIME */
13940
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013941 /* FreeBSD sendfile() constants */
13942#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013943 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013944#endif
13945#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013946 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013947#endif
13948#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013949 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013950#endif
13951
Ross Lagerwall7807c352011-03-17 20:20:30 +020013952 /* constants for posix_fadvise */
13953#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013954 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013955#endif
13956#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013957 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013958#endif
13959#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013960 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013961#endif
13962#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013963 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013964#endif
13965#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013966 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013967#endif
13968#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013969 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013970#endif
13971
13972 /* constants for waitid */
13973#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013974 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13975 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13976 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013977#endif
13978#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013979 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013980#endif
13981#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013982 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013983#endif
13984#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013985 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013986#endif
13987#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013988 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013989#endif
13990#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013991 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013992#endif
13993#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013994 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013995#endif
13996#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013997 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013998#endif
13999
14000 /* constants for lockf */
14001#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014002 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014003#endif
14004#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014005 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014006#endif
14007#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014008 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014009#endif
14010#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014011 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014012#endif
14013
Pablo Galindo4defba32018-01-27 16:16:37 +000014014#ifdef RWF_DSYNC
14015 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14016#endif
14017#ifdef RWF_HIPRI
14018 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14019#endif
14020#ifdef RWF_SYNC
14021 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14022#endif
14023#ifdef RWF_NOWAIT
14024 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14025#endif
14026
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014027/* constants for posix_spawn */
14028#ifdef HAVE_POSIX_SPAWN
14029 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14030 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14031 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14032#endif
14033
pxinwrf2d7ac72019-05-21 18:46:37 +080014034#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014035 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14036 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014037 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014038#endif
14039#ifdef HAVE_SPAWNV
14040 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014041 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014042#endif
14043
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014044#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014045#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014046 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014047#endif
14048#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014049 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014050#endif
14051#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014052 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014053#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014054#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014055 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014056#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014057#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014058 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014059#endif
14060#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014061 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014062#endif
14063#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014064 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014065#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014066#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014067 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014068#endif
14069#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014070 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014071#endif
14072#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014073 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014074#endif
14075#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014076 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014077#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014078#endif
14079
Benjamin Peterson9428d532011-09-14 11:45:52 -040014080#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014081 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
14082 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
14083 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040014084#endif
14085
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014086#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014087 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014088#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014089#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014090 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014091#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014092#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014093 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014094#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014095#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014096 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014097#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014098#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014099 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014100#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014101#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014102 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014103#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014104#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014105 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014106#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010014107#if HAVE_DECL_RTLD_MEMBER
14108 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
14109#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020014110
Victor Stinner9b1f4742016-09-06 16:18:52 -070014111#ifdef HAVE_GETRANDOM_SYSCALL
14112 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
14113 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
14114#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014115#ifdef HAVE_MEMFD_CREATE
14116 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
14117 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
14118#ifdef MFD_HUGETLB
14119 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014120#endif
14121#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014122 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014123#endif
14124#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014125 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014126#endif
14127#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014128 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014129#endif
14130#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014131 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014132#endif
14133#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014134 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014135#endif
14136#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014137 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014138#endif
14139#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014140 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014141#endif
14142#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014143 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014144#endif
14145#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014146 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014147#endif
14148#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014149 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014150#endif
14151#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014152 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014153#endif
14154#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014155 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014156#endif
14157#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014158 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014159#endif
14160#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014161 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
14162#endif
14163#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070014164
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014165#if defined(__APPLE__)
14166 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
14167#endif
14168
Steve Dower2438cdf2019-03-29 16:37:16 -070014169#ifdef MS_WINDOWS
14170 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
14171 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
14172 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
14173 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
14174 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
14175#endif
14176
Victor Stinner8c62be82010-05-06 00:08:46 +000014177 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000014178}
14179
14180
Martin v. Löwis1a214512008-06-11 05:26:20 +000014181static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000014182 PyModuleDef_HEAD_INIT,
14183 MODNAME,
14184 posix__doc__,
14185 -1,
14186 posix_methods,
14187 NULL,
14188 NULL,
14189 NULL,
14190 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000014191};
14192
14193
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014194static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014195
14196#ifdef HAVE_FACCESSAT
14197 "HAVE_FACCESSAT",
14198#endif
14199
14200#ifdef HAVE_FCHDIR
14201 "HAVE_FCHDIR",
14202#endif
14203
14204#ifdef HAVE_FCHMOD
14205 "HAVE_FCHMOD",
14206#endif
14207
14208#ifdef HAVE_FCHMODAT
14209 "HAVE_FCHMODAT",
14210#endif
14211
14212#ifdef HAVE_FCHOWN
14213 "HAVE_FCHOWN",
14214#endif
14215
Larry Hastings00964ed2013-08-12 13:49:30 -040014216#ifdef HAVE_FCHOWNAT
14217 "HAVE_FCHOWNAT",
14218#endif
14219
Larry Hastings9cf065c2012-06-22 16:30:09 -070014220#ifdef HAVE_FEXECVE
14221 "HAVE_FEXECVE",
14222#endif
14223
14224#ifdef HAVE_FDOPENDIR
14225 "HAVE_FDOPENDIR",
14226#endif
14227
Georg Brandl306336b2012-06-24 12:55:33 +020014228#ifdef HAVE_FPATHCONF
14229 "HAVE_FPATHCONF",
14230#endif
14231
Larry Hastings9cf065c2012-06-22 16:30:09 -070014232#ifdef HAVE_FSTATAT
14233 "HAVE_FSTATAT",
14234#endif
14235
14236#ifdef HAVE_FSTATVFS
14237 "HAVE_FSTATVFS",
14238#endif
14239
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014240#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014241 "HAVE_FTRUNCATE",
14242#endif
14243
Larry Hastings9cf065c2012-06-22 16:30:09 -070014244#ifdef HAVE_FUTIMENS
14245 "HAVE_FUTIMENS",
14246#endif
14247
14248#ifdef HAVE_FUTIMES
14249 "HAVE_FUTIMES",
14250#endif
14251
14252#ifdef HAVE_FUTIMESAT
14253 "HAVE_FUTIMESAT",
14254#endif
14255
14256#ifdef HAVE_LINKAT
14257 "HAVE_LINKAT",
14258#endif
14259
14260#ifdef HAVE_LCHFLAGS
14261 "HAVE_LCHFLAGS",
14262#endif
14263
14264#ifdef HAVE_LCHMOD
14265 "HAVE_LCHMOD",
14266#endif
14267
14268#ifdef HAVE_LCHOWN
14269 "HAVE_LCHOWN",
14270#endif
14271
14272#ifdef HAVE_LSTAT
14273 "HAVE_LSTAT",
14274#endif
14275
14276#ifdef HAVE_LUTIMES
14277 "HAVE_LUTIMES",
14278#endif
14279
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014280#ifdef HAVE_MEMFD_CREATE
14281 "HAVE_MEMFD_CREATE",
14282#endif
14283
Larry Hastings9cf065c2012-06-22 16:30:09 -070014284#ifdef HAVE_MKDIRAT
14285 "HAVE_MKDIRAT",
14286#endif
14287
14288#ifdef HAVE_MKFIFOAT
14289 "HAVE_MKFIFOAT",
14290#endif
14291
14292#ifdef HAVE_MKNODAT
14293 "HAVE_MKNODAT",
14294#endif
14295
14296#ifdef HAVE_OPENAT
14297 "HAVE_OPENAT",
14298#endif
14299
14300#ifdef HAVE_READLINKAT
14301 "HAVE_READLINKAT",
14302#endif
14303
14304#ifdef HAVE_RENAMEAT
14305 "HAVE_RENAMEAT",
14306#endif
14307
14308#ifdef HAVE_SYMLINKAT
14309 "HAVE_SYMLINKAT",
14310#endif
14311
14312#ifdef HAVE_UNLINKAT
14313 "HAVE_UNLINKAT",
14314#endif
14315
14316#ifdef HAVE_UTIMENSAT
14317 "HAVE_UTIMENSAT",
14318#endif
14319
14320#ifdef MS_WINDOWS
14321 "MS_WINDOWS",
14322#endif
14323
14324 NULL
14325};
14326
14327
Mark Hammondfe51c6d2002-08-02 02:27:13 +000014328PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000014329INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014330{
Victor Stinner8c62be82010-05-06 00:08:46 +000014331 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014332 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014333 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000014334
Victor Stinner8c62be82010-05-06 00:08:46 +000014335 m = PyModule_Create(&posixmodule);
14336 if (m == NULL)
14337 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000014338
Victor Stinner8c62be82010-05-06 00:08:46 +000014339 /* Initialize environ dictionary */
14340 v = convertenviron();
14341 Py_XINCREF(v);
14342 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
14343 return NULL;
14344 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014345
Victor Stinner8c62be82010-05-06 00:08:46 +000014346 if (all_ins(m))
14347 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000014348
Victor Stinner8c62be82010-05-06 00:08:46 +000014349 if (setup_confname_tables(m))
14350 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000014351
Victor Stinner8c62be82010-05-06 00:08:46 +000014352 Py_INCREF(PyExc_OSError);
14353 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014354
Guido van Rossumb3d39562000-01-31 18:41:26 +000014355#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000014356 if (posix_putenv_garbage == NULL)
14357 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000014358#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000014359
Victor Stinner8c62be82010-05-06 00:08:46 +000014360 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020014361#if defined(HAVE_WAITID) && !defined(__APPLE__)
14362 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014363 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
14364 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014365 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014366 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014367#endif
14368
Christian Heimes25827622013-10-12 01:27:08 +020014369 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000014370 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14371 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14372 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014373 StatResultType = PyStructSequence_NewType(&stat_result_desc);
14374 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014375 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014376 }
14377 structseq_new = StatResultType->tp_new;
14378 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014379
Christian Heimes25827622013-10-12 01:27:08 +020014380 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014381 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
14382 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014383 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014384 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014385#ifdef NEED_TICKS_PER_SECOND
14386# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000014387 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014388# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000014389 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014390# else
Victor Stinner8c62be82010-05-06 00:08:46 +000014391 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014392# endif
14393#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014394
William Orr81574b82018-10-01 22:19:56 -070014395#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014396 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014397 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
14398 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014399 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014400 }
14401 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014402#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014403
14404 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014405 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
14406 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014407 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014408 }
Victor Stinner6036e442015-03-08 01:58:04 +010014409
14410 /* initialize scandir types */
14411 if (PyType_Ready(&ScandirIteratorType) < 0)
14412 return NULL;
14413 if (PyType_Ready(&DirEntryType) < 0)
14414 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014415 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014416#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014417 Py_INCREF((PyObject*) WaitidResultType);
14418 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020014419#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014420 Py_INCREF((PyObject*) StatResultType);
14421 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
14422 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000014423 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014424 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014425
14426#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014427 Py_INCREF(SchedParamType);
14428 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014429#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014430
Larry Hastings605a62d2012-06-24 04:33:36 -070014431 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014432 TimesResultType = PyStructSequence_NewType(&times_result_desc);
14433 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014434 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014435 }
14436 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014437
14438 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014439 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
14440 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014441 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014442 }
14443 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014444
Thomas Wouters477c8d52006-05-27 19:21:47 +000014445#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014446 /*
14447 * Step 2 of weak-linking support on Mac OS X.
14448 *
14449 * The code below removes functions that are not available on the
14450 * currently active platform.
14451 *
14452 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014453 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014454 * OSX 10.4.
14455 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014456#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014457 if (fstatvfs == NULL) {
14458 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14459 return NULL;
14460 }
14461 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014462#endif /* HAVE_FSTATVFS */
14463
14464#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014465 if (statvfs == NULL) {
14466 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14467 return NULL;
14468 }
14469 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014470#endif /* HAVE_STATVFS */
14471
14472# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014473 if (lchown == NULL) {
14474 if (PyObject_DelAttrString(m, "lchown") == -1) {
14475 return NULL;
14476 }
14477 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014478#endif /* HAVE_LCHOWN */
14479
14480
14481#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014482
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014483 Py_INCREF(TerminalSizeType);
14484 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014485
Larry Hastings6fe20b32012-04-19 15:07:49 -070014486 billion = PyLong_FromLong(1000000000);
14487 if (!billion)
14488 return NULL;
14489
Larry Hastings9cf065c2012-06-22 16:30:09 -070014490 /* suppress "function not used" warnings */
14491 {
14492 int ignored;
14493 fd_specified("", -1);
14494 follow_symlinks_specified("", 1);
14495 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14496 dir_fd_converter(Py_None, &ignored);
14497 dir_fd_unavailable(Py_None, &ignored);
14498 }
14499
14500 /*
14501 * provide list of locally available functions
14502 * so os.py can populate support_* lists
14503 */
14504 list = PyList_New(0);
14505 if (!list)
14506 return NULL;
14507 for (trace = have_functions; *trace; trace++) {
14508 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14509 if (!unicode)
14510 return NULL;
14511 if (PyList_Append(list, unicode))
14512 return NULL;
14513 Py_DECREF(unicode);
14514 }
14515 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014516
14517 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014518 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014519
14520 initialized = 1;
14521
Victor Stinner8c62be82010-05-06 00:08:46 +000014522 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014523}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014524
14525#ifdef __cplusplus
14526}
14527#endif