blob: e8dbdcc94aa701771547ac8506ffbeab24cb5143 [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"
Antoine Pitrou346cbd32017-05-27 17:50:54 +020028#include "pythread.h"
Victor Stinner6036e442015-03-08 01:58:04 +010029#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020030#ifndef MS_WINDOWS
31#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010032#else
33#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020034#endif
Victor Stinner621cebe2018-11-12 16:53:38 +010035#include "pycore_pystate.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000036
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020037/* On android API level 21, 'AT_EACCESS' is not declared although
38 * HAVE_FACCESSAT is defined. */
39#ifdef __ANDROID__
40#undef HAVE_FACCESSAT
41#endif
42
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000043#include <stdio.h> /* needed for ctermid() */
44
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000045#ifdef __cplusplus
46extern "C" {
47#endif
48
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000049PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000050"This module provides access to operating system functionality that is\n\
51standardized by the C Standard and the POSIX standard (a thinly\n\
52disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000053corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000055
Ross Lagerwall4d076da2011-03-18 06:56:53 +020056#ifdef HAVE_SYS_UIO_H
57#include <sys/uio.h>
58#endif
59
Christian Heimes75b96182017-09-05 15:53:09 +020060#ifdef HAVE_SYS_SYSMACROS_H
61/* GNU C Library: major(), minor(), makedev() */
62#include <sys/sysmacros.h>
63#endif
64
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000066#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000067#endif /* HAVE_SYS_TYPES_H */
68
69#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000070#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000071#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000072
Guido van Rossum36bc6801995-06-14 22:54:23 +000073#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000074#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000075#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000076
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000078#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000079#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000080
Guido van Rossumb6775db1994-08-01 11:34:53 +000081#ifdef HAVE_FCNTL_H
82#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000083#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000084
Guido van Rossuma6535fd2001-10-18 19:44:10 +000085#ifdef HAVE_GRP_H
86#include <grp.h>
87#endif
88
Barry Warsaw5676bd12003-01-07 20:57:09 +000089#ifdef HAVE_SYSEXITS_H
90#include <sysexits.h>
91#endif /* HAVE_SYSEXITS_H */
92
Anthony Baxter8a560de2004-10-13 15:30:56 +000093#ifdef HAVE_SYS_LOADAVG_H
94#include <sys/loadavg.h>
95#endif
96
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000097#ifdef HAVE_SYS_SENDFILE_H
98#include <sys/sendfile.h>
99#endif
100
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200101#if defined(__APPLE__)
102#include <copyfile.h>
103#endif
104
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500105#ifdef HAVE_SCHED_H
106#include <sched.h>
107#endif
108
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500109#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500110#undef HAVE_SCHED_SETAFFINITY
111#endif
112
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200113#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400114#define USE_XATTRS
115#endif
116
117#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400118#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400119#endif
120
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000121#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
122#ifdef HAVE_SYS_SOCKET_H
123#include <sys/socket.h>
124#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000125#endif
126
Victor Stinner8b905bd2011-10-25 13:34:04 +0200127#ifdef HAVE_DLFCN_H
128#include <dlfcn.h>
129#endif
130
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200131#ifdef __hpux
132#include <sys/mpctl.h>
133#endif
134
135#if defined(__DragonFly__) || \
136 defined(__OpenBSD__) || \
137 defined(__FreeBSD__) || \
138 defined(__NetBSD__) || \
139 defined(__APPLE__)
140#include <sys/sysctl.h>
141#endif
142
Victor Stinner9b1f4742016-09-06 16:18:52 -0700143#ifdef HAVE_LINUX_RANDOM_H
144# include <linux/random.h>
145#endif
146#ifdef HAVE_GETRANDOM_SYSCALL
147# include <sys/syscall.h>
148#endif
149
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100150#if defined(MS_WINDOWS)
151# define TERMSIZE_USE_CONIO
152#elif defined(HAVE_SYS_IOCTL_H)
153# include <sys/ioctl.h>
154# if defined(HAVE_TERMIOS_H)
155# include <termios.h>
156# endif
157# if defined(TIOCGWINSZ)
158# define TERMSIZE_USE_IOCTL
159# endif
160#endif /* MS_WINDOWS */
161
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000163/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000166#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000167#include <process.h>
168#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000169#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000170#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000171#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000172#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700174#define HAVE_WSPAWNV 1
175#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000177#define HAVE_SYSTEM 1
178#define HAVE_CWAIT 1
179#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000180#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000181#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182/* Unix functions that the configure script doesn't check for */
183#define HAVE_EXECV 1
184#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000185#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000186#define HAVE_FORK1 1
187#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#define HAVE_GETEGID 1
189#define HAVE_GETEUID 1
190#define HAVE_GETGID 1
191#define HAVE_GETPPID 1
192#define HAVE_GETUID 1
193#define HAVE_KILL 1
194#define HAVE_OPENDIR 1
195#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000196#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000197#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000198#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000199#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000200#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000201
Victor Stinnera2f7c002012-02-08 03:36:25 +0100202
Larry Hastings61272b72014-01-07 12:41:53 -0800203/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000204# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800205module os
Larry Hastings61272b72014-01-07 12:41:53 -0800206[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000207/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100208
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000210
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000211#if defined(__sgi)&&_COMPILER_VERSION>=700
212/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
213 (default) */
214extern char *ctermid_r(char *);
215#endif
216
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000217#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000219#ifdef HAVE_POSIX_SPAWN
220#include <spawn.h>
221#endif
222
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223#ifdef HAVE_UTIME_H
224#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000225#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000227#ifdef HAVE_SYS_UTIME_H
228#include <sys/utime.h>
229#define HAVE_UTIME_H /* pretend we do for the rest of this file */
230#endif /* HAVE_SYS_UTIME_H */
231
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#ifdef HAVE_SYS_TIMES_H
233#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000234#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235
236#ifdef HAVE_SYS_PARAM_H
237#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000238#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239
240#ifdef HAVE_SYS_UTSNAME_H
241#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000242#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#define NAMLEN(dirent) strlen((dirent)->d_name)
247#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000248#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#include <direct.h>
250#define NAMLEN(dirent) strlen((dirent)->d_name)
251#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000253#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000254#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000255#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000257#endif
258#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000260#endif
261#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000263#endif
264#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000266#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000267#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000269#endif
270#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000272#endif
273#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000275#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000276#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000277#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000278#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100279#ifndef IO_REPARSE_TAG_MOUNT_POINT
280#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
281#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000282#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000283#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000285#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000286#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000287#define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000289
Tim Petersbc2e10e2002-03-03 23:17:02 +0000290#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000291#if defined(PATH_MAX) && PATH_MAX > 1024
292#define MAXPATHLEN PATH_MAX
293#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000294#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000295#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000296#endif /* MAXPATHLEN */
297
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000298#ifdef UNION_WAIT
299/* Emulate some macros on systems that have a union instead of macros */
300
301#ifndef WIFEXITED
302#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
303#endif
304
305#ifndef WEXITSTATUS
306#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
307#endif
308
309#ifndef WTERMSIG
310#define WTERMSIG(u_wait) ((u_wait).w_termsig)
311#endif
312
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000313#define WAIT_TYPE union wait
314#define WAIT_STATUS_INT(s) (s.w_status)
315
316#else /* !UNION_WAIT */
317#define WAIT_TYPE int
318#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000319#endif /* UNION_WAIT */
320
Greg Wardb48bc172000-03-01 21:51:56 +0000321/* Don't use the "_r" form if we don't need it (also, won't have a
322 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200323#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000324#define USE_CTERMID_R
325#endif
326
Fred Drake699f3522000-06-29 21:12:41 +0000327/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000328#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000329#undef FSTAT
330#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200331#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000332# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700333# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200334# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800335# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000336#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000337# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700338# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000339# define FSTAT fstat
340# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000341#endif
342
Tim Peters11b23062003-04-23 02:39:17 +0000343#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000344#include <sys/mkdev.h>
345#else
346#if defined(MAJOR_IN_SYSMACROS)
347#include <sys/sysmacros.h>
348#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000349#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
350#include <sys/mkdev.h>
351#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000352#endif
Fred Drake699f3522000-06-29 21:12:41 +0000353
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200354#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100355#define INITFUNC PyInit_nt
356#define MODNAME "nt"
357#else
358#define INITFUNC PyInit_posix
359#define MODNAME "posix"
360#endif
361
jcea6c51d512018-01-28 14:00:08 +0100362#if defined(__sun)
363/* Something to implement in autoconf, not present in autoconf 2.69 */
364#define HAVE_STRUCT_STAT_ST_FSTYPE 1
365#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200366
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800367#ifdef _Py_MEMORY_SANITIZER
368# include <sanitizer/msan_interface.h>
369#endif
370
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200371#ifdef HAVE_FORK
372static void
373run_at_forkers(PyObject *lst, int reverse)
374{
375 Py_ssize_t i;
376 PyObject *cpy;
377
378 if (lst != NULL) {
379 assert(PyList_CheckExact(lst));
380
381 /* Use a list copy in case register_at_fork() is called from
382 * one of the callbacks.
383 */
384 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
385 if (cpy == NULL)
386 PyErr_WriteUnraisable(lst);
387 else {
388 if (reverse)
389 PyList_Reverse(cpy);
390 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
391 PyObject *func, *res;
392 func = PyList_GET_ITEM(cpy, i);
393 res = PyObject_CallObject(func, NULL);
394 if (res == NULL)
395 PyErr_WriteUnraisable(func);
396 else
397 Py_DECREF(res);
398 }
399 Py_DECREF(cpy);
400 }
401 }
402}
403
404void
405PyOS_BeforeFork(void)
406{
Victor Stinnercaba55b2018-08-03 15:33:52 +0200407 run_at_forkers(_PyInterpreterState_Get()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200408
409 _PyImport_AcquireLock();
410}
411
412void
413PyOS_AfterFork_Parent(void)
414{
415 if (_PyImport_ReleaseLock() <= 0)
416 Py_FatalError("failed releasing import lock after fork");
417
Victor Stinnercaba55b2018-08-03 15:33:52 +0200418 run_at_forkers(_PyInterpreterState_Get()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200419}
420
421void
422PyOS_AfterFork_Child(void)
423{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200424 _PyGILState_Reinit();
Eric Snow59032962018-09-14 14:17:20 -0700425 _PyInterpreterState_DeleteExceptMain();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200426 PyEval_ReInitThreads();
427 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200428 _PySignal_AfterFork();
Eric Snow8479a342019-03-08 23:44:33 -0700429 _PyRuntimeState_ReInitThreads();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200430
Victor Stinnercaba55b2018-08-03 15:33:52 +0200431 run_at_forkers(_PyInterpreterState_Get()->after_forkers_child, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200432}
433
434static int
435register_at_forker(PyObject **lst, PyObject *func)
436{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700437 if (func == NULL) /* nothing to register? do nothing. */
438 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200439 if (*lst == NULL) {
440 *lst = PyList_New(0);
441 if (*lst == NULL)
442 return -1;
443 }
444 return PyList_Append(*lst, func);
445}
446#endif
447
448/* Legacy wrapper */
449void
450PyOS_AfterFork(void)
451{
452#ifdef HAVE_FORK
453 PyOS_AfterFork_Child();
454#endif
455}
456
457
Victor Stinner6036e442015-03-08 01:58:04 +0100458#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200459/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700460void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
461void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200462 ULONG, struct _Py_stat_struct *);
463#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700464
465#ifdef MS_WINDOWS
466static int
467win32_warn_bytes_api()
468{
469 return PyErr_WarnEx(PyExc_DeprecationWarning,
470 "The Windows bytes API has been deprecated, "
471 "use Unicode filenames instead",
472 1);
473}
474#endif
475
476
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200477#ifndef MS_WINDOWS
478PyObject *
479_PyLong_FromUid(uid_t uid)
480{
481 if (uid == (uid_t)-1)
482 return PyLong_FromLong(-1);
483 return PyLong_FromUnsignedLong(uid);
484}
485
486PyObject *
487_PyLong_FromGid(gid_t gid)
488{
489 if (gid == (gid_t)-1)
490 return PyLong_FromLong(-1);
491 return PyLong_FromUnsignedLong(gid);
492}
493
494int
495_Py_Uid_Converter(PyObject *obj, void *p)
496{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700497 uid_t uid;
498 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200499 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200500 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700501 unsigned long uresult;
502
503 index = PyNumber_Index(obj);
504 if (index == NULL) {
505 PyErr_Format(PyExc_TypeError,
506 "uid should be integer, not %.200s",
507 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200508 return 0;
509 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700510
511 /*
512 * Handling uid_t is complicated for two reasons:
513 * * Although uid_t is (always?) unsigned, it still
514 * accepts -1.
515 * * We don't know its size in advance--it may be
516 * bigger than an int, or it may be smaller than
517 * a long.
518 *
519 * So a bit of defensive programming is in order.
520 * Start with interpreting the value passed
521 * in as a signed long and see if it works.
522 */
523
524 result = PyLong_AsLongAndOverflow(index, &overflow);
525
526 if (!overflow) {
527 uid = (uid_t)result;
528
529 if (result == -1) {
530 if (PyErr_Occurred())
531 goto fail;
532 /* It's a legitimate -1, we're done. */
533 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200534 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700535
536 /* Any other negative number is disallowed. */
537 if (result < 0)
538 goto underflow;
539
540 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200541 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700542 (long)uid != result)
543 goto underflow;
544 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200545 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700546
547 if (overflow < 0)
548 goto underflow;
549
550 /*
551 * Okay, the value overflowed a signed long. If it
552 * fits in an *unsigned* long, it may still be okay,
553 * as uid_t may be unsigned long on this platform.
554 */
555 uresult = PyLong_AsUnsignedLong(index);
556 if (PyErr_Occurred()) {
557 if (PyErr_ExceptionMatches(PyExc_OverflowError))
558 goto overflow;
559 goto fail;
560 }
561
562 uid = (uid_t)uresult;
563
564 /*
565 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
566 * but this value would get interpreted as (uid_t)-1 by chown
567 * and its siblings. That's not what the user meant! So we
568 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100569 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700570 */
571 if (uid == (uid_t)-1)
572 goto overflow;
573
574 /* Ensure the value wasn't truncated. */
575 if (sizeof(uid_t) < sizeof(long) &&
576 (unsigned long)uid != uresult)
577 goto overflow;
578 /* fallthrough */
579
580success:
581 Py_DECREF(index);
582 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200583 return 1;
584
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700585underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200586 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700587 "uid is less than minimum");
588 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200589
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700590overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200591 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700592 "uid is greater than maximum");
593 /* fallthrough */
594
595fail:
596 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200597 return 0;
598}
599
600int
601_Py_Gid_Converter(PyObject *obj, void *p)
602{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700603 gid_t gid;
604 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200605 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200606 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700607 unsigned long uresult;
608
609 index = PyNumber_Index(obj);
610 if (index == NULL) {
611 PyErr_Format(PyExc_TypeError,
612 "gid should be integer, not %.200s",
613 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200614 return 0;
615 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616
617 /*
618 * Handling gid_t is complicated for two reasons:
619 * * Although gid_t is (always?) unsigned, it still
620 * accepts -1.
621 * * We don't know its size in advance--it may be
622 * bigger than an int, or it may be smaller than
623 * a long.
624 *
625 * So a bit of defensive programming is in order.
626 * Start with interpreting the value passed
627 * in as a signed long and see if it works.
628 */
629
630 result = PyLong_AsLongAndOverflow(index, &overflow);
631
632 if (!overflow) {
633 gid = (gid_t)result;
634
635 if (result == -1) {
636 if (PyErr_Occurred())
637 goto fail;
638 /* It's a legitimate -1, we're done. */
639 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200640 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700641
642 /* Any other negative number is disallowed. */
643 if (result < 0) {
644 goto underflow;
645 }
646
647 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200648 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700649 (long)gid != result)
650 goto underflow;
651 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200652 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700653
654 if (overflow < 0)
655 goto underflow;
656
657 /*
658 * Okay, the value overflowed a signed long. If it
659 * fits in an *unsigned* long, it may still be okay,
660 * as gid_t may be unsigned long on this platform.
661 */
662 uresult = PyLong_AsUnsignedLong(index);
663 if (PyErr_Occurred()) {
664 if (PyErr_ExceptionMatches(PyExc_OverflowError))
665 goto overflow;
666 goto fail;
667 }
668
669 gid = (gid_t)uresult;
670
671 /*
672 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
673 * but this value would get interpreted as (gid_t)-1 by chown
674 * and its siblings. That's not what the user meant! So we
675 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100676 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700677 */
678 if (gid == (gid_t)-1)
679 goto overflow;
680
681 /* Ensure the value wasn't truncated. */
682 if (sizeof(gid_t) < sizeof(long) &&
683 (unsigned long)gid != uresult)
684 goto overflow;
685 /* fallthrough */
686
687success:
688 Py_DECREF(index);
689 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200690 return 1;
691
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700692underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200693 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700694 "gid is less than minimum");
695 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200696
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700697overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200698 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700699 "gid is greater than maximum");
700 /* fallthrough */
701
702fail:
703 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200704 return 0;
705}
706#endif /* MS_WINDOWS */
707
708
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700709#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800710
711
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200712#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
713static int
714_Py_Dev_Converter(PyObject *obj, void *p)
715{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200716 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200717 if (PyErr_Occurred())
718 return 0;
719 return 1;
720}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800721#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200722
723
Larry Hastings9cf065c2012-06-22 16:30:09 -0700724#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400725/*
726 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
727 * without the int cast, the value gets interpreted as uint (4291925331),
728 * which doesn't play nicely with all the initializer lines in this file that
729 * look like this:
730 * int dir_fd = DEFAULT_DIR_FD;
731 */
732#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700733#else
734#define DEFAULT_DIR_FD (-100)
735#endif
736
737static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300738_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200739{
740 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700741 long long_value;
742
743 PyObject *index = PyNumber_Index(o);
744 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700745 return 0;
746 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700747
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300748 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700749 long_value = PyLong_AsLongAndOverflow(index, &overflow);
750 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300751 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200752 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700753 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700754 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700755 return 0;
756 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200757 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700758 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700759 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700760 return 0;
761 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700762
Larry Hastings9cf065c2012-06-22 16:30:09 -0700763 *p = (int)long_value;
764 return 1;
765}
766
767static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200768dir_fd_converter(PyObject *o, void *p)
769{
770 if (o == Py_None) {
771 *(int *)p = DEFAULT_DIR_FD;
772 return 1;
773 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300774 else if (PyIndex_Check(o)) {
775 return _fd_converter(o, (int *)p);
776 }
777 else {
778 PyErr_Format(PyExc_TypeError,
779 "argument should be integer or None, not %.200s",
780 Py_TYPE(o)->tp_name);
781 return 0;
782 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700783}
784
785
Larry Hastings9cf065c2012-06-22 16:30:09 -0700786/*
787 * A PyArg_ParseTuple "converter" function
788 * that handles filesystem paths in the manner
789 * preferred by the os module.
790 *
791 * path_converter accepts (Unicode) strings and their
792 * subclasses, and bytes and their subclasses. What
793 * it does with the argument depends on the platform:
794 *
795 * * On Windows, if we get a (Unicode) string we
796 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700797 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700798 *
799 * * On all other platforms, strings are encoded
800 * to bytes using PyUnicode_FSConverter, then we
801 * extract the char * from the bytes object and
802 * return that.
803 *
804 * path_converter also optionally accepts signed
805 * integers (representing open file descriptors) instead
806 * of path strings.
807 *
808 * Input fields:
809 * path.nullable
810 * If nonzero, the path is permitted to be None.
811 * path.allow_fd
812 * If nonzero, the path is permitted to be a file handle
813 * (a signed int) instead of a string.
814 * path.function_name
815 * If non-NULL, path_converter will use that as the name
816 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700817 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700818 * path.argument_name
819 * If non-NULL, path_converter will use that as the name
820 * of the parameter in error messages.
821 * (If path.argument_name is NULL it uses "path".)
822 *
823 * Output fields:
824 * path.wide
825 * Points to the path if it was expressed as Unicode
826 * and was not encoded. (Only used on Windows.)
827 * path.narrow
828 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700829 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000830 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700831 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700832 * path.fd
833 * Contains a file descriptor if path.accept_fd was true
834 * and the caller provided a signed integer instead of any
835 * sort of string.
836 *
837 * WARNING: if your "path" parameter is optional, and is
838 * unspecified, path_converter will never get called.
839 * So if you set allow_fd, you *MUST* initialize path.fd = -1
840 * yourself!
841 * path.length
842 * The length of the path in characters, if specified as
843 * a string.
844 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800845 * The original object passed in (if get a PathLike object,
846 * the result of PyOS_FSPath() is treated as the original object).
847 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700848 * path.cleanup
849 * For internal use only. May point to a temporary object.
850 * (Pay no attention to the man behind the curtain.)
851 *
852 * At most one of path.wide or path.narrow will be non-NULL.
853 * If path was None and path.nullable was set,
854 * or if path was an integer and path.allow_fd was set,
855 * both path.wide and path.narrow will be NULL
856 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200857 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700858 * path_converter takes care to not write to the path_t
859 * unless it's successful. However it must reset the
860 * "cleanup" field each time it's called.
861 *
862 * Use as follows:
863 * path_t path;
864 * memset(&path, 0, sizeof(path));
865 * PyArg_ParseTuple(args, "O&", path_converter, &path);
866 * // ... use values from path ...
867 * path_cleanup(&path);
868 *
869 * (Note that if PyArg_Parse fails you don't need to call
870 * path_cleanup(). However it is safe to do so.)
871 */
872typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100873 const char *function_name;
874 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700875 int nullable;
876 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300877 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700878#ifdef MS_WINDOWS
879 BOOL narrow;
880#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300881 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700882#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700883 int fd;
884 Py_ssize_t length;
885 PyObject *object;
886 PyObject *cleanup;
887} path_t;
888
Steve Dowercc16be82016-09-08 10:35:16 -0700889#ifdef MS_WINDOWS
890#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
891 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
892#else
Larry Hastings2f936352014-08-05 14:04:04 +1000893#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
894 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700895#endif
Larry Hastings31826802013-10-19 00:09:25 -0700896
Larry Hastings9cf065c2012-06-22 16:30:09 -0700897static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800898path_cleanup(path_t *path)
899{
900 Py_CLEAR(path->object);
901 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700902}
903
904static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300905path_converter(PyObject *o, void *p)
906{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700907 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800908 PyObject *bytes = NULL;
909 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700910 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300911 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700912#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800913 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700914 const wchar_t *wide;
915#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700916
917#define FORMAT_EXCEPTION(exc, fmt) \
918 PyErr_Format(exc, "%s%s" fmt, \
919 path->function_name ? path->function_name : "", \
920 path->function_name ? ": " : "", \
921 path->argument_name ? path->argument_name : "path")
922
923 /* Py_CLEANUP_SUPPORTED support */
924 if (o == NULL) {
925 path_cleanup(path);
926 return 1;
927 }
928
Brett Cannon3f9183b2016-08-26 14:44:48 -0700929 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800930 path->object = path->cleanup = NULL;
931 /* path->object owns a reference to the original object */
932 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300934 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700936#ifdef MS_WINDOWS
937 path->narrow = FALSE;
938#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700939 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700940#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800942 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943 }
944
Brett Cannon3f9183b2016-08-26 14:44:48 -0700945 /* Only call this here so that we don't treat the return value of
946 os.fspath() as an fd or buffer. */
947 is_index = path->allow_fd && PyIndex_Check(o);
948 is_buffer = PyObject_CheckBuffer(o);
949 is_bytes = PyBytes_Check(o);
950 is_unicode = PyUnicode_Check(o);
951
952 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
953 /* Inline PyOS_FSPath() for better error messages. */
954 _Py_IDENTIFIER(__fspath__);
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000955 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700956
957 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
958 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800959 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700960 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000961 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700962 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000963 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700964 goto error_exit;
965 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000966 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700967 is_unicode = 1;
968 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000969 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700970 is_bytes = 1;
971 }
972 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000973 PyErr_Format(PyExc_TypeError,
974 "expected %.200s.__fspath__() to return str or bytes, "
975 "not %.200s", Py_TYPE(o)->tp_name,
976 Py_TYPE(res)->tp_name);
977 Py_DECREF(res);
978 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700979 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000980
981 /* still owns a reference to the original object */
982 Py_DECREF(o);
983 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700984 }
985
986 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700987#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +0200988 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100989 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800990 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700991 }
Victor Stinner59799a82013-11-13 14:17:30 +0100992 if (length > 32767) {
993 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +0800994 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700995 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300996 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300997 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +0800998 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300999 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001000
1001 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001002 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001003 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001004 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001005#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001006 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001007 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001008 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001009#endif
1010 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001011 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001012 bytes = o;
1013 Py_INCREF(bytes);
1014 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001015 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001016 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001017 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001018 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1019 "%s%s%s should be %s, not %.200s",
1020 path->function_name ? path->function_name : "",
1021 path->function_name ? ": " : "",
1022 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001023 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1024 "integer or None" :
1025 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1026 path->nullable ? "string, bytes, os.PathLike or None" :
1027 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001028 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001029 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001030 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001031 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001032 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001033 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001034 }
1035 }
Steve Dowercc16be82016-09-08 10:35:16 -07001036 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001037 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001038 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001039 }
1040 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001041#ifdef MS_WINDOWS
1042 path->narrow = FALSE;
1043#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001044 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001045#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001046 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001047 }
1048 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001049 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001050 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1051 path->function_name ? path->function_name : "",
1052 path->function_name ? ": " : "",
1053 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001054 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1055 "integer or None" :
1056 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1057 path->nullable ? "string, bytes, os.PathLike or None" :
1058 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001059 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001060 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001061 }
1062
Larry Hastings9cf065c2012-06-22 16:30:09 -07001063 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001064 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001065 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001066 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001067 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001068 }
1069
Steve Dowercc16be82016-09-08 10:35:16 -07001070#ifdef MS_WINDOWS
1071 wo = PyUnicode_DecodeFSDefaultAndSize(
1072 narrow,
1073 length
1074 );
1075 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001076 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001077 }
1078
Xiang Zhang04316c42017-01-08 23:26:57 +08001079 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001080 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001081 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001082 }
1083 if (length > 32767) {
1084 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001085 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001086 }
1087 if (wcslen(wide) != length) {
1088 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001089 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001090 }
1091 path->wide = wide;
1092 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001093 path->cleanup = wo;
1094 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001095#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001096 path->wide = NULL;
1097 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001098 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001099 /* Still a reference owned by path->object, don't have to
1100 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001101 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001102 }
1103 else {
1104 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001105 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001106#endif
1107 path->fd = -1;
1108
1109 success_exit:
1110 path->length = length;
1111 path->object = o;
1112 return Py_CLEANUP_SUPPORTED;
1113
1114 error_exit:
1115 Py_XDECREF(o);
1116 Py_XDECREF(bytes);
1117#ifdef MS_WINDOWS
1118 Py_XDECREF(wo);
1119#endif
1120 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001121}
1122
1123static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001124argument_unavailable_error(const char *function_name, const char *argument_name)
1125{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001126 PyErr_Format(PyExc_NotImplementedError,
1127 "%s%s%s unavailable on this platform",
1128 (function_name != NULL) ? function_name : "",
1129 (function_name != NULL) ? ": ": "",
1130 argument_name);
1131}
1132
1133static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001134dir_fd_unavailable(PyObject *o, void *p)
1135{
1136 int dir_fd;
1137 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001138 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001139 if (dir_fd != DEFAULT_DIR_FD) {
1140 argument_unavailable_error(NULL, "dir_fd");
1141 return 0;
1142 }
1143 *(int *)p = dir_fd;
1144 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001145}
1146
1147static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001148fd_specified(const char *function_name, int fd)
1149{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001150 if (fd == -1)
1151 return 0;
1152
1153 argument_unavailable_error(function_name, "fd");
1154 return 1;
1155}
1156
1157static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001158follow_symlinks_specified(const char *function_name, int follow_symlinks)
1159{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001160 if (follow_symlinks)
1161 return 0;
1162
1163 argument_unavailable_error(function_name, "follow_symlinks");
1164 return 1;
1165}
1166
1167static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001168path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1169{
Steve Dowercc16be82016-09-08 10:35:16 -07001170 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1171#ifndef MS_WINDOWS
1172 && !path->narrow
1173#endif
1174 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001175 PyErr_Format(PyExc_ValueError,
1176 "%s: can't specify dir_fd without matching path",
1177 function_name);
1178 return 1;
1179 }
1180 return 0;
1181}
1182
1183static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001184dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1185{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001186 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1187 PyErr_Format(PyExc_ValueError,
1188 "%s: can't specify both dir_fd and fd",
1189 function_name);
1190 return 1;
1191 }
1192 return 0;
1193}
1194
1195static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001196fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1197 int follow_symlinks)
1198{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001199 if ((fd > 0) && (!follow_symlinks)) {
1200 PyErr_Format(PyExc_ValueError,
1201 "%s: cannot use fd and follow_symlinks together",
1202 function_name);
1203 return 1;
1204 }
1205 return 0;
1206}
1207
1208static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001209dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1210 int follow_symlinks)
1211{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001212 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1213 PyErr_Format(PyExc_ValueError,
1214 "%s: cannot use dir_fd and follow_symlinks together",
1215 function_name);
1216 return 1;
1217 }
1218 return 0;
1219}
1220
Larry Hastings2f936352014-08-05 14:04:04 +10001221#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001222 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001223#else
Larry Hastings2f936352014-08-05 14:04:04 +10001224 typedef off_t Py_off_t;
1225#endif
1226
1227static int
1228Py_off_t_converter(PyObject *arg, void *addr)
1229{
1230#ifdef HAVE_LARGEFILE_SUPPORT
1231 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1232#else
1233 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001234#endif
1235 if (PyErr_Occurred())
1236 return 0;
1237 return 1;
1238}
Larry Hastings2f936352014-08-05 14:04:04 +10001239
1240static PyObject *
1241PyLong_FromPy_off_t(Py_off_t offset)
1242{
1243#ifdef HAVE_LARGEFILE_SUPPORT
1244 return PyLong_FromLongLong(offset);
1245#else
1246 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001247#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001248}
1249
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001250#ifdef HAVE_SIGSET_T
1251/* Convert an iterable of integers to a sigset.
1252 Return 1 on success, return 0 and raise an exception on error. */
1253int
1254_Py_Sigset_Converter(PyObject *obj, void *addr)
1255{
1256 sigset_t *mask = (sigset_t *)addr;
1257 PyObject *iterator, *item;
1258 long signum;
1259 int overflow;
1260
1261 if (sigemptyset(mask)) {
1262 /* Probably only if mask == NULL. */
1263 PyErr_SetFromErrno(PyExc_OSError);
1264 return 0;
1265 }
1266
1267 iterator = PyObject_GetIter(obj);
1268 if (iterator == NULL) {
1269 return 0;
1270 }
1271
1272 while ((item = PyIter_Next(iterator)) != NULL) {
1273 signum = PyLong_AsLongAndOverflow(item, &overflow);
1274 Py_DECREF(item);
1275 if (signum <= 0 || signum >= NSIG) {
1276 if (overflow || signum != -1 || !PyErr_Occurred()) {
1277 PyErr_Format(PyExc_ValueError,
1278 "signal number %ld out of range", signum);
1279 }
1280 goto error;
1281 }
1282 if (sigaddset(mask, (int)signum)) {
1283 if (errno != EINVAL) {
1284 /* Probably impossible */
1285 PyErr_SetFromErrno(PyExc_OSError);
1286 goto error;
1287 }
1288 /* For backwards compatibility, allow idioms such as
1289 * `range(1, NSIG)` but warn about invalid signal numbers
1290 */
1291 const char msg[] =
1292 "invalid signal number %ld, please use valid_signals()";
1293 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1294 goto error;
1295 }
1296 }
1297 }
1298 if (!PyErr_Occurred()) {
1299 Py_DECREF(iterator);
1300 return 1;
1301 }
1302
1303error:
1304 Py_DECREF(iterator);
1305 return 0;
1306}
1307#endif /* HAVE_SIGSET_T */
1308
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001309#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001310
1311static int
Brian Curtind25aef52011-06-13 15:16:04 -05001312win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001313{
Martin Panter70214ad2016-08-04 02:38:59 +00001314 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1315 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001316 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001317
1318 if (0 == DeviceIoControl(
1319 reparse_point_handle,
1320 FSCTL_GET_REPARSE_POINT,
1321 NULL, 0, /* in buffer */
1322 target_buffer, sizeof(target_buffer),
1323 &n_bytes_returned,
1324 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001325 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001326
1327 if (reparse_tag)
1328 *reparse_tag = rdb->ReparseTag;
1329
Brian Curtind25aef52011-06-13 15:16:04 -05001330 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001331}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001332
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001333#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001334
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001335/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001336#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001337/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001338** environ directly, we must obtain it with _NSGetEnviron(). See also
1339** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001340*/
1341#include <crt_externs.h>
1342static char **environ;
1343#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001345#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001346
Barry Warsaw53699e91996-12-10 23:23:01 +00001347static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001348convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001349{
Victor Stinner8c62be82010-05-06 00:08:46 +00001350 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001351#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001352 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001353#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001354 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001355#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001356
Victor Stinner8c62be82010-05-06 00:08:46 +00001357 d = PyDict_New();
1358 if (d == NULL)
1359 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001360#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001361 if (environ == NULL)
1362 environ = *_NSGetEnviron();
1363#endif
1364#ifdef MS_WINDOWS
1365 /* _wenviron must be initialized in this way if the program is started
1366 through main() instead of wmain(). */
1367 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001368 e = _wenviron;
Victor Stinner8c62be82010-05-06 00:08:46 +00001369#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001370 e = environ;
1371#endif
1372 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001373 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001374 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001375 PyObject *k;
1376 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001377#ifdef MS_WINDOWS
1378 const wchar_t *p = wcschr(*e, L'=');
1379#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001380 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001381#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001382 if (p == NULL)
1383 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001384#ifdef MS_WINDOWS
1385 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1386#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001387 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001388#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001390 Py_DECREF(d);
1391 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001392 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001393#ifdef MS_WINDOWS
1394 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1395#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001396 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001397#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001398 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001399 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001400 Py_DECREF(d);
1401 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001402 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001403 if (PyDict_GetItemWithError(d, k) == NULL) {
1404 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1405 Py_DECREF(v);
1406 Py_DECREF(k);
1407 Py_DECREF(d);
1408 return NULL;
1409 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001410 }
1411 Py_DECREF(k);
1412 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001413 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001414 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001415}
1416
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001417/* Set a POSIX-specific error from errno, and return NULL */
1418
Barry Warsawd58d7641998-07-23 16:14:40 +00001419static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001420posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001421{
Victor Stinner8c62be82010-05-06 00:08:46 +00001422 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001423}
Mark Hammondef8b6542001-05-13 08:04:26 +00001424
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001425#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001426static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001427win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001428{
Victor Stinner8c62be82010-05-06 00:08:46 +00001429 /* XXX We should pass the function name along in the future.
1430 (winreg.c also wants to pass the function name.)
1431 This would however require an additional param to the
1432 Windows error object, which is non-trivial.
1433 */
1434 errno = GetLastError();
1435 if (filename)
1436 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1437 else
1438 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001439}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001440
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001441static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001442win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001443{
1444 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001445 if (filename)
1446 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001447 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001448 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001449 filename);
1450 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001451 return PyErr_SetFromWindowsErr(err);
1452}
1453
1454static PyObject *
1455win32_error_object(const char* function, PyObject* filename)
1456{
1457 errno = GetLastError();
1458 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001459}
1460
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001461#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001462
Larry Hastings9cf065c2012-06-22 16:30:09 -07001463static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001464posix_path_object_error(PyObject *path)
1465{
1466 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1467}
1468
1469static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001470path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001471{
1472#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001473 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1474 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001475#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001476 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001477#endif
1478}
1479
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001480static PyObject *
1481path_object_error2(PyObject *path, PyObject *path2)
1482{
1483#ifdef MS_WINDOWS
1484 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1485 PyExc_OSError, 0, path, path2);
1486#else
1487 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1488#endif
1489}
1490
1491static PyObject *
1492path_error(path_t *path)
1493{
1494 return path_object_error(path->object);
1495}
Larry Hastings31826802013-10-19 00:09:25 -07001496
Larry Hastingsb0827312014-02-09 22:05:19 -08001497static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001498posix_path_error(path_t *path)
1499{
1500 return posix_path_object_error(path->object);
1501}
1502
1503static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001504path_error2(path_t *path, path_t *path2)
1505{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001506 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001507}
1508
1509
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001510/* POSIX generic methods */
1511
Larry Hastings2f936352014-08-05 14:04:04 +10001512static int
1513fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001514{
Victor Stinner8c62be82010-05-06 00:08:46 +00001515 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001516 int *pointer = (int *)p;
1517 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001518 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001519 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001520 *pointer = fd;
1521 return 1;
1522}
1523
1524static PyObject *
1525posix_fildes_fd(int fd, int (*func)(int))
1526{
1527 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001528 int async_err = 0;
1529
1530 do {
1531 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001532 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001533 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001534 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001535 Py_END_ALLOW_THREADS
1536 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1537 if (res != 0)
1538 return (!async_err) ? posix_error() : NULL;
1539 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001540}
Guido van Rossum21142a01999-01-08 21:05:37 +00001541
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001542
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001543#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544/* This is a reimplementation of the C library's chdir function,
1545 but one that produces Win32 errors instead of DOS error codes.
1546 chdir is essentially a wrapper around SetCurrentDirectory; however,
1547 it also needs to set "magic" environment variables indicating
1548 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001549static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001550win32_wchdir(LPCWSTR path)
1551{
Victor Stinnered537822015-12-13 21:40:26 +01001552 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001553 int result;
1554 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001555
Victor Stinner8c62be82010-05-06 00:08:46 +00001556 if(!SetCurrentDirectoryW(path))
1557 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001558 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001559 if (!result)
1560 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001561 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001562 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001563 if (!new_path) {
1564 SetLastError(ERROR_OUTOFMEMORY);
1565 return FALSE;
1566 }
1567 result = GetCurrentDirectoryW(result, new_path);
1568 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001569 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001570 return FALSE;
1571 }
1572 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001573 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1574 wcsncmp(new_path, L"//", 2) == 0);
1575 if (!is_unc_like_path) {
1576 env[1] = new_path[0];
1577 result = SetEnvironmentVariableW(env, new_path);
1578 }
Victor Stinnered537822015-12-13 21:40:26 +01001579 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001580 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001581 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001582}
1583#endif
1584
Martin v. Löwis14694662006-02-03 12:54:16 +00001585#ifdef MS_WINDOWS
1586/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1587 - time stamps are restricted to second resolution
1588 - file modification times suffer from forth-and-back conversions between
1589 UTC and local time
1590 Therefore, we implement our own stat, based on the Win32 API directly.
1591*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001592#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001593#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001594
Victor Stinner6036e442015-03-08 01:58:04 +01001595static void
Steve Dowercc16be82016-09-08 10:35:16 -07001596find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1597 BY_HANDLE_FILE_INFORMATION *info,
1598 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001599{
1600 memset(info, 0, sizeof(*info));
1601 info->dwFileAttributes = pFileData->dwFileAttributes;
1602 info->ftCreationTime = pFileData->ftCreationTime;
1603 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1604 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1605 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1606 info->nFileSizeLow = pFileData->nFileSizeLow;
1607/* info->nNumberOfLinks = 1; */
1608 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1609 *reparse_tag = pFileData->dwReserved0;
1610 else
1611 *reparse_tag = 0;
1612}
1613
Guido van Rossumd8faa362007-04-27 19:54:29 +00001614static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001615attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001616{
Victor Stinner8c62be82010-05-06 00:08:46 +00001617 HANDLE hFindFile;
1618 WIN32_FIND_DATAW FileData;
1619 hFindFile = FindFirstFileW(pszFile, &FileData);
1620 if (hFindFile == INVALID_HANDLE_VALUE)
1621 return FALSE;
1622 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001623 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001624 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001625}
1626
Brian Curtind25aef52011-06-13 15:16:04 -05001627static BOOL
1628get_target_path(HANDLE hdl, wchar_t **target_path)
1629{
1630 int buf_size, result_length;
1631 wchar_t *buf;
1632
1633 /* We have a good handle to the target, use it to determine
1634 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001635 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1636 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001637 if(!buf_size)
1638 return FALSE;
1639
Victor Stinnerc36674a2016-03-16 14:30:16 +01001640 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001641 if (!buf) {
1642 SetLastError(ERROR_OUTOFMEMORY);
1643 return FALSE;
1644 }
1645
Steve Dower2ea51c92015-03-20 21:49:12 -07001646 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001647 buf, buf_size, VOLUME_NAME_DOS);
1648
1649 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001650 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001651 return FALSE;
1652 }
1653
Brian Curtind25aef52011-06-13 15:16:04 -05001654 buf[result_length] = 0;
1655
1656 *target_path = buf;
1657 return TRUE;
1658}
1659
1660static int
Steve Dowercc16be82016-09-08 10:35:16 -07001661win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001662 BOOL traverse)
1663{
Victor Stinner26de69d2011-06-17 15:15:38 +02001664 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001665 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001666 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001667 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001668 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001669 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001670
Steve Dowercc16be82016-09-08 10:35:16 -07001671 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001672 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001673 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001674 0, /* share mode */
1675 NULL, /* security attributes */
1676 OPEN_EXISTING,
1677 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001678 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1679 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001680 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001681 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1682 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001683 NULL);
1684
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001685 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001686 /* Either the target doesn't exist, or we don't have access to
1687 get a handle to it. If the former, we need to return an error.
1688 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001689 DWORD lastError = GetLastError();
1690 if (lastError != ERROR_ACCESS_DENIED &&
1691 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001692 return -1;
1693 /* Could not get attributes on open file. Fall back to
1694 reading the directory. */
1695 if (!attributes_from_dir(path, &info, &reparse_tag))
1696 /* Very strange. This should not fail now */
1697 return -1;
1698 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1699 if (traverse) {
1700 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001701 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001702 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001703 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001704 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001705 } else {
1706 if (!GetFileInformationByHandle(hFile, &info)) {
1707 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001708 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 }
1710 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Mark Becwarb82bfac2019-02-02 16:08:23 -05001711 if (!win32_get_reparse_tag(hFile, &reparse_tag)) {
1712 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001713 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001714 }
Brian Curtind25aef52011-06-13 15:16:04 -05001715 /* Close the outer open file handle now that we're about to
1716 reopen it with different flags. */
1717 if (!CloseHandle(hFile))
1718 return -1;
1719
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001720 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001721 /* In order to call GetFinalPathNameByHandle we need to open
1722 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001723 hFile2 = CreateFileW(
1724 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1725 NULL, OPEN_EXISTING,
1726 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1727 NULL);
1728 if (hFile2 == INVALID_HANDLE_VALUE)
1729 return -1;
1730
Mark Becwarb82bfac2019-02-02 16:08:23 -05001731 if (!get_target_path(hFile2, &target_path)) {
1732 CloseHandle(hFile2);
Brian Curtind25aef52011-06-13 15:16:04 -05001733 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001734 }
1735
1736 if (!CloseHandle(hFile2)) {
1737 return -1;
1738 }
Brian Curtind25aef52011-06-13 15:16:04 -05001739
Steve Dowercc16be82016-09-08 10:35:16 -07001740 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001741 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001742 return code;
1743 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001744 } else
1745 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001746 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001747 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001748
1749 /* Set S_IEXEC if it is an .exe, .bat, ... */
1750 dot = wcsrchr(path, '.');
1751 if (dot) {
1752 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1753 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1754 result->st_mode |= 0111;
1755 }
1756 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001757}
1758
1759static int
Steve Dowercc16be82016-09-08 10:35:16 -07001760win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001761{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001762 /* Protocol violation: we explicitly clear errno, instead of
1763 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001764 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001765 errno = 0;
1766 return code;
1767}
Brian Curtind25aef52011-06-13 15:16:04 -05001768/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001769
1770 In Posix, stat automatically traverses symlinks and returns the stat
1771 structure for the target. In Windows, the equivalent GetFileAttributes by
1772 default does not traverse symlinks and instead returns attributes for
1773 the symlink.
1774
1775 Therefore, win32_lstat will get the attributes traditionally, and
1776 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001777 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001778
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001779static int
Steve Dowercc16be82016-09-08 10:35:16 -07001780win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001781{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001782 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001783}
1784
Victor Stinner8c62be82010-05-06 00:08:46 +00001785static int
Steve Dowercc16be82016-09-08 10:35:16 -07001786win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001787{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001788 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001789}
1790
Martin v. Löwis14694662006-02-03 12:54:16 +00001791#endif /* MS_WINDOWS */
1792
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001793PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001794"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001795This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001796 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001797or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1798\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001799Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1800or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001801\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001802See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001803
1804static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001805 {"st_mode", "protection bits"},
1806 {"st_ino", "inode"},
1807 {"st_dev", "device"},
1808 {"st_nlink", "number of hard links"},
1809 {"st_uid", "user ID of owner"},
1810 {"st_gid", "group ID of owner"},
1811 {"st_size", "total size, in bytes"},
1812 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1813 {NULL, "integer time of last access"},
1814 {NULL, "integer time of last modification"},
1815 {NULL, "integer time of last change"},
1816 {"st_atime", "time of last access"},
1817 {"st_mtime", "time of last modification"},
1818 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001819 {"st_atime_ns", "time of last access in nanoseconds"},
1820 {"st_mtime_ns", "time of last modification in nanoseconds"},
1821 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001822#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001823 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001824#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001825#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001826 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001827#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001828#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001829 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001830#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001831#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001832 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001833#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001834#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001835 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001836#endif
1837#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001838 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001839#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001840#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1841 {"st_file_attributes", "Windows file attribute bits"},
1842#endif
jcea6c51d512018-01-28 14:00:08 +01001843#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1844 {"st_fstype", "Type of filesystem"},
1845#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001847};
1848
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001849#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001850#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001851#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001852#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001853#endif
1854
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001855#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001856#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1857#else
1858#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1859#endif
1860
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001861#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001862#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1863#else
1864#define ST_RDEV_IDX ST_BLOCKS_IDX
1865#endif
1866
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001867#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1868#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1869#else
1870#define ST_FLAGS_IDX ST_RDEV_IDX
1871#endif
1872
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001873#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001874#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001875#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001876#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001877#endif
1878
1879#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1880#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1881#else
1882#define ST_BIRTHTIME_IDX ST_GEN_IDX
1883#endif
1884
Zachary Ware63f277b2014-06-19 09:46:37 -05001885#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1886#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1887#else
1888#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1889#endif
1890
jcea6c51d512018-01-28 14:00:08 +01001891#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1892#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1893#else
1894#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1895#endif
1896
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001897static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001898 "stat_result", /* name */
1899 stat_result__doc__, /* doc */
1900 stat_result_fields,
1901 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001902};
1903
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001904PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001905"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1906This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001907 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001908or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001909\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001910See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001911
1912static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001913 {"f_bsize", },
1914 {"f_frsize", },
1915 {"f_blocks", },
1916 {"f_bfree", },
1917 {"f_bavail", },
1918 {"f_files", },
1919 {"f_ffree", },
1920 {"f_favail", },
1921 {"f_flag", },
1922 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001923 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001924 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001925};
1926
1927static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001928 "statvfs_result", /* name */
1929 statvfs_result__doc__, /* doc */
1930 statvfs_result_fields,
1931 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001932};
1933
Ross Lagerwall7807c352011-03-17 20:20:30 +02001934#if defined(HAVE_WAITID) && !defined(__APPLE__)
1935PyDoc_STRVAR(waitid_result__doc__,
1936"waitid_result: Result from waitid.\n\n\
1937This object may be accessed either as a tuple of\n\
1938 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1939or via the attributes si_pid, si_uid, and so on.\n\
1940\n\
1941See os.waitid for more information.");
1942
1943static PyStructSequence_Field waitid_result_fields[] = {
1944 {"si_pid", },
1945 {"si_uid", },
1946 {"si_signo", },
1947 {"si_status", },
1948 {"si_code", },
1949 {0}
1950};
1951
1952static PyStructSequence_Desc waitid_result_desc = {
1953 "waitid_result", /* name */
1954 waitid_result__doc__, /* doc */
1955 waitid_result_fields,
1956 5
1957};
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001958static PyTypeObject* WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +02001959#endif
1960
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001961static int initialized;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001962static PyTypeObject* StatResultType;
1963static PyTypeObject* StatVFSResultType;
William Orr81574b82018-10-01 22:19:56 -07001964#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001965static PyTypeObject* SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001966#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001967static newfunc structseq_new;
1968
1969static PyObject *
1970statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1971{
Victor Stinner8c62be82010-05-06 00:08:46 +00001972 PyStructSequence *result;
1973 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001974
Victor Stinner8c62be82010-05-06 00:08:46 +00001975 result = (PyStructSequence*)structseq_new(type, args, kwds);
1976 if (!result)
1977 return NULL;
1978 /* If we have been initialized from a tuple,
1979 st_?time might be set to None. Initialize it
1980 from the int slots. */
1981 for (i = 7; i <= 9; i++) {
1982 if (result->ob_item[i+3] == Py_None) {
1983 Py_DECREF(Py_None);
1984 Py_INCREF(result->ob_item[i]);
1985 result->ob_item[i+3] = result->ob_item[i];
1986 }
1987 }
1988 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001989}
1990
1991
Larry Hastings6fe20b32012-04-19 15:07:49 -07001992static PyObject *billion = NULL;
1993
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001994static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001995fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001996{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001997 PyObject *s = _PyLong_FromTime_t(sec);
1998 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1999 PyObject *s_in_ns = NULL;
2000 PyObject *ns_total = NULL;
2001 PyObject *float_s = NULL;
2002
2003 if (!(s && ns_fractional))
2004 goto exit;
2005
2006 s_in_ns = PyNumber_Multiply(s, billion);
2007 if (!s_in_ns)
2008 goto exit;
2009
2010 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2011 if (!ns_total)
2012 goto exit;
2013
Victor Stinner01b5aab2017-10-24 02:02:00 -07002014 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2015 if (!float_s) {
2016 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002017 }
2018
2019 PyStructSequence_SET_ITEM(v, index, s);
2020 PyStructSequence_SET_ITEM(v, index+3, float_s);
2021 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2022 s = NULL;
2023 float_s = NULL;
2024 ns_total = NULL;
2025exit:
2026 Py_XDECREF(s);
2027 Py_XDECREF(ns_fractional);
2028 Py_XDECREF(s_in_ns);
2029 Py_XDECREF(ns_total);
2030 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002031}
2032
Tim Peters5aa91602002-01-30 05:46:57 +00002033/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002034 (used by posix_stat() and posix_fstat()) */
2035static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002036_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002037{
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 unsigned long ansec, mnsec, cnsec;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002039 PyObject *v = PyStructSequence_New(StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002040 if (v == NULL)
2041 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002042
Victor Stinner8c62be82010-05-06 00:08:46 +00002043 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002044 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002045 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002046#ifdef MS_WINDOWS
2047 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002048#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002049 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002050#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002051 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002052#if defined(MS_WINDOWS)
2053 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2054 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2055#else
2056 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2057 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2058#endif
xdegaye50e86032017-05-22 11:15:08 +02002059 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2060 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002061
Martin v. Löwis14694662006-02-03 12:54:16 +00002062#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002063 ansec = st->st_atim.tv_nsec;
2064 mnsec = st->st_mtim.tv_nsec;
2065 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002066#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002067 ansec = st->st_atimespec.tv_nsec;
2068 mnsec = st->st_mtimespec.tv_nsec;
2069 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002070#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002071 ansec = st->st_atime_nsec;
2072 mnsec = st->st_mtime_nsec;
2073 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002074#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002075 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002076#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002077 fill_time(v, 7, st->st_atime, ansec);
2078 fill_time(v, 8, st->st_mtime, mnsec);
2079 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002080
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002081#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002082 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2083 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002084#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002085#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2087 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002088#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002089#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002090 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2091 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002092#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002093#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002094 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2095 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002096#endif
2097#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002098 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002099 PyObject *val;
2100 unsigned long bsec,bnsec;
2101 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002102#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002103 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002104#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002105 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002106#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002107 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002108 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2109 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002110 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002111#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002112#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002113 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2114 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002115#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002116#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2117 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2118 PyLong_FromUnsignedLong(st->st_file_attributes));
2119#endif
jcea6c51d512018-01-28 14:00:08 +01002120#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2121 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2122 PyUnicode_FromString(st->st_fstype));
2123#endif
Fred Drake699f3522000-06-29 21:12:41 +00002124
Victor Stinner8c62be82010-05-06 00:08:46 +00002125 if (PyErr_Occurred()) {
2126 Py_DECREF(v);
2127 return NULL;
2128 }
Fred Drake699f3522000-06-29 21:12:41 +00002129
Victor Stinner8c62be82010-05-06 00:08:46 +00002130 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002131}
2132
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002133/* POSIX methods */
2134
Guido van Rossum94f6f721999-01-06 18:42:14 +00002135
2136static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002137posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002138 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002139{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002140 STRUCT_STAT st;
2141 int result;
2142
2143#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2144 if (follow_symlinks_specified(function_name, follow_symlinks))
2145 return NULL;
2146#endif
2147
2148 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2149 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2150 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2151 return NULL;
2152
2153 Py_BEGIN_ALLOW_THREADS
2154 if (path->fd != -1)
2155 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002156#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002157 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002158 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002159 else
Steve Dowercc16be82016-09-08 10:35:16 -07002160 result = win32_lstat(path->wide, &st);
2161#else
2162 else
2163#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002164 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2165 result = LSTAT(path->narrow, &st);
2166 else
Steve Dowercc16be82016-09-08 10:35:16 -07002167#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002168#ifdef HAVE_FSTATAT
2169 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2170 result = fstatat(dir_fd, path->narrow, &st,
2171 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2172 else
Steve Dowercc16be82016-09-08 10:35:16 -07002173#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002174 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002175#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002176 Py_END_ALLOW_THREADS
2177
Victor Stinner292c8352012-10-30 02:17:38 +01002178 if (result != 0) {
2179 return path_error(path);
2180 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002181
2182 return _pystat_fromstructstat(&st);
2183}
2184
Larry Hastings2f936352014-08-05 14:04:04 +10002185/*[python input]
2186
2187for s in """
2188
2189FACCESSAT
2190FCHMODAT
2191FCHOWNAT
2192FSTATAT
2193LINKAT
2194MKDIRAT
2195MKFIFOAT
2196MKNODAT
2197OPENAT
2198READLINKAT
2199SYMLINKAT
2200UNLINKAT
2201
2202""".strip().split():
2203 s = s.strip()
2204 print("""
2205#ifdef HAVE_{s}
2206 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002207#else
Larry Hastings2f936352014-08-05 14:04:04 +10002208 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002209#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002210""".rstrip().format(s=s))
2211
2212for s in """
2213
2214FCHDIR
2215FCHMOD
2216FCHOWN
2217FDOPENDIR
2218FEXECVE
2219FPATHCONF
2220FSTATVFS
2221FTRUNCATE
2222
2223""".strip().split():
2224 s = s.strip()
2225 print("""
2226#ifdef HAVE_{s}
2227 #define PATH_HAVE_{s} 1
2228#else
2229 #define PATH_HAVE_{s} 0
2230#endif
2231
2232""".rstrip().format(s=s))
2233[python start generated code]*/
2234
2235#ifdef HAVE_FACCESSAT
2236 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2237#else
2238 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2239#endif
2240
2241#ifdef HAVE_FCHMODAT
2242 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2243#else
2244 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2245#endif
2246
2247#ifdef HAVE_FCHOWNAT
2248 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2249#else
2250 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2251#endif
2252
2253#ifdef HAVE_FSTATAT
2254 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2255#else
2256 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2257#endif
2258
2259#ifdef HAVE_LINKAT
2260 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2261#else
2262 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2263#endif
2264
2265#ifdef HAVE_MKDIRAT
2266 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2267#else
2268 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2269#endif
2270
2271#ifdef HAVE_MKFIFOAT
2272 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2273#else
2274 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2275#endif
2276
2277#ifdef HAVE_MKNODAT
2278 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2279#else
2280 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2281#endif
2282
2283#ifdef HAVE_OPENAT
2284 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2285#else
2286 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2287#endif
2288
2289#ifdef HAVE_READLINKAT
2290 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2291#else
2292 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2293#endif
2294
2295#ifdef HAVE_SYMLINKAT
2296 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2297#else
2298 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2299#endif
2300
2301#ifdef HAVE_UNLINKAT
2302 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2303#else
2304 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2305#endif
2306
2307#ifdef HAVE_FCHDIR
2308 #define PATH_HAVE_FCHDIR 1
2309#else
2310 #define PATH_HAVE_FCHDIR 0
2311#endif
2312
2313#ifdef HAVE_FCHMOD
2314 #define PATH_HAVE_FCHMOD 1
2315#else
2316 #define PATH_HAVE_FCHMOD 0
2317#endif
2318
2319#ifdef HAVE_FCHOWN
2320 #define PATH_HAVE_FCHOWN 1
2321#else
2322 #define PATH_HAVE_FCHOWN 0
2323#endif
2324
2325#ifdef HAVE_FDOPENDIR
2326 #define PATH_HAVE_FDOPENDIR 1
2327#else
2328 #define PATH_HAVE_FDOPENDIR 0
2329#endif
2330
2331#ifdef HAVE_FEXECVE
2332 #define PATH_HAVE_FEXECVE 1
2333#else
2334 #define PATH_HAVE_FEXECVE 0
2335#endif
2336
2337#ifdef HAVE_FPATHCONF
2338 #define PATH_HAVE_FPATHCONF 1
2339#else
2340 #define PATH_HAVE_FPATHCONF 0
2341#endif
2342
2343#ifdef HAVE_FSTATVFS
2344 #define PATH_HAVE_FSTATVFS 1
2345#else
2346 #define PATH_HAVE_FSTATVFS 0
2347#endif
2348
2349#ifdef HAVE_FTRUNCATE
2350 #define PATH_HAVE_FTRUNCATE 1
2351#else
2352 #define PATH_HAVE_FTRUNCATE 0
2353#endif
2354/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002355
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002356#ifdef MS_WINDOWS
2357 #undef PATH_HAVE_FTRUNCATE
2358 #define PATH_HAVE_FTRUNCATE 1
2359#endif
Larry Hastings31826802013-10-19 00:09:25 -07002360
Larry Hastings61272b72014-01-07 12:41:53 -08002361/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002362
2363class path_t_converter(CConverter):
2364
2365 type = "path_t"
2366 impl_by_reference = True
2367 parse_by_reference = True
2368
2369 converter = 'path_converter'
2370
2371 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002372 # right now path_t doesn't support default values.
2373 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002374 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002375 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002376
Larry Hastings2f936352014-08-05 14:04:04 +10002377 if self.c_default not in (None, 'Py_None'):
2378 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002379
2380 self.nullable = nullable
2381 self.allow_fd = allow_fd
2382
Larry Hastings7726ac92014-01-31 22:03:12 -08002383 def pre_render(self):
2384 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002385 if isinstance(value, str):
2386 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002387 return str(int(bool(value)))
2388
2389 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002390 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002391 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002392 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002393 strify(self.nullable),
2394 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002395 )
2396
2397 def cleanup(self):
2398 return "path_cleanup(&" + self.name + ");\n"
2399
2400
2401class dir_fd_converter(CConverter):
2402 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002403
Larry Hastings2f936352014-08-05 14:04:04 +10002404 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002405 if self.default in (unspecified, None):
2406 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002407 if isinstance(requires, str):
2408 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2409 else:
2410 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002411
Larry Hastings2f936352014-08-05 14:04:04 +10002412class fildes_converter(CConverter):
2413 type = 'int'
2414 converter = 'fildes_converter'
2415
2416class uid_t_converter(CConverter):
2417 type = "uid_t"
2418 converter = '_Py_Uid_Converter'
2419
2420class gid_t_converter(CConverter):
2421 type = "gid_t"
2422 converter = '_Py_Gid_Converter'
2423
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002424class dev_t_converter(CConverter):
2425 type = 'dev_t'
2426 converter = '_Py_Dev_Converter'
2427
2428class dev_t_return_converter(unsigned_long_return_converter):
2429 type = 'dev_t'
2430 conversion_fn = '_PyLong_FromDev'
2431 unsigned_cast = '(dev_t)'
2432
Larry Hastings2f936352014-08-05 14:04:04 +10002433class FSConverter_converter(CConverter):
2434 type = 'PyObject *'
2435 converter = 'PyUnicode_FSConverter'
2436 def converter_init(self):
2437 if self.default is not unspecified:
2438 fail("FSConverter_converter does not support default values")
2439 self.c_default = 'NULL'
2440
2441 def cleanup(self):
2442 return "Py_XDECREF(" + self.name + ");\n"
2443
2444class pid_t_converter(CConverter):
2445 type = 'pid_t'
2446 format_unit = '" _Py_PARSE_PID "'
2447
2448class idtype_t_converter(int_converter):
2449 type = 'idtype_t'
2450
2451class id_t_converter(CConverter):
2452 type = 'id_t'
2453 format_unit = '" _Py_PARSE_PID "'
2454
Benjamin Petersonca470632016-09-06 13:47:26 -07002455class intptr_t_converter(CConverter):
2456 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002457 format_unit = '" _Py_PARSE_INTPTR "'
2458
2459class Py_off_t_converter(CConverter):
2460 type = 'Py_off_t'
2461 converter = 'Py_off_t_converter'
2462
2463class Py_off_t_return_converter(long_return_converter):
2464 type = 'Py_off_t'
2465 conversion_fn = 'PyLong_FromPy_off_t'
2466
2467class path_confname_converter(CConverter):
2468 type="int"
2469 converter="conv_path_confname"
2470
2471class confstr_confname_converter(path_confname_converter):
2472 converter='conv_confstr_confname'
2473
2474class sysconf_confname_converter(path_confname_converter):
2475 converter="conv_sysconf_confname"
2476
2477class sched_param_converter(CConverter):
2478 type = 'struct sched_param'
2479 converter = 'convert_sched_param'
2480 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002481
Larry Hastings61272b72014-01-07 12:41:53 -08002482[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002483/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002484
Larry Hastings61272b72014-01-07 12:41:53 -08002485/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002486
Larry Hastings2a727912014-01-16 11:32:01 -08002487os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002488
2489 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002490 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002491 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002492
2493 *
2494
Larry Hastings2f936352014-08-05 14:04:04 +10002495 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002496 If not None, it should be a file descriptor open to a directory,
2497 and path should be a relative string; path will then be relative to
2498 that directory.
2499
2500 follow_symlinks: bool = True
2501 If False, and the last element of the path is a symbolic link,
2502 stat will examine the symbolic link itself instead of the file
2503 the link points to.
2504
2505Perform a stat system call on the given path.
2506
2507dir_fd and follow_symlinks may not be implemented
2508 on your platform. If they are unavailable, using them will raise a
2509 NotImplementedError.
2510
2511It's an error to use dir_fd or follow_symlinks when specifying path as
2512 an open file descriptor.
2513
Larry Hastings61272b72014-01-07 12:41:53 -08002514[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002515
Larry Hastings31826802013-10-19 00:09:25 -07002516static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002517os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002518/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002519{
2520 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2521}
2522
Larry Hastings2f936352014-08-05 14:04:04 +10002523
2524/*[clinic input]
2525os.lstat
2526
2527 path : path_t
2528
2529 *
2530
2531 dir_fd : dir_fd(requires='fstatat') = None
2532
2533Perform a stat system call on the given path, without following symbolic links.
2534
2535Like stat(), but do not follow symbolic links.
2536Equivalent to stat(path, follow_symlinks=False).
2537[clinic start generated code]*/
2538
Larry Hastings2f936352014-08-05 14:04:04 +10002539static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002540os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2541/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002542{
2543 int follow_symlinks = 0;
2544 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2545}
Larry Hastings31826802013-10-19 00:09:25 -07002546
Larry Hastings2f936352014-08-05 14:04:04 +10002547
Larry Hastings61272b72014-01-07 12:41:53 -08002548/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002549os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002550
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002551 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002552 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002553
2554 mode: int
2555 Operating-system mode bitfield. Can be F_OK to test existence,
2556 or the inclusive-OR of R_OK, W_OK, and X_OK.
2557
2558 *
2559
Larry Hastings2f936352014-08-05 14:04:04 +10002560 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002561 If not None, it should be a file descriptor open to a directory,
2562 and path should be relative; path will then be relative to that
2563 directory.
2564
2565 effective_ids: bool = False
2566 If True, access will use the effective uid/gid instead of
2567 the real uid/gid.
2568
2569 follow_symlinks: bool = True
2570 If False, and the last element of the path is a symbolic link,
2571 access will examine the symbolic link itself instead of the file
2572 the link points to.
2573
2574Use the real uid/gid to test for access to a path.
2575
2576{parameters}
2577dir_fd, effective_ids, and follow_symlinks may not be implemented
2578 on your platform. If they are unavailable, using them will raise a
2579 NotImplementedError.
2580
2581Note that most operations will use the effective uid/gid, therefore this
2582 routine can be used in a suid/sgid environment to test if the invoking user
2583 has the specified access to the path.
2584
Larry Hastings61272b72014-01-07 12:41:53 -08002585[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002586
Larry Hastings2f936352014-08-05 14:04:04 +10002587static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002588os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002589 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002590/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002591{
Larry Hastings2f936352014-08-05 14:04:04 +10002592 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002593
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002594#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002595 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002596#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002597 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002598#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002599
Larry Hastings9cf065c2012-06-22 16:30:09 -07002600#ifndef HAVE_FACCESSAT
2601 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002602 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603
2604 if (effective_ids) {
2605 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002606 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002607 }
2608#endif
2609
2610#ifdef MS_WINDOWS
2611 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002612 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002613 Py_END_ALLOW_THREADS
2614
2615 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002616 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002617 * * we didn't get a -1, and
2618 * * write access wasn't requested,
2619 * * or the file isn't read-only,
2620 * * or it's a directory.
2621 * (Directories cannot be read-only on Windows.)
2622 */
Larry Hastings2f936352014-08-05 14:04:04 +10002623 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002624 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002625 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002626 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627#else
2628
2629 Py_BEGIN_ALLOW_THREADS
2630#ifdef HAVE_FACCESSAT
2631 if ((dir_fd != DEFAULT_DIR_FD) ||
2632 effective_ids ||
2633 !follow_symlinks) {
2634 int flags = 0;
2635 if (!follow_symlinks)
2636 flags |= AT_SYMLINK_NOFOLLOW;
2637 if (effective_ids)
2638 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002639 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002640 }
2641 else
2642#endif
Larry Hastings31826802013-10-19 00:09:25 -07002643 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002644 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002645 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002646#endif
2647
Larry Hastings9cf065c2012-06-22 16:30:09 -07002648 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002649}
2650
Guido van Rossumd371ff11999-01-25 16:12:23 +00002651#ifndef F_OK
2652#define F_OK 0
2653#endif
2654#ifndef R_OK
2655#define R_OK 4
2656#endif
2657#ifndef W_OK
2658#define W_OK 2
2659#endif
2660#ifndef X_OK
2661#define X_OK 1
2662#endif
2663
Larry Hastings31826802013-10-19 00:09:25 -07002664
Guido van Rossumd371ff11999-01-25 16:12:23 +00002665#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002666/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002667os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002668
2669 fd: int
2670 Integer file descriptor handle.
2671
2672 /
2673
2674Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002675[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002676
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002677static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002678os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002679/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002680{
2681 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002682
Larry Hastings31826802013-10-19 00:09:25 -07002683 ret = ttyname(fd);
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002684 if (ret == NULL) {
2685 return posix_error();
2686 }
2687 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002688}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002689#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002690
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002691#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002692/*[clinic input]
2693os.ctermid
2694
2695Return the name of the controlling terminal for this process.
2696[clinic start generated code]*/
2697
Larry Hastings2f936352014-08-05 14:04:04 +10002698static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002699os_ctermid_impl(PyObject *module)
2700/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002701{
Victor Stinner8c62be82010-05-06 00:08:46 +00002702 char *ret;
2703 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002704
Greg Wardb48bc172000-03-01 21:51:56 +00002705#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002706 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002707#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002708 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002709#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002710 if (ret == NULL)
2711 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002712 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002713}
Larry Hastings2f936352014-08-05 14:04:04 +10002714#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002715
Larry Hastings2f936352014-08-05 14:04:04 +10002716
2717/*[clinic input]
2718os.chdir
2719
2720 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2721
2722Change the current working directory to the specified path.
2723
2724path may always be specified as a string.
2725On some platforms, path may also be specified as an open file descriptor.
2726 If this functionality is unavailable, using it raises an exception.
2727[clinic start generated code]*/
2728
Larry Hastings2f936352014-08-05 14:04:04 +10002729static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002730os_chdir_impl(PyObject *module, path_t *path)
2731/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002732{
2733 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002734
2735 Py_BEGIN_ALLOW_THREADS
2736#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002737 /* on unix, success = 0, on windows, success = !0 */
2738 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002739#else
2740#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002741 if (path->fd != -1)
2742 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002743 else
2744#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002745 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002746#endif
2747 Py_END_ALLOW_THREADS
2748
2749 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002750 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002751 }
2752
Larry Hastings2f936352014-08-05 14:04:04 +10002753 Py_RETURN_NONE;
2754}
2755
2756
2757#ifdef HAVE_FCHDIR
2758/*[clinic input]
2759os.fchdir
2760
2761 fd: fildes
2762
2763Change to the directory of the given file descriptor.
2764
2765fd must be opened on a directory, not a file.
2766Equivalent to os.chdir(fd).
2767
2768[clinic start generated code]*/
2769
Fred Drake4d1e64b2002-04-15 19:40:07 +00002770static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002771os_fchdir_impl(PyObject *module, int fd)
2772/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002773{
Larry Hastings2f936352014-08-05 14:04:04 +10002774 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002775}
2776#endif /* HAVE_FCHDIR */
2777
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002778
Larry Hastings2f936352014-08-05 14:04:04 +10002779/*[clinic input]
2780os.chmod
2781
2782 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002783 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002784 On some platforms, path may also be specified as an open file descriptor.
2785 If this functionality is unavailable, using it raises an exception.
2786
2787 mode: int
2788 Operating-system mode bitfield.
2789
2790 *
2791
2792 dir_fd : dir_fd(requires='fchmodat') = None
2793 If not None, it should be a file descriptor open to a directory,
2794 and path should be relative; path will then be relative to that
2795 directory.
2796
2797 follow_symlinks: bool = True
2798 If False, and the last element of the path is a symbolic link,
2799 chmod will modify the symbolic link itself instead of the file
2800 the link points to.
2801
2802Change the access permissions of a file.
2803
2804It is an error to use dir_fd or follow_symlinks when specifying path as
2805 an open file descriptor.
2806dir_fd and follow_symlinks may not be implemented on your platform.
2807 If they are unavailable, using them will raise a NotImplementedError.
2808
2809[clinic start generated code]*/
2810
Larry Hastings2f936352014-08-05 14:04:04 +10002811static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002812os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002813 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002814/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002815{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002817
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002818#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002819 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002820#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002821
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822#ifdef HAVE_FCHMODAT
2823 int fchmodat_nofollow_unsupported = 0;
2824#endif
2825
Larry Hastings9cf065c2012-06-22 16:30:09 -07002826#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2827 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002828 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829#endif
2830
2831#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002832 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002833 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002834 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 result = 0;
2836 else {
2837 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002838 attr &= ~FILE_ATTRIBUTE_READONLY;
2839 else
2840 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002841 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002842 }
2843 Py_END_ALLOW_THREADS
2844
2845 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002846 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002847 }
2848#else /* MS_WINDOWS */
2849 Py_BEGIN_ALLOW_THREADS
2850#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002851 if (path->fd != -1)
2852 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002853 else
2854#endif
2855#ifdef HAVE_LCHMOD
2856 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002857 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002858 else
2859#endif
2860#ifdef HAVE_FCHMODAT
2861 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2862 /*
2863 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2864 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002865 * and then says it isn't implemented yet.
2866 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002867 *
2868 * Once it is supported, os.chmod will automatically
2869 * support dir_fd and follow_symlinks=False. (Hopefully.)
2870 * Until then, we need to be careful what exception we raise.
2871 */
Larry Hastings2f936352014-08-05 14:04:04 +10002872 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002873 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2874 /*
2875 * But wait! We can't throw the exception without allowing threads,
2876 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2877 */
2878 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002879 result &&
2880 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2881 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002882 }
2883 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002884#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002885 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002886 Py_END_ALLOW_THREADS
2887
2888 if (result) {
2889#ifdef HAVE_FCHMODAT
2890 if (fchmodat_nofollow_unsupported) {
2891 if (dir_fd != DEFAULT_DIR_FD)
2892 dir_fd_and_follow_symlinks_invalid("chmod",
2893 dir_fd, follow_symlinks);
2894 else
2895 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002896 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002897 }
2898 else
2899#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002900 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002901 }
2902#endif
2903
Larry Hastings2f936352014-08-05 14:04:04 +10002904 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002905}
2906
Larry Hastings9cf065c2012-06-22 16:30:09 -07002907
Christian Heimes4e30a842007-11-30 22:12:06 +00002908#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002909/*[clinic input]
2910os.fchmod
2911
2912 fd: int
2913 mode: int
2914
2915Change the access permissions of the file given by file descriptor fd.
2916
2917Equivalent to os.chmod(fd, mode).
2918[clinic start generated code]*/
2919
Larry Hastings2f936352014-08-05 14:04:04 +10002920static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002921os_fchmod_impl(PyObject *module, int fd, int mode)
2922/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002923{
2924 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002925 int async_err = 0;
2926
2927 do {
2928 Py_BEGIN_ALLOW_THREADS
2929 res = fchmod(fd, mode);
2930 Py_END_ALLOW_THREADS
2931 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2932 if (res != 0)
2933 return (!async_err) ? posix_error() : NULL;
2934
Victor Stinner8c62be82010-05-06 00:08:46 +00002935 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002936}
2937#endif /* HAVE_FCHMOD */
2938
Larry Hastings2f936352014-08-05 14:04:04 +10002939
Christian Heimes4e30a842007-11-30 22:12:06 +00002940#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002941/*[clinic input]
2942os.lchmod
2943
2944 path: path_t
2945 mode: int
2946
2947Change the access permissions of a file, without following symbolic links.
2948
2949If path is a symlink, this affects the link itself rather than the target.
2950Equivalent to chmod(path, mode, follow_symlinks=False)."
2951[clinic start generated code]*/
2952
Larry Hastings2f936352014-08-05 14:04:04 +10002953static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002954os_lchmod_impl(PyObject *module, path_t *path, int mode)
2955/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002956{
Victor Stinner8c62be82010-05-06 00:08:46 +00002957 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002958 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002959 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002960 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002961 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002962 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002963 return NULL;
2964 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002965 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002966}
2967#endif /* HAVE_LCHMOD */
2968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002969
Thomas Wouterscf297e42007-02-23 15:07:44 +00002970#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002971/*[clinic input]
2972os.chflags
2973
2974 path: path_t
2975 flags: unsigned_long(bitwise=True)
2976 follow_symlinks: bool=True
2977
2978Set file flags.
2979
2980If follow_symlinks is False, and the last element of the path is a symbolic
2981 link, chflags will change flags on the symbolic link itself instead of the
2982 file the link points to.
2983follow_symlinks may not be implemented on your platform. If it is
2984unavailable, using it will raise a NotImplementedError.
2985
2986[clinic start generated code]*/
2987
Larry Hastings2f936352014-08-05 14:04:04 +10002988static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002989os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002990 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002991/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002992{
2993 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002994
2995#ifndef HAVE_LCHFLAGS
2996 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002997 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002998#endif
2999
Victor Stinner8c62be82010-05-06 00:08:46 +00003000 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003001#ifdef HAVE_LCHFLAGS
3002 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003003 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003004 else
3005#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003006 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003007 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003008
Larry Hastings2f936352014-08-05 14:04:04 +10003009 if (result)
3010 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003011
Larry Hastings2f936352014-08-05 14:04:04 +10003012 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003013}
3014#endif /* HAVE_CHFLAGS */
3015
Larry Hastings2f936352014-08-05 14:04:04 +10003016
Thomas Wouterscf297e42007-02-23 15:07:44 +00003017#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003018/*[clinic input]
3019os.lchflags
3020
3021 path: path_t
3022 flags: unsigned_long(bitwise=True)
3023
3024Set file flags.
3025
3026This function will not follow symbolic links.
3027Equivalent to chflags(path, flags, follow_symlinks=False).
3028[clinic start generated code]*/
3029
Larry Hastings2f936352014-08-05 14:04:04 +10003030static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003031os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3032/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003033{
Victor Stinner8c62be82010-05-06 00:08:46 +00003034 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003035 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003036 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003037 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003038 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003039 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003040 }
Victor Stinner292c8352012-10-30 02:17:38 +01003041 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003042}
3043#endif /* HAVE_LCHFLAGS */
3044
Larry Hastings2f936352014-08-05 14:04:04 +10003045
Martin v. Löwis244edc82001-10-04 22:44:26 +00003046#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003047/*[clinic input]
3048os.chroot
3049 path: path_t
3050
3051Change root directory to path.
3052
3053[clinic start generated code]*/
3054
Larry Hastings2f936352014-08-05 14:04:04 +10003055static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003056os_chroot_impl(PyObject *module, path_t *path)
3057/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003058{
3059 int res;
3060 Py_BEGIN_ALLOW_THREADS
3061 res = chroot(path->narrow);
3062 Py_END_ALLOW_THREADS
3063 if (res < 0)
3064 return path_error(path);
3065 Py_RETURN_NONE;
3066}
3067#endif /* HAVE_CHROOT */
3068
Martin v. Löwis244edc82001-10-04 22:44:26 +00003069
Guido van Rossum21142a01999-01-08 21:05:37 +00003070#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003071/*[clinic input]
3072os.fsync
3073
3074 fd: fildes
3075
3076Force write of fd to disk.
3077[clinic start generated code]*/
3078
Larry Hastings2f936352014-08-05 14:04:04 +10003079static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003080os_fsync_impl(PyObject *module, int fd)
3081/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003082{
3083 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003084}
3085#endif /* HAVE_FSYNC */
3086
Larry Hastings2f936352014-08-05 14:04:04 +10003087
Ross Lagerwall7807c352011-03-17 20:20:30 +02003088#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003089/*[clinic input]
3090os.sync
3091
3092Force write of everything to disk.
3093[clinic start generated code]*/
3094
Larry Hastings2f936352014-08-05 14:04:04 +10003095static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003096os_sync_impl(PyObject *module)
3097/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003098{
3099 Py_BEGIN_ALLOW_THREADS
3100 sync();
3101 Py_END_ALLOW_THREADS
3102 Py_RETURN_NONE;
3103}
Larry Hastings2f936352014-08-05 14:04:04 +10003104#endif /* HAVE_SYNC */
3105
Ross Lagerwall7807c352011-03-17 20:20:30 +02003106
Guido van Rossum21142a01999-01-08 21:05:37 +00003107#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003108#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003109extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3110#endif
3111
Larry Hastings2f936352014-08-05 14:04:04 +10003112/*[clinic input]
3113os.fdatasync
3114
3115 fd: fildes
3116
3117Force write of fd to disk without forcing update of metadata.
3118[clinic start generated code]*/
3119
Larry Hastings2f936352014-08-05 14:04:04 +10003120static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003121os_fdatasync_impl(PyObject *module, int fd)
3122/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003123{
3124 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003125}
3126#endif /* HAVE_FDATASYNC */
3127
3128
Fredrik Lundh10723342000-07-10 16:38:09 +00003129#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003130/*[clinic input]
3131os.chown
3132
3133 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003134 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003135
3136 uid: uid_t
3137
3138 gid: gid_t
3139
3140 *
3141
3142 dir_fd : dir_fd(requires='fchownat') = None
3143 If not None, it should be a file descriptor open to a directory,
3144 and path should be relative; path will then be relative to that
3145 directory.
3146
3147 follow_symlinks: bool = True
3148 If False, and the last element of the path is a symbolic link,
3149 stat will examine the symbolic link itself instead of the file
3150 the link points to.
3151
3152Change the owner and group id of path to the numeric uid and gid.\
3153
3154path may always be specified as a string.
3155On some platforms, path may also be specified as an open file descriptor.
3156 If this functionality is unavailable, using it raises an exception.
3157If dir_fd is not None, it should be a file descriptor open to a directory,
3158 and path should be relative; path will then be relative to that directory.
3159If follow_symlinks is False, and the last element of the path is a symbolic
3160 link, chown will modify the symbolic link itself instead of the file the
3161 link points to.
3162It is an error to use dir_fd or follow_symlinks when specifying path as
3163 an open file descriptor.
3164dir_fd and follow_symlinks may not be implemented on your platform.
3165 If they are unavailable, using them will raise a NotImplementedError.
3166
3167[clinic start generated code]*/
3168
Larry Hastings2f936352014-08-05 14:04:04 +10003169static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003170os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003171 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003172/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003173{
3174 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003175
3176#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3177 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003178 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003179#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003180 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3181 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3182 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003183
3184#ifdef __APPLE__
3185 /*
3186 * This is for Mac OS X 10.3, which doesn't have lchown.
3187 * (But we still have an lchown symbol because of weak-linking.)
3188 * It doesn't have fchownat either. So there's no possibility
3189 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003190 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003191 if ((!follow_symlinks) && (lchown == NULL)) {
3192 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003193 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194 }
3195#endif
3196
Victor Stinner8c62be82010-05-06 00:08:46 +00003197 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003198#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003199 if (path->fd != -1)
3200 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003201 else
3202#endif
3203#ifdef HAVE_LCHOWN
3204 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003205 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003206 else
3207#endif
3208#ifdef HAVE_FCHOWNAT
3209 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003210 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003211 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3212 else
3213#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003214 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003215 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003216
Larry Hastings2f936352014-08-05 14:04:04 +10003217 if (result)
3218 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003219
Larry Hastings2f936352014-08-05 14:04:04 +10003220 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003221}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003222#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003223
Larry Hastings2f936352014-08-05 14:04:04 +10003224
Christian Heimes4e30a842007-11-30 22:12:06 +00003225#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003226/*[clinic input]
3227os.fchown
3228
3229 fd: int
3230 uid: uid_t
3231 gid: gid_t
3232
3233Change the owner and group id of the file specified by file descriptor.
3234
3235Equivalent to os.chown(fd, uid, gid).
3236
3237[clinic start generated code]*/
3238
Larry Hastings2f936352014-08-05 14:04:04 +10003239static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003240os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3241/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003242{
Victor Stinner8c62be82010-05-06 00:08:46 +00003243 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003244 int async_err = 0;
3245
3246 do {
3247 Py_BEGIN_ALLOW_THREADS
3248 res = fchown(fd, uid, gid);
3249 Py_END_ALLOW_THREADS
3250 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3251 if (res != 0)
3252 return (!async_err) ? posix_error() : NULL;
3253
Victor Stinner8c62be82010-05-06 00:08:46 +00003254 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003255}
3256#endif /* HAVE_FCHOWN */
3257
Larry Hastings2f936352014-08-05 14:04:04 +10003258
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003259#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003260/*[clinic input]
3261os.lchown
3262
3263 path : path_t
3264 uid: uid_t
3265 gid: gid_t
3266
3267Change the owner and group id of path to the numeric uid and gid.
3268
3269This function will not follow symbolic links.
3270Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3271[clinic start generated code]*/
3272
Larry Hastings2f936352014-08-05 14:04:04 +10003273static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003274os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3275/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003276{
Victor Stinner8c62be82010-05-06 00:08:46 +00003277 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003278 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003279 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003280 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003281 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003282 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003283 }
Larry Hastings2f936352014-08-05 14:04:04 +10003284 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003285}
3286#endif /* HAVE_LCHOWN */
3287
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003288
Barry Warsaw53699e91996-12-10 23:23:01 +00003289static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003290posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003291{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003292 char *buf, *tmpbuf;
3293 char *cwd;
3294 const size_t chunk = 1024;
3295 size_t buflen = 0;
3296 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003297
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003298#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003300 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003301 wchar_t *wbuf2 = wbuf;
3302 PyObject *resobj;
3303 DWORD len;
3304 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003305 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003306 /* If the buffer is large enough, len does not include the
3307 terminating \0. If the buffer is too small, len includes
3308 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003309 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003310 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003311 if (wbuf2)
3312 len = GetCurrentDirectoryW(len, wbuf2);
3313 }
3314 Py_END_ALLOW_THREADS
3315 if (!wbuf2) {
3316 PyErr_NoMemory();
3317 return NULL;
3318 }
3319 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003320 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003321 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003322 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 }
3324 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003325 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003326 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003327 return resobj;
3328 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003329
3330 if (win32_warn_bytes_api())
3331 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003332#endif
3333
Victor Stinner4403d7d2015-04-25 00:16:10 +02003334 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003335 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003336 do {
3337 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003338#ifdef MS_WINDOWS
3339 if (buflen > INT_MAX) {
3340 PyErr_NoMemory();
3341 break;
3342 }
3343#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003344 tmpbuf = PyMem_RawRealloc(buf, buflen);
3345 if (tmpbuf == NULL)
3346 break;
3347
3348 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003349#ifdef MS_WINDOWS
3350 cwd = getcwd(buf, (int)buflen);
3351#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003352 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003353#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003354 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003355 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003356
3357 if (cwd == NULL) {
3358 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003359 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003360 }
3361
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003363 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3364 else
3365 obj = PyUnicode_DecodeFSDefault(buf);
3366 PyMem_RawFree(buf);
3367
3368 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003369}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003370
Larry Hastings2f936352014-08-05 14:04:04 +10003371
3372/*[clinic input]
3373os.getcwd
3374
3375Return a unicode string representing the current working directory.
3376[clinic start generated code]*/
3377
Larry Hastings2f936352014-08-05 14:04:04 +10003378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003379os_getcwd_impl(PyObject *module)
3380/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003381{
3382 return posix_getcwd(0);
3383}
3384
Larry Hastings2f936352014-08-05 14:04:04 +10003385
3386/*[clinic input]
3387os.getcwdb
3388
3389Return a bytes string representing the current working directory.
3390[clinic start generated code]*/
3391
Larry Hastings2f936352014-08-05 14:04:04 +10003392static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003393os_getcwdb_impl(PyObject *module)
3394/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003395{
3396 return posix_getcwd(1);
3397}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003398
Larry Hastings2f936352014-08-05 14:04:04 +10003399
Larry Hastings9cf065c2012-06-22 16:30:09 -07003400#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3401#define HAVE_LINK 1
3402#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003403
Guido van Rossumb6775db1994-08-01 11:34:53 +00003404#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003405/*[clinic input]
3406
3407os.link
3408
3409 src : path_t
3410 dst : path_t
3411 *
3412 src_dir_fd : dir_fd = None
3413 dst_dir_fd : dir_fd = None
3414 follow_symlinks: bool = True
3415
3416Create a hard link to a file.
3417
3418If either src_dir_fd or dst_dir_fd is not None, it should be a file
3419 descriptor open to a directory, and the respective path string (src or dst)
3420 should be relative; the path will then be relative to that directory.
3421If follow_symlinks is False, and the last element of src is a symbolic
3422 link, link will create a link to the symbolic link itself instead of the
3423 file the link points to.
3424src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3425 platform. If they are unavailable, using them will raise a
3426 NotImplementedError.
3427[clinic start generated code]*/
3428
Larry Hastings2f936352014-08-05 14:04:04 +10003429static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003430os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003431 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003432/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003433{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003435 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003436#else
3437 int result;
3438#endif
3439
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440#ifndef HAVE_LINKAT
3441 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3442 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003443 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 }
3445#endif
3446
Steve Dowercc16be82016-09-08 10:35:16 -07003447#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003448 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003449 PyErr_SetString(PyExc_NotImplementedError,
3450 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003451 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452 }
Steve Dowercc16be82016-09-08 10:35:16 -07003453#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003454
Brian Curtin1b9df392010-11-24 20:24:31 +00003455#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003456 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003457 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003459
Larry Hastings2f936352014-08-05 14:04:04 +10003460 if (!result)
3461 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003462#else
3463 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003464#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3466 (dst_dir_fd != DEFAULT_DIR_FD) ||
3467 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003468 result = linkat(src_dir_fd, src->narrow,
3469 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3471 else
Steve Dowercc16be82016-09-08 10:35:16 -07003472#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003473 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003474 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003475
Larry Hastings2f936352014-08-05 14:04:04 +10003476 if (result)
3477 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003478#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479
Larry Hastings2f936352014-08-05 14:04:04 +10003480 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003481}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003482#endif
3483
Brian Curtin1b9df392010-11-24 20:24:31 +00003484
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003485#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003486static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003487_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003488{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 PyObject *v;
3490 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3491 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003492 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003494 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496
Steve Dowercc16be82016-09-08 10:35:16 -07003497 WIN32_FIND_DATAW wFileData;
3498 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003499
Steve Dowercc16be82016-09-08 10:35:16 -07003500 if (!path->wide) { /* Default arg: "." */
3501 po_wchars = L".";
3502 len = 1;
3503 } else {
3504 po_wchars = path->wide;
3505 len = wcslen(path->wide);
3506 }
3507 /* The +5 is so we can append "\\*.*\0" */
3508 wnamebuf = PyMem_New(wchar_t, len + 5);
3509 if (!wnamebuf) {
3510 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003511 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003512 }
Steve Dowercc16be82016-09-08 10:35:16 -07003513 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003515 wchar_t wch = wnamebuf[len-1];
3516 if (wch != SEP && wch != ALTSEP && wch != L':')
3517 wnamebuf[len++] = SEP;
3518 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 }
Steve Dowercc16be82016-09-08 10:35:16 -07003520 if ((list = PyList_New(0)) == NULL) {
3521 goto exit;
3522 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003523 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003524 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003525 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003526 if (hFindFile == INVALID_HANDLE_VALUE) {
3527 int error = GetLastError();
3528 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003529 goto exit;
3530 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003531 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003533 }
3534 do {
3535 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003536 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3537 wcscmp(wFileData.cFileName, L"..") != 0) {
3538 v = PyUnicode_FromWideChar(wFileData.cFileName,
3539 wcslen(wFileData.cFileName));
3540 if (path->narrow && v) {
3541 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3542 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003543 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003544 Py_DECREF(list);
3545 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 break;
3547 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003548 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003549 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 Py_DECREF(list);
3551 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003552 break;
3553 }
3554 Py_DECREF(v);
3555 }
3556 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003557 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 Py_END_ALLOW_THREADS
3559 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3560 it got to the end of the directory. */
3561 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003563 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 }
3566 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003567
Larry Hastings9cf065c2012-06-22 16:30:09 -07003568exit:
3569 if (hFindFile != INVALID_HANDLE_VALUE) {
3570 if (FindClose(hFindFile) == FALSE) {
3571 if (list != NULL) {
3572 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003573 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003574 }
3575 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003577 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003578
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003580} /* end of _listdir_windows_no_opendir */
3581
3582#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3583
3584static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003585_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003586{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003587 PyObject *v;
3588 DIR *dirp = NULL;
3589 struct dirent *ep;
3590 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003591#ifdef HAVE_FDOPENDIR
3592 int fd = -1;
3593#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003594
Victor Stinner8c62be82010-05-06 00:08:46 +00003595 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003596#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003597 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003599 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003600 if (fd == -1)
3601 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003602
Larry Hastingsfdaea062012-06-25 04:42:23 -07003603 return_str = 1;
3604
Larry Hastings9cf065c2012-06-22 16:30:09 -07003605 Py_BEGIN_ALLOW_THREADS
3606 dirp = fdopendir(fd);
3607 Py_END_ALLOW_THREADS
3608 }
3609 else
3610#endif
3611 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003612 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003613 if (path->narrow) {
3614 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003615 /* only return bytes if they specified a bytes-like object */
3616 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003617 }
3618 else {
3619 name = ".";
3620 return_str = 1;
3621 }
3622
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623 Py_BEGIN_ALLOW_THREADS
3624 dirp = opendir(name);
3625 Py_END_ALLOW_THREADS
3626 }
3627
3628 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003629 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003630#ifdef HAVE_FDOPENDIR
3631 if (fd != -1) {
3632 Py_BEGIN_ALLOW_THREADS
3633 close(fd);
3634 Py_END_ALLOW_THREADS
3635 }
3636#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003637 goto exit;
3638 }
3639 if ((list = PyList_New(0)) == NULL) {
3640 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003641 }
3642 for (;;) {
3643 errno = 0;
3644 Py_BEGIN_ALLOW_THREADS
3645 ep = readdir(dirp);
3646 Py_END_ALLOW_THREADS
3647 if (ep == NULL) {
3648 if (errno == 0) {
3649 break;
3650 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003651 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003652 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003653 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003654 }
3655 }
3656 if (ep->d_name[0] == '.' &&
3657 (NAMLEN(ep) == 1 ||
3658 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3659 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003660 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003661 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3662 else
3663 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003664 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003665 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003666 break;
3667 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003668 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003669 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003670 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 break;
3672 }
3673 Py_DECREF(v);
3674 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003675
Larry Hastings9cf065c2012-06-22 16:30:09 -07003676exit:
3677 if (dirp != NULL) {
3678 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003679#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003680 if (fd > -1)
3681 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003682#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003683 closedir(dirp);
3684 Py_END_ALLOW_THREADS
3685 }
3686
Larry Hastings9cf065c2012-06-22 16:30:09 -07003687 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003688} /* end of _posix_listdir */
3689#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003690
Larry Hastings2f936352014-08-05 14:04:04 +10003691
3692/*[clinic input]
3693os.listdir
3694
3695 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3696
3697Return a list containing the names of the files in the directory.
3698
BNMetricsb9427072018-11-02 15:20:19 +00003699path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003700 the filenames returned will also be bytes; in all other circumstances
3701 the filenames returned will be str.
3702If path is None, uses the path='.'.
3703On some platforms, path may also be specified as an open file descriptor;\
3704 the file descriptor must refer to a directory.
3705 If this functionality is unavailable, using it raises NotImplementedError.
3706
3707The list is in arbitrary order. It does not include the special
3708entries '.' and '..' even if they are present in the directory.
3709
3710
3711[clinic start generated code]*/
3712
Larry Hastings2f936352014-08-05 14:04:04 +10003713static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003714os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003715/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003716{
3717#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3718 return _listdir_windows_no_opendir(path, NULL);
3719#else
3720 return _posix_listdir(path, NULL);
3721#endif
3722}
3723
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003724#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003725/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003726/*[clinic input]
3727os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003728
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003729 path: path_t
3730 /
3731
3732[clinic start generated code]*/
3733
3734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003735os__getfullpathname_impl(PyObject *module, path_t *path)
3736/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003737{
Steve Dowercc16be82016-09-08 10:35:16 -07003738 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3739 wchar_t *wtemp;
3740 DWORD result;
3741 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003742
Steve Dowercc16be82016-09-08 10:35:16 -07003743 result = GetFullPathNameW(path->wide,
3744 Py_ARRAY_LENGTH(woutbuf),
3745 woutbuf, &wtemp);
3746 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3747 woutbufp = PyMem_New(wchar_t, result);
3748 if (!woutbufp)
3749 return PyErr_NoMemory();
3750 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003751 }
Steve Dowercc16be82016-09-08 10:35:16 -07003752 if (result) {
3753 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3754 if (path->narrow)
3755 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3756 } else
3757 v = win32_error_object("GetFullPathNameW", path->object);
3758 if (woutbufp != woutbuf)
3759 PyMem_Free(woutbufp);
3760 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003761}
Brian Curtind40e6f72010-07-08 21:39:08 +00003762
Brian Curtind25aef52011-06-13 15:16:04 -05003763
Larry Hastings2f936352014-08-05 14:04:04 +10003764/*[clinic input]
3765os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003766
Steve Dower23ad6d02018-02-22 10:39:10 -08003767 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003768 /
3769
3770A helper function for samepath on windows.
3771[clinic start generated code]*/
3772
Larry Hastings2f936352014-08-05 14:04:04 +10003773static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003774os__getfinalpathname_impl(PyObject *module, path_t *path)
3775/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003776{
3777 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003778 wchar_t buf[MAXPATHLEN], *target_path = buf;
3779 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003780 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003781 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003782
Steve Dower23ad6d02018-02-22 10:39:10 -08003783 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003784 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003785 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003786 0, /* desired access */
3787 0, /* share mode */
3788 NULL, /* security attributes */
3789 OPEN_EXISTING,
3790 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3791 FILE_FLAG_BACKUP_SEMANTICS,
3792 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003793 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003794
Steve Dower23ad6d02018-02-22 10:39:10 -08003795 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003796 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003797 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003798
3799 /* We have a good handle to the target, use it to determine the
3800 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003801 while (1) {
3802 Py_BEGIN_ALLOW_THREADS
3803 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3804 buf_size, VOLUME_NAME_DOS);
3805 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003806
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003807 if (!result_length) {
3808 result = win32_error_object("GetFinalPathNameByHandleW",
3809 path->object);
3810 goto cleanup;
3811 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003812
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003813 if (result_length < buf_size) {
3814 break;
3815 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003816
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003817 wchar_t *tmp;
3818 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3819 result_length * sizeof(*tmp));
3820 if (!tmp) {
3821 result = PyErr_NoMemory();
3822 goto cleanup;
3823 }
3824
3825 buf_size = result_length;
3826 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003827 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003828
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003829 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003830 if (path->narrow)
3831 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003832
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003833cleanup:
3834 if (target_path != buf) {
3835 PyMem_Free(target_path);
3836 }
3837 CloseHandle(hFile);
3838 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003839}
Brian Curtin62857742010-09-06 17:07:27 +00003840
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003841/*[clinic input]
3842os._isdir
3843
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003844 path as arg: object
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003845 /
3846
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003847Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003848[clinic start generated code]*/
3849
Brian Curtin9c669cc2011-06-08 18:17:18 -05003850static PyObject *
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003851os__isdir(PyObject *module, PyObject *arg)
3852/*[clinic end generated code: output=404f334d85d4bf25 input=36cb6785874d479e]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003853{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003854 DWORD attributes;
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003855 path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0);
3856
3857 if (!path_converter(arg, &path)) {
3858 if (PyErr_ExceptionMatches(PyExc_ValueError)) {
3859 PyErr_Clear();
3860 Py_RETURN_FALSE;
3861 }
3862 return NULL;
3863 }
Brian Curtin9c669cc2011-06-08 18:17:18 -05003864
Steve Dowerb22a6772016-07-17 20:49:38 -07003865 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003866 attributes = GetFileAttributesW(path.wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003867 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003868
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003869 path_cleanup(&path);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003870 if (attributes == INVALID_FILE_ATTRIBUTES)
3871 Py_RETURN_FALSE;
3872
Brian Curtin9c669cc2011-06-08 18:17:18 -05003873 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3874 Py_RETURN_TRUE;
3875 else
3876 Py_RETURN_FALSE;
3877}
Tim Golden6b528062013-08-01 12:44:00 +01003878
Tim Golden6b528062013-08-01 12:44:00 +01003879
Larry Hastings2f936352014-08-05 14:04:04 +10003880/*[clinic input]
3881os._getvolumepathname
3882
Steve Dower23ad6d02018-02-22 10:39:10 -08003883 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003884
3885A helper function for ismount on Win32.
3886[clinic start generated code]*/
3887
Larry Hastings2f936352014-08-05 14:04:04 +10003888static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003889os__getvolumepathname_impl(PyObject *module, path_t *path)
3890/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003891{
3892 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003893 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003894 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003895 BOOL ret;
3896
Tim Golden6b528062013-08-01 12:44:00 +01003897 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003898 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003899
Victor Stinner850a18e2017-10-24 16:53:32 -07003900 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003901 PyErr_SetString(PyExc_OverflowError, "path too long");
3902 return NULL;
3903 }
3904
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003905 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003906 if (mountpath == NULL)
3907 return PyErr_NoMemory();
3908
3909 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003910 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003911 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003912 Py_END_ALLOW_THREADS
3913
3914 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003915 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003916 goto exit;
3917 }
3918 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003919 if (path->narrow)
3920 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003921
3922exit:
3923 PyMem_Free(mountpath);
3924 return result;
3925}
Tim Golden6b528062013-08-01 12:44:00 +01003926
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003927#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003928
Larry Hastings2f936352014-08-05 14:04:04 +10003929
3930/*[clinic input]
3931os.mkdir
3932
3933 path : path_t
3934
3935 mode: int = 0o777
3936
3937 *
3938
3939 dir_fd : dir_fd(requires='mkdirat') = None
3940
3941# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3942
3943Create a directory.
3944
3945If dir_fd is not None, it should be a file descriptor open to a directory,
3946 and path should be relative; path will then be relative to that directory.
3947dir_fd may not be implemented on your platform.
3948 If it is unavailable, using it will raise a NotImplementedError.
3949
3950The mode argument is ignored on Windows.
3951[clinic start generated code]*/
3952
Larry Hastings2f936352014-08-05 14:04:04 +10003953static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003954os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3955/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003956{
3957 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003958
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003959#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003960 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003961 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003962 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003963
Larry Hastings2f936352014-08-05 14:04:04 +10003964 if (!result)
3965 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003966#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003967 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003968#if HAVE_MKDIRAT
3969 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003970 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003971 else
3972#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003973#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003974 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003975#else
Larry Hastings2f936352014-08-05 14:04:04 +10003976 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003977#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003978 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003979 if (result < 0)
3980 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003981#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003982 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003983}
3984
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003985
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003986/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3987#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003988#include <sys/resource.h>
3989#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003990
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003991
3992#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003993/*[clinic input]
3994os.nice
3995
3996 increment: int
3997 /
3998
3999Add increment to the priority of process and return the new priority.
4000[clinic start generated code]*/
4001
Larry Hastings2f936352014-08-05 14:04:04 +10004002static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004003os_nice_impl(PyObject *module, int increment)
4004/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004005{
4006 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004007
Victor Stinner8c62be82010-05-06 00:08:46 +00004008 /* There are two flavours of 'nice': one that returns the new
4009 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004010 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004011 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004012
Victor Stinner8c62be82010-05-06 00:08:46 +00004013 If we are of the nice family that returns the new priority, we
4014 need to clear errno before the call, and check if errno is filled
4015 before calling posix_error() on a returnvalue of -1, because the
4016 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004017
Victor Stinner8c62be82010-05-06 00:08:46 +00004018 errno = 0;
4019 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004020#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004021 if (value == 0)
4022 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004023#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004024 if (value == -1 && errno != 0)
4025 /* either nice() or getpriority() returned an error */
4026 return posix_error();
4027 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004028}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004029#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004030
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004031
4032#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004033/*[clinic input]
4034os.getpriority
4035
4036 which: int
4037 who: int
4038
4039Return program scheduling priority.
4040[clinic start generated code]*/
4041
Larry Hastings2f936352014-08-05 14:04:04 +10004042static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004043os_getpriority_impl(PyObject *module, int which, int who)
4044/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004045{
4046 int retval;
4047
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004048 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004049 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004050 if (errno != 0)
4051 return posix_error();
4052 return PyLong_FromLong((long)retval);
4053}
4054#endif /* HAVE_GETPRIORITY */
4055
4056
4057#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004058/*[clinic input]
4059os.setpriority
4060
4061 which: int
4062 who: int
4063 priority: int
4064
4065Set program scheduling priority.
4066[clinic start generated code]*/
4067
Larry Hastings2f936352014-08-05 14:04:04 +10004068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004069os_setpriority_impl(PyObject *module, int which, int who, int priority)
4070/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004071{
4072 int retval;
4073
4074 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004075 if (retval == -1)
4076 return posix_error();
4077 Py_RETURN_NONE;
4078}
4079#endif /* HAVE_SETPRIORITY */
4080
4081
Barry Warsaw53699e91996-12-10 23:23:01 +00004082static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004083internal_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 +00004084{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004085 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004086 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004087
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004088#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004089 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004090 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004091#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004092 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004093#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004094
Larry Hastings9cf065c2012-06-22 16:30:09 -07004095 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4096 (dst_dir_fd != DEFAULT_DIR_FD);
4097#ifndef HAVE_RENAMEAT
4098 if (dir_fd_specified) {
4099 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004100 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004101 }
4102#endif
4103
Larry Hastings9cf065c2012-06-22 16:30:09 -07004104#ifdef MS_WINDOWS
4105 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004106 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004107 Py_END_ALLOW_THREADS
4108
Larry Hastings2f936352014-08-05 14:04:04 +10004109 if (!result)
4110 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004111
4112#else
Steve Dowercc16be82016-09-08 10:35:16 -07004113 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4114 PyErr_Format(PyExc_ValueError,
4115 "%s: src and dst must be the same type", function_name);
4116 return NULL;
4117 }
4118
Larry Hastings9cf065c2012-06-22 16:30:09 -07004119 Py_BEGIN_ALLOW_THREADS
4120#ifdef HAVE_RENAMEAT
4121 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004122 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004123 else
4124#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004125 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004126 Py_END_ALLOW_THREADS
4127
Larry Hastings2f936352014-08-05 14:04:04 +10004128 if (result)
4129 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004130#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004131 Py_RETURN_NONE;
4132}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004133
Larry Hastings2f936352014-08-05 14:04:04 +10004134
4135/*[clinic input]
4136os.rename
4137
4138 src : path_t
4139 dst : path_t
4140 *
4141 src_dir_fd : dir_fd = None
4142 dst_dir_fd : dir_fd = None
4143
4144Rename a file or directory.
4145
4146If either src_dir_fd or dst_dir_fd is not None, it should be a file
4147 descriptor open to a directory, and the respective path string (src or dst)
4148 should be relative; the path will then be relative to that directory.
4149src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4150 If they are unavailable, using them will raise a NotImplementedError.
4151[clinic start generated code]*/
4152
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004153static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004154os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004155 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004156/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004157{
Larry Hastings2f936352014-08-05 14:04:04 +10004158 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004159}
4160
Larry Hastings2f936352014-08-05 14:04:04 +10004161
4162/*[clinic input]
4163os.replace = os.rename
4164
4165Rename a file or directory, overwriting the destination.
4166
4167If either src_dir_fd or dst_dir_fd is not None, it should be a file
4168 descriptor open to a directory, and the respective path string (src or dst)
4169 should be relative; the path will then be relative to that directory.
4170src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004171 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004172[clinic start generated code]*/
4173
Larry Hastings2f936352014-08-05 14:04:04 +10004174static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004175os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4176 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004177/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004178{
4179 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4180}
4181
4182
4183/*[clinic input]
4184os.rmdir
4185
4186 path: path_t
4187 *
4188 dir_fd: dir_fd(requires='unlinkat') = None
4189
4190Remove a directory.
4191
4192If dir_fd is not None, it should be a file descriptor open to a directory,
4193 and path should be relative; path will then be relative to that directory.
4194dir_fd may not be implemented on your platform.
4195 If it is unavailable, using it will raise a NotImplementedError.
4196[clinic start generated code]*/
4197
Larry Hastings2f936352014-08-05 14:04:04 +10004198static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004199os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4200/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004201{
4202 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004203
4204 Py_BEGIN_ALLOW_THREADS
4205#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004206 /* Windows, success=1, UNIX, success=0 */
4207 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004208#else
4209#ifdef HAVE_UNLINKAT
4210 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004211 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004212 else
4213#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004214 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004215#endif
4216 Py_END_ALLOW_THREADS
4217
Larry Hastings2f936352014-08-05 14:04:04 +10004218 if (result)
4219 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004220
Larry Hastings2f936352014-08-05 14:04:04 +10004221 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004222}
4223
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004224
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004225#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004226#ifdef MS_WINDOWS
4227/*[clinic input]
4228os.system -> long
4229
4230 command: Py_UNICODE
4231
4232Execute the command in a subshell.
4233[clinic start generated code]*/
4234
Larry Hastings2f936352014-08-05 14:04:04 +10004235static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004236os_system_impl(PyObject *module, const Py_UNICODE *command)
4237/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004238{
4239 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004240 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004241 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004242 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004243 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004244 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004245 return result;
4246}
4247#else /* MS_WINDOWS */
4248/*[clinic input]
4249os.system -> long
4250
4251 command: FSConverter
4252
4253Execute the command in a subshell.
4254[clinic start generated code]*/
4255
Larry Hastings2f936352014-08-05 14:04:04 +10004256static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004257os_system_impl(PyObject *module, PyObject *command)
4258/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004259{
4260 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004261 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004262 Py_BEGIN_ALLOW_THREADS
4263 result = system(bytes);
4264 Py_END_ALLOW_THREADS
4265 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004266}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004267#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004268#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004269
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004270
Larry Hastings2f936352014-08-05 14:04:04 +10004271/*[clinic input]
4272os.umask
4273
4274 mask: int
4275 /
4276
4277Set the current numeric umask and return the previous umask.
4278[clinic start generated code]*/
4279
Larry Hastings2f936352014-08-05 14:04:04 +10004280static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004281os_umask_impl(PyObject *module, int mask)
4282/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004283{
4284 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004285 if (i < 0)
4286 return posix_error();
4287 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004288}
4289
Brian Curtind40e6f72010-07-08 21:39:08 +00004290#ifdef MS_WINDOWS
4291
4292/* override the default DeleteFileW behavior so that directory
4293symlinks can be removed with this function, the same as with
4294Unix symlinks */
4295BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4296{
4297 WIN32_FILE_ATTRIBUTE_DATA info;
4298 WIN32_FIND_DATAW find_data;
4299 HANDLE find_data_handle;
4300 int is_directory = 0;
4301 int is_link = 0;
4302
4303 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4304 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004305
Brian Curtind40e6f72010-07-08 21:39:08 +00004306 /* Get WIN32_FIND_DATA structure for the path to determine if
4307 it is a symlink */
4308 if(is_directory &&
4309 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4310 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4311
4312 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004313 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4314 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4315 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4316 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004317 FindClose(find_data_handle);
4318 }
4319 }
4320 }
4321
4322 if (is_directory && is_link)
4323 return RemoveDirectoryW(lpFileName);
4324
4325 return DeleteFileW(lpFileName);
4326}
4327#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004329
Larry Hastings2f936352014-08-05 14:04:04 +10004330/*[clinic input]
4331os.unlink
4332
4333 path: path_t
4334 *
4335 dir_fd: dir_fd(requires='unlinkat')=None
4336
4337Remove a file (same as remove()).
4338
4339If dir_fd is not None, it should be a file descriptor open to a directory,
4340 and path should be relative; path will then be relative to that directory.
4341dir_fd may not be implemented on your platform.
4342 If it is unavailable, using it will raise a NotImplementedError.
4343
4344[clinic start generated code]*/
4345
Larry Hastings2f936352014-08-05 14:04:04 +10004346static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004347os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4348/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004349{
4350 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004351
4352 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004353 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004354#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004355 /* Windows, success=1, UNIX, success=0 */
4356 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004357#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004358#ifdef HAVE_UNLINKAT
4359 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004360 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004361 else
4362#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004363 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004364#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004365 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004366 Py_END_ALLOW_THREADS
4367
Larry Hastings2f936352014-08-05 14:04:04 +10004368 if (result)
4369 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004370
Larry Hastings2f936352014-08-05 14:04:04 +10004371 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004372}
4373
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004374
Larry Hastings2f936352014-08-05 14:04:04 +10004375/*[clinic input]
4376os.remove = os.unlink
4377
4378Remove a file (same as unlink()).
4379
4380If dir_fd is not None, it should be a file descriptor open to a directory,
4381 and path should be relative; path will then be relative to that directory.
4382dir_fd may not be implemented on your platform.
4383 If it is unavailable, using it will raise a NotImplementedError.
4384[clinic start generated code]*/
4385
Larry Hastings2f936352014-08-05 14:04:04 +10004386static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004387os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4388/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004389{
4390 return os_unlink_impl(module, path, dir_fd);
4391}
4392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004393
Larry Hastings605a62d2012-06-24 04:33:36 -07004394static PyStructSequence_Field uname_result_fields[] = {
4395 {"sysname", "operating system name"},
4396 {"nodename", "name of machine on network (implementation-defined)"},
4397 {"release", "operating system release"},
4398 {"version", "operating system version"},
4399 {"machine", "hardware identifier"},
4400 {NULL}
4401};
4402
4403PyDoc_STRVAR(uname_result__doc__,
4404"uname_result: Result from os.uname().\n\n\
4405This object may be accessed either as a tuple of\n\
4406 (sysname, nodename, release, version, machine),\n\
4407or via the attributes sysname, nodename, release, version, and machine.\n\
4408\n\
4409See os.uname for more information.");
4410
4411static PyStructSequence_Desc uname_result_desc = {
4412 "uname_result", /* name */
4413 uname_result__doc__, /* doc */
4414 uname_result_fields,
4415 5
4416};
4417
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004418static PyTypeObject* UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07004419
4420
4421#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004422/*[clinic input]
4423os.uname
4424
4425Return an object identifying the current operating system.
4426
4427The object behaves like a named tuple with the following fields:
4428 (sysname, nodename, release, version, machine)
4429
4430[clinic start generated code]*/
4431
Larry Hastings2f936352014-08-05 14:04:04 +10004432static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004433os_uname_impl(PyObject *module)
4434/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004435{
Victor Stinner8c62be82010-05-06 00:08:46 +00004436 struct utsname u;
4437 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004438 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004439
Victor Stinner8c62be82010-05-06 00:08:46 +00004440 Py_BEGIN_ALLOW_THREADS
4441 res = uname(&u);
4442 Py_END_ALLOW_THREADS
4443 if (res < 0)
4444 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004445
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004446 value = PyStructSequence_New(UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004447 if (value == NULL)
4448 return NULL;
4449
4450#define SET(i, field) \
4451 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004452 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004453 if (!o) { \
4454 Py_DECREF(value); \
4455 return NULL; \
4456 } \
4457 PyStructSequence_SET_ITEM(value, i, o); \
4458 } \
4459
4460 SET(0, u.sysname);
4461 SET(1, u.nodename);
4462 SET(2, u.release);
4463 SET(3, u.version);
4464 SET(4, u.machine);
4465
4466#undef SET
4467
4468 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004469}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004470#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004471
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004472
Larry Hastings9cf065c2012-06-22 16:30:09 -07004473
4474typedef struct {
4475 int now;
4476 time_t atime_s;
4477 long atime_ns;
4478 time_t mtime_s;
4479 long mtime_ns;
4480} utime_t;
4481
4482/*
Victor Stinner484df002014-10-09 13:52:31 +02004483 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004484 * they also intentionally leak the declaration of a pointer named "time"
4485 */
4486#define UTIME_TO_TIMESPEC \
4487 struct timespec ts[2]; \
4488 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004489 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004490 time = NULL; \
4491 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004492 ts[0].tv_sec = ut->atime_s; \
4493 ts[0].tv_nsec = ut->atime_ns; \
4494 ts[1].tv_sec = ut->mtime_s; \
4495 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004496 time = ts; \
4497 } \
4498
4499#define UTIME_TO_TIMEVAL \
4500 struct timeval tv[2]; \
4501 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004502 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004503 time = NULL; \
4504 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004505 tv[0].tv_sec = ut->atime_s; \
4506 tv[0].tv_usec = ut->atime_ns / 1000; \
4507 tv[1].tv_sec = ut->mtime_s; \
4508 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004509 time = tv; \
4510 } \
4511
4512#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004513 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004514 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004515 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004516 time = NULL; \
4517 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004518 u.actime = ut->atime_s; \
4519 u.modtime = ut->mtime_s; \
4520 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004521 }
4522
4523#define UTIME_TO_TIME_T \
4524 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004525 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004526 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004527 time = NULL; \
4528 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004529 timet[0] = ut->atime_s; \
4530 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004531 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004532 } \
4533
4534
Victor Stinner528a9ab2015-09-03 21:30:26 +02004535#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004536
4537static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004538utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004539{
4540#ifdef HAVE_UTIMENSAT
4541 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4542 UTIME_TO_TIMESPEC;
4543 return utimensat(dir_fd, path, time, flags);
4544#elif defined(HAVE_FUTIMESAT)
4545 UTIME_TO_TIMEVAL;
4546 /*
4547 * follow_symlinks will never be false here;
4548 * we only allow !follow_symlinks and dir_fd together
4549 * if we have utimensat()
4550 */
4551 assert(follow_symlinks);
4552 return futimesat(dir_fd, path, time);
4553#endif
4554}
4555
Larry Hastings2f936352014-08-05 14:04:04 +10004556 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4557#else
4558 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004559#endif
4560
Victor Stinner528a9ab2015-09-03 21:30:26 +02004561#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004562
4563static int
Victor Stinner484df002014-10-09 13:52:31 +02004564utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004565{
4566#ifdef HAVE_FUTIMENS
4567 UTIME_TO_TIMESPEC;
4568 return futimens(fd, time);
4569#else
4570 UTIME_TO_TIMEVAL;
4571 return futimes(fd, time);
4572#endif
4573}
4574
Larry Hastings2f936352014-08-05 14:04:04 +10004575 #define PATH_UTIME_HAVE_FD 1
4576#else
4577 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004578#endif
4579
Victor Stinner5ebae872015-09-22 01:29:33 +02004580#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4581# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4582#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004583
Victor Stinner4552ced2015-09-21 22:37:15 +02004584#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004585
4586static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004587utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588{
4589#ifdef HAVE_UTIMENSAT
4590 UTIME_TO_TIMESPEC;
4591 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4592#else
4593 UTIME_TO_TIMEVAL;
4594 return lutimes(path, time);
4595#endif
4596}
4597
4598#endif
4599
4600#ifndef MS_WINDOWS
4601
4602static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004603utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004604{
4605#ifdef HAVE_UTIMENSAT
4606 UTIME_TO_TIMESPEC;
4607 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4608#elif defined(HAVE_UTIMES)
4609 UTIME_TO_TIMEVAL;
4610 return utimes(path, time);
4611#elif defined(HAVE_UTIME_H)
4612 UTIME_TO_UTIMBUF;
4613 return utime(path, time);
4614#else
4615 UTIME_TO_TIME_T;
4616 return utime(path, time);
4617#endif
4618}
4619
4620#endif
4621
Larry Hastings76ad59b2012-05-03 00:30:07 -07004622static int
4623split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4624{
4625 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004626 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004627 divmod = PyNumber_Divmod(py_long, billion);
4628 if (!divmod)
4629 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004630 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4631 PyErr_Format(PyExc_TypeError,
4632 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4633 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4634 goto exit;
4635 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004636 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4637 if ((*s == -1) && PyErr_Occurred())
4638 goto exit;
4639 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004640 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004641 goto exit;
4642
4643 result = 1;
4644exit:
4645 Py_XDECREF(divmod);
4646 return result;
4647}
4648
Larry Hastings2f936352014-08-05 14:04:04 +10004649
4650/*[clinic input]
4651os.utime
4652
4653 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4654 times: object = NULL
4655 *
4656 ns: object = NULL
4657 dir_fd: dir_fd(requires='futimensat') = None
4658 follow_symlinks: bool=True
4659
Martin Panter0ff89092015-09-09 01:56:53 +00004660# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004661
4662Set the access and modified time of path.
4663
4664path may always be specified as a string.
4665On some platforms, path may also be specified as an open file descriptor.
4666 If this functionality is unavailable, using it raises an exception.
4667
4668If times is not None, it must be a tuple (atime, mtime);
4669 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004670If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004671 atime_ns and mtime_ns should be expressed as integer nanoseconds
4672 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004673If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004674Specifying tuples for both times and ns is an error.
4675
4676If dir_fd is not None, it should be a file descriptor open to a directory,
4677 and path should be relative; path will then be relative to that directory.
4678If follow_symlinks is False, and the last element of the path is a symbolic
4679 link, utime will modify the symbolic link itself instead of the file the
4680 link points to.
4681It is an error to use dir_fd or follow_symlinks when specifying path
4682 as an open file descriptor.
4683dir_fd and follow_symlinks may not be available on your platform.
4684 If they are unavailable, using them will raise a NotImplementedError.
4685
4686[clinic start generated code]*/
4687
Larry Hastings2f936352014-08-05 14:04:04 +10004688static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004689os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4690 int dir_fd, int follow_symlinks)
4691/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004692{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004693#ifdef MS_WINDOWS
4694 HANDLE hFile;
4695 FILETIME atime, mtime;
4696#else
4697 int result;
4698#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004699
Larry Hastings2f936352014-08-05 14:04:04 +10004700 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004701
Christian Heimesb3c87242013-08-01 00:08:16 +02004702 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004703
Larry Hastings9cf065c2012-06-22 16:30:09 -07004704 if (times && (times != Py_None) && ns) {
4705 PyErr_SetString(PyExc_ValueError,
4706 "utime: you may specify either 'times'"
4707 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004708 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004709 }
4710
4711 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004712 time_t a_sec, m_sec;
4713 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004714 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715 PyErr_SetString(PyExc_TypeError,
4716 "utime: 'times' must be either"
4717 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004718 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004719 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004721 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004722 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004723 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004724 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004725 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004726 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004727 utime.atime_s = a_sec;
4728 utime.atime_ns = a_nsec;
4729 utime.mtime_s = m_sec;
4730 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004731 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004733 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004734 PyErr_SetString(PyExc_TypeError,
4735 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004736 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004737 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004739 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004740 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004741 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004743 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004744 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 }
4746 else {
4747 /* times and ns are both None/unspecified. use "now". */
4748 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004749 }
4750
Victor Stinner4552ced2015-09-21 22:37:15 +02004751#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004752 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004753 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004754#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004755
Larry Hastings2f936352014-08-05 14:04:04 +10004756 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4757 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4758 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004759 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004760
Larry Hastings9cf065c2012-06-22 16:30:09 -07004761#if !defined(HAVE_UTIMENSAT)
4762 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004763 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004764 "utime: cannot use dir_fd and follow_symlinks "
4765 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004766 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004767 }
4768#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004769
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004770#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004771 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004772 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4773 NULL, OPEN_EXISTING,
4774 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004775 Py_END_ALLOW_THREADS
4776 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004777 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004778 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004779 }
4780
Larry Hastings9cf065c2012-06-22 16:30:09 -07004781 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004782 GetSystemTimeAsFileTime(&mtime);
4783 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004784 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004785 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004786 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4787 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004788 }
4789 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4790 /* Avoid putting the file name into the error here,
4791 as that may confuse the user into believing that
4792 something is wrong with the file, when it also
4793 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004794 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004795 CloseHandle(hFile);
4796 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004798 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004799#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004800 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004801
Victor Stinner4552ced2015-09-21 22:37:15 +02004802#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004803 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004804 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004805 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004806#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004807
Victor Stinner528a9ab2015-09-03 21:30:26 +02004808#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004810 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811 else
4812#endif
4813
Victor Stinner528a9ab2015-09-03 21:30:26 +02004814#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004815 if (path->fd != -1)
4816 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004817 else
4818#endif
4819
Larry Hastings2f936352014-08-05 14:04:04 +10004820 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004821
4822 Py_END_ALLOW_THREADS
4823
4824 if (result < 0) {
4825 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004826 posix_error();
4827 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004828 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004829
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004830#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004831
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004832 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004833}
4834
Guido van Rossum3b066191991-06-04 19:40:25 +00004835/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004836
Larry Hastings2f936352014-08-05 14:04:04 +10004837
4838/*[clinic input]
4839os._exit
4840
4841 status: int
4842
4843Exit to the system with specified status, without normal exit processing.
4844[clinic start generated code]*/
4845
Larry Hastings2f936352014-08-05 14:04:04 +10004846static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004847os__exit_impl(PyObject *module, int status)
4848/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004849{
4850 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004851 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004852}
4853
Steve Dowercc16be82016-09-08 10:35:16 -07004854#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4855#define EXECV_CHAR wchar_t
4856#else
4857#define EXECV_CHAR char
4858#endif
4859
Martin v. Löwis114619e2002-10-07 06:44:21 +00004860#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4861static void
Steve Dowercc16be82016-09-08 10:35:16 -07004862free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004863{
Victor Stinner8c62be82010-05-06 00:08:46 +00004864 Py_ssize_t i;
4865 for (i = 0; i < count; i++)
4866 PyMem_Free(array[i]);
4867 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004868}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004869
Berker Peksag81816462016-09-15 20:19:47 +03004870static int
4871fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004872{
Victor Stinner8c62be82010-05-06 00:08:46 +00004873 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004874 PyObject *ub;
4875 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004876#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004877 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004878 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004879 *out = PyUnicode_AsWideCharString(ub, &size);
4880 if (*out)
4881 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004882#else
Berker Peksag81816462016-09-15 20:19:47 +03004883 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004884 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004885 size = PyBytes_GET_SIZE(ub);
4886 *out = PyMem_Malloc(size + 1);
4887 if (*out) {
4888 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4889 result = 1;
4890 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004891 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004892#endif
Berker Peksag81816462016-09-15 20:19:47 +03004893 Py_DECREF(ub);
4894 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004895}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004896#endif
4897
Ross Lagerwall7807c352011-03-17 20:20:30 +02004898#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004899static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004900parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4901{
Victor Stinner8c62be82010-05-06 00:08:46 +00004902 Py_ssize_t i, pos, envc;
4903 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004904 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004905 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004906
Victor Stinner8c62be82010-05-06 00:08:46 +00004907 i = PyMapping_Size(env);
4908 if (i < 0)
4909 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004910 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004911 if (envlist == NULL) {
4912 PyErr_NoMemory();
4913 return NULL;
4914 }
4915 envc = 0;
4916 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004917 if (!keys)
4918 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004919 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004920 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 goto error;
4922 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4923 PyErr_Format(PyExc_TypeError,
4924 "env.keys() or env.values() is not a list");
4925 goto error;
4926 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004927
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 for (pos = 0; pos < i; pos++) {
4929 key = PyList_GetItem(keys, pos);
4930 val = PyList_GetItem(vals, pos);
4931 if (!key || !val)
4932 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004933
Berker Peksag81816462016-09-15 20:19:47 +03004934#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4935 if (!PyUnicode_FSDecoder(key, &key2))
4936 goto error;
4937 if (!PyUnicode_FSDecoder(val, &val2)) {
4938 Py_DECREF(key2);
4939 goto error;
4940 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004941 /* Search from index 1 because on Windows starting '=' is allowed for
4942 defining hidden environment variables. */
4943 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4944 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4945 {
4946 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004947 Py_DECREF(key2);
4948 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004949 goto error;
4950 }
Berker Peksag81816462016-09-15 20:19:47 +03004951 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4952#else
4953 if (!PyUnicode_FSConverter(key, &key2))
4954 goto error;
4955 if (!PyUnicode_FSConverter(val, &val2)) {
4956 Py_DECREF(key2);
4957 goto error;
4958 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004959 if (PyBytes_GET_SIZE(key2) == 0 ||
4960 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4961 {
4962 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004963 Py_DECREF(key2);
4964 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004965 goto error;
4966 }
Berker Peksag81816462016-09-15 20:19:47 +03004967 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4968 PyBytes_AS_STRING(val2));
4969#endif
4970 Py_DECREF(key2);
4971 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004972 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004974
4975 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4976 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 goto error;
4978 }
Berker Peksag81816462016-09-15 20:19:47 +03004979
Steve Dowercc16be82016-09-08 10:35:16 -07004980 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 }
4982 Py_DECREF(vals);
4983 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004984
Victor Stinner8c62be82010-05-06 00:08:46 +00004985 envlist[envc] = 0;
4986 *envc_ptr = envc;
4987 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004988
4989error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 Py_XDECREF(keys);
4991 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004992 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004994}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004995
Steve Dowercc16be82016-09-08 10:35:16 -07004996static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004997parse_arglist(PyObject* argv, Py_ssize_t *argc)
4998{
4999 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005000 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005001 if (argvlist == NULL) {
5002 PyErr_NoMemory();
5003 return NULL;
5004 }
5005 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005006 PyObject* item = PySequence_ITEM(argv, i);
5007 if (item == NULL)
5008 goto fail;
5009 if (!fsconvert_strdup(item, &argvlist[i])) {
5010 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005011 goto fail;
5012 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005013 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005014 }
5015 argvlist[*argc] = NULL;
5016 return argvlist;
5017fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005018 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005019 free_string_array(argvlist, *argc);
5020 return NULL;
5021}
Steve Dowercc16be82016-09-08 10:35:16 -07005022
Ross Lagerwall7807c352011-03-17 20:20:30 +02005023#endif
5024
Larry Hastings2f936352014-08-05 14:04:04 +10005025
Ross Lagerwall7807c352011-03-17 20:20:30 +02005026#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005027/*[clinic input]
5028os.execv
5029
Steve Dowercc16be82016-09-08 10:35:16 -07005030 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005031 Path of executable file.
5032 argv: object
5033 Tuple or list of strings.
5034 /
5035
5036Execute an executable path with arguments, replacing current process.
5037[clinic start generated code]*/
5038
Larry Hastings2f936352014-08-05 14:04:04 +10005039static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005040os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5041/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005042{
Steve Dowercc16be82016-09-08 10:35:16 -07005043 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005044 Py_ssize_t argc;
5045
5046 /* execv has two arguments: (path, argv), where
5047 argv is a list or tuple of strings. */
5048
Ross Lagerwall7807c352011-03-17 20:20:30 +02005049 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5050 PyErr_SetString(PyExc_TypeError,
5051 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005052 return NULL;
5053 }
5054 argc = PySequence_Size(argv);
5055 if (argc < 1) {
5056 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005057 return NULL;
5058 }
5059
5060 argvlist = parse_arglist(argv, &argc);
5061 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005062 return NULL;
5063 }
Steve Dowerbce26262016-11-19 19:17:26 -08005064 if (!argvlist[0][0]) {
5065 PyErr_SetString(PyExc_ValueError,
5066 "execv() arg 2 first element cannot be empty");
5067 free_string_array(argvlist, argc);
5068 return NULL;
5069 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005070
Steve Dowerbce26262016-11-19 19:17:26 -08005071 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005072#ifdef HAVE_WEXECV
5073 _wexecv(path->wide, argvlist);
5074#else
5075 execv(path->narrow, argvlist);
5076#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005077 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005078
5079 /* If we get here it's definitely an error */
5080
5081 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005082 return posix_error();
5083}
5084
Larry Hastings2f936352014-08-05 14:04:04 +10005085
5086/*[clinic input]
5087os.execve
5088
5089 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5090 Path of executable file.
5091 argv: object
5092 Tuple or list of strings.
5093 env: object
5094 Dictionary of strings mapping to strings.
5095
5096Execute an executable path with arguments, replacing current process.
5097[clinic start generated code]*/
5098
Larry Hastings2f936352014-08-05 14:04:04 +10005099static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005100os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5101/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005102{
Steve Dowercc16be82016-09-08 10:35:16 -07005103 EXECV_CHAR **argvlist = NULL;
5104 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005105 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005106
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 /* execve has three arguments: (path, argv, env), where
5108 argv is a list or tuple of strings and env is a dictionary
5109 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005110
Ross Lagerwall7807c352011-03-17 20:20:30 +02005111 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005112 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005113 "execve: argv must be a tuple or list");
5114 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005115 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005116 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005117 if (argc < 1) {
5118 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5119 return NULL;
5120 }
5121
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 if (!PyMapping_Check(env)) {
5123 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005124 "execve: environment must be a mapping object");
5125 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005127
Ross Lagerwall7807c352011-03-17 20:20:30 +02005128 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005129 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005130 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 }
Steve Dowerbce26262016-11-19 19:17:26 -08005132 if (!argvlist[0][0]) {
5133 PyErr_SetString(PyExc_ValueError,
5134 "execve: argv first element cannot be empty");
5135 goto fail;
5136 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005137
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 envlist = parse_envlist(env, &envc);
5139 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005140 goto fail;
5141
Steve Dowerbce26262016-11-19 19:17:26 -08005142 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005143#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005144 if (path->fd > -1)
5145 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005146 else
5147#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005148#ifdef HAVE_WEXECV
5149 _wexecve(path->wide, argvlist, envlist);
5150#else
Larry Hastings2f936352014-08-05 14:04:04 +10005151 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005152#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005153 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005154
5155 /* If we get here it's definitely an error */
5156
Alexey Izbyshev83460312018-10-20 03:28:22 +03005157 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005158
Steve Dowercc16be82016-09-08 10:35:16 -07005159 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005160 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005161 if (argvlist)
5162 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005163 return NULL;
5164}
Steve Dowercc16be82016-09-08 10:35:16 -07005165
Larry Hastings9cf065c2012-06-22 16:30:09 -07005166#endif /* HAVE_EXECV */
5167
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005168#ifdef HAVE_POSIX_SPAWN
5169
5170enum posix_spawn_file_actions_identifier {
5171 POSIX_SPAWN_OPEN,
5172 POSIX_SPAWN_CLOSE,
5173 POSIX_SPAWN_DUP2
5174};
5175
William Orr81574b82018-10-01 22:19:56 -07005176#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005177static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005178convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005179#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005180
5181static int
Victor Stinner325e4ba2019-02-01 15:47:24 +01005182parse_posix_spawn_flags(const char *func_name, PyObject *setpgroup,
5183 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005184 PyObject *setsigdef, PyObject *scheduler,
5185 posix_spawnattr_t *attrp)
5186{
5187 long all_flags = 0;
5188
5189 errno = posix_spawnattr_init(attrp);
5190 if (errno) {
5191 posix_error();
5192 return -1;
5193 }
5194
5195 if (setpgroup) {
5196 pid_t pgid = PyLong_AsPid(setpgroup);
5197 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5198 goto fail;
5199 }
5200 errno = posix_spawnattr_setpgroup(attrp, pgid);
5201 if (errno) {
5202 posix_error();
5203 goto fail;
5204 }
5205 all_flags |= POSIX_SPAWN_SETPGROUP;
5206 }
5207
5208 if (resetids) {
5209 all_flags |= POSIX_SPAWN_RESETIDS;
5210 }
5211
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005212 if (setsid) {
5213#ifdef POSIX_SPAWN_SETSID
5214 all_flags |= POSIX_SPAWN_SETSID;
5215#elif defined(POSIX_SPAWN_SETSID_NP)
5216 all_flags |= POSIX_SPAWN_SETSID_NP;
5217#else
5218 argument_unavailable_error(func_name, "setsid");
5219 return -1;
5220#endif
5221 }
5222
Pablo Galindo254a4662018-09-07 16:44:24 +01005223 if (setsigmask) {
5224 sigset_t set;
5225 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5226 goto fail;
5227 }
5228 errno = posix_spawnattr_setsigmask(attrp, &set);
5229 if (errno) {
5230 posix_error();
5231 goto fail;
5232 }
5233 all_flags |= POSIX_SPAWN_SETSIGMASK;
5234 }
5235
5236 if (setsigdef) {
5237 sigset_t set;
5238 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5239 goto fail;
5240 }
5241 errno = posix_spawnattr_setsigdefault(attrp, &set);
5242 if (errno) {
5243 posix_error();
5244 goto fail;
5245 }
5246 all_flags |= POSIX_SPAWN_SETSIGDEF;
5247 }
5248
5249 if (scheduler) {
5250#ifdef POSIX_SPAWN_SETSCHEDULER
5251 PyObject *py_schedpolicy;
5252 struct sched_param schedparam;
5253
5254 if (!PyArg_ParseTuple(scheduler, "OO&"
5255 ";A scheduler tuple must have two elements",
5256 &py_schedpolicy, convert_sched_param, &schedparam)) {
5257 goto fail;
5258 }
5259 if (py_schedpolicy != Py_None) {
5260 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5261
5262 if (schedpolicy == -1 && PyErr_Occurred()) {
5263 goto fail;
5264 }
5265 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5266 if (errno) {
5267 posix_error();
5268 goto fail;
5269 }
5270 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5271 }
5272 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5273 if (errno) {
5274 posix_error();
5275 goto fail;
5276 }
5277 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5278#else
5279 PyErr_SetString(PyExc_NotImplementedError,
5280 "The scheduler option is not supported in this system.");
5281 goto fail;
5282#endif
5283 }
5284
5285 errno = posix_spawnattr_setflags(attrp, all_flags);
5286 if (errno) {
5287 posix_error();
5288 goto fail;
5289 }
5290
5291 return 0;
5292
5293fail:
5294 (void)posix_spawnattr_destroy(attrp);
5295 return -1;
5296}
5297
5298static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005299parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005300 posix_spawn_file_actions_t *file_actionsp,
5301 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005302{
5303 PyObject *seq;
5304 PyObject *file_action = NULL;
5305 PyObject *tag_obj;
5306
5307 seq = PySequence_Fast(file_actions,
5308 "file_actions must be a sequence or None");
5309 if (seq == NULL) {
5310 return -1;
5311 }
5312
5313 errno = posix_spawn_file_actions_init(file_actionsp);
5314 if (errno) {
5315 posix_error();
5316 Py_DECREF(seq);
5317 return -1;
5318 }
5319
5320 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5321 file_action = PySequence_Fast_GET_ITEM(seq, i);
5322 Py_INCREF(file_action);
5323 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5324 PyErr_SetString(PyExc_TypeError,
5325 "Each file_actions element must be a non-empty tuple");
5326 goto fail;
5327 }
5328 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5329 if (tag == -1 && PyErr_Occurred()) {
5330 goto fail;
5331 }
5332
5333 /* Populate the file_actions object */
5334 switch (tag) {
5335 case POSIX_SPAWN_OPEN: {
5336 int fd, oflag;
5337 PyObject *path;
5338 unsigned long mode;
5339 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5340 ";A open file_action tuple must have 5 elements",
5341 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5342 &oflag, &mode))
5343 {
5344 goto fail;
5345 }
Pablo Galindocb970732018-06-19 09:19:50 +01005346 if (PyList_Append(temp_buffer, path)) {
5347 Py_DECREF(path);
5348 goto fail;
5349 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005350 errno = posix_spawn_file_actions_addopen(file_actionsp,
5351 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005352 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005353 if (errno) {
5354 posix_error();
5355 goto fail;
5356 }
5357 break;
5358 }
5359 case POSIX_SPAWN_CLOSE: {
5360 int fd;
5361 if (!PyArg_ParseTuple(file_action, "Oi"
5362 ";A close file_action tuple must have 2 elements",
5363 &tag_obj, &fd))
5364 {
5365 goto fail;
5366 }
5367 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5368 if (errno) {
5369 posix_error();
5370 goto fail;
5371 }
5372 break;
5373 }
5374 case POSIX_SPAWN_DUP2: {
5375 int fd1, fd2;
5376 if (!PyArg_ParseTuple(file_action, "Oii"
5377 ";A dup2 file_action tuple must have 3 elements",
5378 &tag_obj, &fd1, &fd2))
5379 {
5380 goto fail;
5381 }
5382 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5383 fd1, fd2);
5384 if (errno) {
5385 posix_error();
5386 goto fail;
5387 }
5388 break;
5389 }
5390 default: {
5391 PyErr_SetString(PyExc_TypeError,
5392 "Unknown file_actions identifier");
5393 goto fail;
5394 }
5395 }
5396 Py_DECREF(file_action);
5397 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005398
Serhiy Storchakaef347532018-05-01 16:45:04 +03005399 Py_DECREF(seq);
5400 return 0;
5401
5402fail:
5403 Py_DECREF(seq);
5404 Py_DECREF(file_action);
5405 (void)posix_spawn_file_actions_destroy(file_actionsp);
5406 return -1;
5407}
5408
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005409
5410static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005411py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5412 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005413 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005414 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005415{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005416 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005417 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005418 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005419 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005420 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005421 posix_spawnattr_t attr;
5422 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005423 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005424 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005425 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005426 pid_t pid;
5427 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005428
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005429 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005430 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005431 like posix.environ. */
5432
Serhiy Storchakaef347532018-05-01 16:45:04 +03005433 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005434 PyErr_Format(PyExc_TypeError,
5435 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005436 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005437 }
5438 argc = PySequence_Size(argv);
5439 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005440 PyErr_Format(PyExc_ValueError,
5441 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005442 return NULL;
5443 }
5444
5445 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005446 PyErr_Format(PyExc_TypeError,
5447 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005448 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005449 }
5450
5451 argvlist = parse_arglist(argv, &argc);
5452 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005453 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005454 }
5455 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005456 PyErr_Format(PyExc_ValueError,
5457 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005458 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005459 }
5460
5461 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005462 if (envlist == NULL) {
5463 goto exit;
5464 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005465
Serhiy Storchakad700f972018-09-08 14:48:18 +03005466 if (file_actions != NULL) {
Pablo Galindocb970732018-06-19 09:19:50 +01005467 /* There is a bug in old versions of glibc that makes some of the
5468 * helper functions for manipulating file actions not copy the provided
5469 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5470 * copy the value of path for some old versions of glibc (<2.20).
5471 * The use of temp_buffer here is a workaround that keeps the
5472 * python objects that own the buffers alive until posix_spawn gets called.
5473 * Check https://bugs.python.org/issue33630 and
5474 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5475 temp_buffer = PyList_New(0);
5476 if (!temp_buffer) {
5477 goto exit;
5478 }
5479 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005480 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005481 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005482 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005483 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005484
Victor Stinner325e4ba2019-02-01 15:47:24 +01005485 if (parse_posix_spawn_flags(func_name, setpgroup, resetids, setsid,
5486 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005487 goto exit;
5488 }
5489 attrp = &attr;
5490
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005491 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005492#ifdef HAVE_POSIX_SPAWNP
5493 if (use_posix_spawnp) {
5494 err_code = posix_spawnp(&pid, path->narrow,
5495 file_actionsp, attrp, argvlist, envlist);
5496 }
5497 else
5498#endif /* HAVE_POSIX_SPAWNP */
5499 {
5500 err_code = posix_spawn(&pid, path->narrow,
5501 file_actionsp, attrp, argvlist, envlist);
5502 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005503 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005504
Serhiy Storchakaef347532018-05-01 16:45:04 +03005505 if (err_code) {
5506 errno = err_code;
5507 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005508 goto exit;
5509 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005510#ifdef _Py_MEMORY_SANITIZER
5511 __msan_unpoison(&pid, sizeof(pid));
5512#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005513 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005514
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005515exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005516 if (file_actionsp) {
5517 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005518 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005519 if (attrp) {
5520 (void)posix_spawnattr_destroy(attrp);
5521 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005522 if (envlist) {
5523 free_string_array(envlist, envc);
5524 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005525 if (argvlist) {
5526 free_string_array(argvlist, argc);
5527 }
Pablo Galindocb970732018-06-19 09:19:50 +01005528 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005529 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005530}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005531
5532
5533/*[clinic input]
5534
5535os.posix_spawn
5536 path: path_t
5537 Path of executable file.
5538 argv: object
5539 Tuple or list of strings.
5540 env: object
5541 Dictionary of strings mapping to strings.
5542 /
5543 *
5544 file_actions: object(c_default='NULL') = ()
5545 A sequence of file action tuples.
5546 setpgroup: object = NULL
5547 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5548 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005549 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5550 setsid: bool(accept={int}) = False
5551 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005552 setsigmask: object(c_default='NULL') = ()
5553 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5554 setsigdef: object(c_default='NULL') = ()
5555 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5556 scheduler: object = NULL
5557 A tuple with the scheduler policy (optional) and parameters.
5558
5559Execute the program specified by path in a new process.
5560[clinic start generated code]*/
5561
5562static PyObject *
5563os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5564 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005565 PyObject *setpgroup, int resetids, int setsid,
5566 PyObject *setsigmask, PyObject *setsigdef,
5567 PyObject *scheduler)
5568/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005569{
5570 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005571 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005572 scheduler);
5573}
5574 #endif /* HAVE_POSIX_SPAWN */
5575
5576
5577
5578#ifdef HAVE_POSIX_SPAWNP
5579/*[clinic input]
5580
5581os.posix_spawnp
5582 path: path_t
5583 Path of executable file.
5584 argv: object
5585 Tuple or list of strings.
5586 env: object
5587 Dictionary of strings mapping to strings.
5588 /
5589 *
5590 file_actions: object(c_default='NULL') = ()
5591 A sequence of file action tuples.
5592 setpgroup: object = NULL
5593 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5594 resetids: bool(accept={int}) = False
5595 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005596 setsid: bool(accept={int}) = False
5597 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005598 setsigmask: object(c_default='NULL') = ()
5599 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5600 setsigdef: object(c_default='NULL') = ()
5601 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5602 scheduler: object = NULL
5603 A tuple with the scheduler policy (optional) and parameters.
5604
5605Execute the program specified by path in a new process.
5606[clinic start generated code]*/
5607
5608static PyObject *
5609os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5610 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005611 PyObject *setpgroup, int resetids, int setsid,
5612 PyObject *setsigmask, PyObject *setsigdef,
5613 PyObject *scheduler)
5614/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005615{
5616 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005617 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005618 scheduler);
5619}
5620#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005622
Steve Dowercc16be82016-09-08 10:35:16 -07005623#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005624/*[clinic input]
5625os.spawnv
5626
5627 mode: int
5628 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005629 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005630 Path of executable file.
5631 argv: object
5632 Tuple or list of strings.
5633 /
5634
5635Execute the program specified by path in a new process.
5636[clinic start generated code]*/
5637
Larry Hastings2f936352014-08-05 14:04:04 +10005638static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005639os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5640/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005641{
Steve Dowercc16be82016-09-08 10:35:16 -07005642 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005643 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005644 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005645 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005646 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005647
Victor Stinner8c62be82010-05-06 00:08:46 +00005648 /* spawnv has three arguments: (mode, path, argv), where
5649 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005650
Victor Stinner8c62be82010-05-06 00:08:46 +00005651 if (PyList_Check(argv)) {
5652 argc = PyList_Size(argv);
5653 getitem = PyList_GetItem;
5654 }
5655 else if (PyTuple_Check(argv)) {
5656 argc = PyTuple_Size(argv);
5657 getitem = PyTuple_GetItem;
5658 }
5659 else {
5660 PyErr_SetString(PyExc_TypeError,
5661 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005662 return NULL;
5663 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005664 if (argc == 0) {
5665 PyErr_SetString(PyExc_ValueError,
5666 "spawnv() arg 2 cannot be empty");
5667 return NULL;
5668 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005669
Steve Dowercc16be82016-09-08 10:35:16 -07005670 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005671 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005672 return PyErr_NoMemory();
5673 }
5674 for (i = 0; i < argc; i++) {
5675 if (!fsconvert_strdup((*getitem)(argv, i),
5676 &argvlist[i])) {
5677 free_string_array(argvlist, i);
5678 PyErr_SetString(
5679 PyExc_TypeError,
5680 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005681 return NULL;
5682 }
Steve Dower93ff8722016-11-19 19:03:54 -08005683 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005684 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005685 PyErr_SetString(
5686 PyExc_ValueError,
5687 "spawnv() arg 2 first element cannot be empty");
5688 return NULL;
5689 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005690 }
5691 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005692
Victor Stinner8c62be82010-05-06 00:08:46 +00005693 if (mode == _OLD_P_OVERLAY)
5694 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005695
Victor Stinner8c62be82010-05-06 00:08:46 +00005696 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005697 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005698#ifdef HAVE_WSPAWNV
5699 spawnval = _wspawnv(mode, path->wide, argvlist);
5700#else
5701 spawnval = _spawnv(mode, path->narrow, argvlist);
5702#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005703 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005704 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005705
Victor Stinner8c62be82010-05-06 00:08:46 +00005706 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005707
Victor Stinner8c62be82010-05-06 00:08:46 +00005708 if (spawnval == -1)
5709 return posix_error();
5710 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005711 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005712}
5713
Larry Hastings2f936352014-08-05 14:04:04 +10005714/*[clinic input]
5715os.spawnve
5716
5717 mode: int
5718 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005719 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005720 Path of executable file.
5721 argv: object
5722 Tuple or list of strings.
5723 env: object
5724 Dictionary of strings mapping to strings.
5725 /
5726
5727Execute the program specified by path in a new process.
5728[clinic start generated code]*/
5729
Larry Hastings2f936352014-08-05 14:04:04 +10005730static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005731os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005732 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005733/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005734{
Steve Dowercc16be82016-09-08 10:35:16 -07005735 EXECV_CHAR **argvlist;
5736 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005737 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005738 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005739 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005740 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005741 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005742
Victor Stinner8c62be82010-05-06 00:08:46 +00005743 /* spawnve has four arguments: (mode, path, argv, env), where
5744 argv is a list or tuple of strings and env is a dictionary
5745 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005746
Victor Stinner8c62be82010-05-06 00:08:46 +00005747 if (PyList_Check(argv)) {
5748 argc = PyList_Size(argv);
5749 getitem = PyList_GetItem;
5750 }
5751 else if (PyTuple_Check(argv)) {
5752 argc = PyTuple_Size(argv);
5753 getitem = PyTuple_GetItem;
5754 }
5755 else {
5756 PyErr_SetString(PyExc_TypeError,
5757 "spawnve() arg 2 must be a tuple or list");
5758 goto fail_0;
5759 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005760 if (argc == 0) {
5761 PyErr_SetString(PyExc_ValueError,
5762 "spawnve() arg 2 cannot be empty");
5763 goto fail_0;
5764 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005765 if (!PyMapping_Check(env)) {
5766 PyErr_SetString(PyExc_TypeError,
5767 "spawnve() arg 3 must be a mapping object");
5768 goto fail_0;
5769 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005770
Steve Dowercc16be82016-09-08 10:35:16 -07005771 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005772 if (argvlist == NULL) {
5773 PyErr_NoMemory();
5774 goto fail_0;
5775 }
5776 for (i = 0; i < argc; i++) {
5777 if (!fsconvert_strdup((*getitem)(argv, i),
5778 &argvlist[i]))
5779 {
5780 lastarg = i;
5781 goto fail_1;
5782 }
Steve Dowerbce26262016-11-19 19:17:26 -08005783 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005784 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005785 PyErr_SetString(
5786 PyExc_ValueError,
5787 "spawnv() arg 2 first element cannot be empty");
5788 goto fail_1;
5789 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005790 }
5791 lastarg = argc;
5792 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005793
Victor Stinner8c62be82010-05-06 00:08:46 +00005794 envlist = parse_envlist(env, &envc);
5795 if (envlist == NULL)
5796 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005797
Victor Stinner8c62be82010-05-06 00:08:46 +00005798 if (mode == _OLD_P_OVERLAY)
5799 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005800
Victor Stinner8c62be82010-05-06 00:08:46 +00005801 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005802 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005803#ifdef HAVE_WSPAWNV
5804 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5805#else
5806 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5807#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005808 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005809 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005810
Victor Stinner8c62be82010-05-06 00:08:46 +00005811 if (spawnval == -1)
5812 (void) posix_error();
5813 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005814 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005815
Victor Stinner8c62be82010-05-06 00:08:46 +00005816 while (--envc >= 0)
5817 PyMem_DEL(envlist[envc]);
5818 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005819 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005820 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005821 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005822 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005823}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005824
Guido van Rossuma1065681999-01-25 23:20:23 +00005825#endif /* HAVE_SPAWNV */
5826
5827
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005828#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005829
5830/* Helper function to validate arguments.
5831 Returns 0 on success. non-zero on failure with a TypeError raised.
5832 If obj is non-NULL it must be callable. */
5833static int
5834check_null_or_callable(PyObject *obj, const char* obj_name)
5835{
5836 if (obj && !PyCallable_Check(obj)) {
5837 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5838 obj_name, Py_TYPE(obj)->tp_name);
5839 return -1;
5840 }
5841 return 0;
5842}
5843
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005844/*[clinic input]
5845os.register_at_fork
5846
Gregory P. Smith163468a2017-05-29 10:03:41 -07005847 *
5848 before: object=NULL
5849 A callable to be called in the parent before the fork() syscall.
5850 after_in_child: object=NULL
5851 A callable to be called in the child after fork().
5852 after_in_parent: object=NULL
5853 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005854
Gregory P. Smith163468a2017-05-29 10:03:41 -07005855Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005856
Gregory P. Smith163468a2017-05-29 10:03:41 -07005857'before' callbacks are called in reverse order.
5858'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005859
5860[clinic start generated code]*/
5861
5862static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005863os_register_at_fork_impl(PyObject *module, PyObject *before,
5864 PyObject *after_in_child, PyObject *after_in_parent)
5865/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005866{
5867 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005868
Gregory P. Smith163468a2017-05-29 10:03:41 -07005869 if (!before && !after_in_child && !after_in_parent) {
5870 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5871 return NULL;
5872 }
5873 if (check_null_or_callable(before, "before") ||
5874 check_null_or_callable(after_in_child, "after_in_child") ||
5875 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005876 return NULL;
5877 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02005878 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005879
Gregory P. Smith163468a2017-05-29 10:03:41 -07005880 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005881 return NULL;
5882 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005883 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005884 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005885 }
5886 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5887 return NULL;
5888 }
5889 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005890}
5891#endif /* HAVE_FORK */
5892
5893
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005894#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005895/*[clinic input]
5896os.fork1
5897
5898Fork a child process with a single multiplexed (i.e., not bound) thread.
5899
5900Return 0 to child process and PID of child to parent process.
5901[clinic start generated code]*/
5902
Larry Hastings2f936352014-08-05 14:04:04 +10005903static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005904os_fork1_impl(PyObject *module)
5905/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005906{
Victor Stinner8c62be82010-05-06 00:08:46 +00005907 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005908
Eric Snow59032962018-09-14 14:17:20 -07005909 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5910 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5911 return NULL;
5912 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005913 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005914 pid = fork1();
5915 if (pid == 0) {
5916 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005917 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 } else {
5919 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005920 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005921 }
5922 if (pid == -1)
5923 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005924 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005925}
Larry Hastings2f936352014-08-05 14:04:04 +10005926#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005927
5928
Guido van Rossumad0ee831995-03-01 10:34:45 +00005929#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005930/*[clinic input]
5931os.fork
5932
5933Fork a child process.
5934
5935Return 0 to child process and PID of child to parent process.
5936[clinic start generated code]*/
5937
Larry Hastings2f936352014-08-05 14:04:04 +10005938static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005939os_fork_impl(PyObject *module)
5940/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005941{
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005943
Eric Snow59032962018-09-14 14:17:20 -07005944 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5945 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5946 return NULL;
5947 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005948 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005949 pid = fork();
5950 if (pid == 0) {
5951 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005952 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005953 } else {
5954 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005955 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005956 }
5957 if (pid == -1)
5958 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005959 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005960}
Larry Hastings2f936352014-08-05 14:04:04 +10005961#endif /* HAVE_FORK */
5962
Guido van Rossum85e3b011991-06-03 12:42:10 +00005963
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005964#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005965#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005966/*[clinic input]
5967os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005968
Larry Hastings2f936352014-08-05 14:04:04 +10005969 policy: int
5970
5971Get the maximum scheduling priority for policy.
5972[clinic start generated code]*/
5973
Larry Hastings2f936352014-08-05 14:04:04 +10005974static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005975os_sched_get_priority_max_impl(PyObject *module, int policy)
5976/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005977{
5978 int max;
5979
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005980 max = sched_get_priority_max(policy);
5981 if (max < 0)
5982 return posix_error();
5983 return PyLong_FromLong(max);
5984}
5985
Larry Hastings2f936352014-08-05 14:04:04 +10005986
5987/*[clinic input]
5988os.sched_get_priority_min
5989
5990 policy: int
5991
5992Get the minimum scheduling priority for policy.
5993[clinic start generated code]*/
5994
Larry Hastings2f936352014-08-05 14:04:04 +10005995static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005996os_sched_get_priority_min_impl(PyObject *module, int policy)
5997/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005998{
5999 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006000 if (min < 0)
6001 return posix_error();
6002 return PyLong_FromLong(min);
6003}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006004#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6005
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006006
Larry Hastings2f936352014-08-05 14:04:04 +10006007#ifdef HAVE_SCHED_SETSCHEDULER
6008/*[clinic input]
6009os.sched_getscheduler
6010 pid: pid_t
6011 /
6012
6013Get the scheduling policy for the process identifiedy by pid.
6014
6015Passing 0 for pid returns the scheduling policy for the calling process.
6016[clinic start generated code]*/
6017
Larry Hastings2f936352014-08-05 14:04:04 +10006018static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006019os_sched_getscheduler_impl(PyObject *module, pid_t pid)
6020/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006021{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006022 int policy;
6023
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006024 policy = sched_getscheduler(pid);
6025 if (policy < 0)
6026 return posix_error();
6027 return PyLong_FromLong(policy);
6028}
Larry Hastings2f936352014-08-05 14:04:04 +10006029#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006030
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006031
William Orr81574b82018-10-01 22:19:56 -07006032#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006033/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006034class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006035
6036@classmethod
6037os.sched_param.__new__
6038
6039 sched_priority: object
6040 A scheduling parameter.
6041
6042Current has only one field: sched_priority");
6043[clinic start generated code]*/
6044
Larry Hastings2f936352014-08-05 14:04:04 +10006045static PyObject *
6046os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006047/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006048{
6049 PyObject *res;
6050
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006051 res = PyStructSequence_New(type);
6052 if (!res)
6053 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006054 Py_INCREF(sched_priority);
6055 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006056 return res;
6057}
6058
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006059
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006060PyDoc_VAR(os_sched_param__doc__);
6061
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006062static PyStructSequence_Field sched_param_fields[] = {
6063 {"sched_priority", "the scheduling priority"},
6064 {0}
6065};
6066
6067static PyStructSequence_Desc sched_param_desc = {
6068 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006069 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006070 sched_param_fields,
6071 1
6072};
6073
6074static int
6075convert_sched_param(PyObject *param, struct sched_param *res)
6076{
6077 long priority;
6078
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006079 if (Py_TYPE(param) != SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006080 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6081 return 0;
6082 }
6083 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6084 if (priority == -1 && PyErr_Occurred())
6085 return 0;
6086 if (priority > INT_MAX || priority < INT_MIN) {
6087 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6088 return 0;
6089 }
6090 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6091 return 1;
6092}
William Orr81574b82018-10-01 22:19:56 -07006093#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006094
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006095
6096#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006097/*[clinic input]
6098os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006099
Larry Hastings2f936352014-08-05 14:04:04 +10006100 pid: pid_t
6101 policy: int
6102 param: sched_param
6103 /
6104
6105Set the scheduling policy for the process identified by pid.
6106
6107If pid is 0, the calling process is changed.
6108param is an instance of sched_param.
6109[clinic start generated code]*/
6110
Larry Hastings2f936352014-08-05 14:04:04 +10006111static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006112os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006113 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006114/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006115{
Jesus Cea9c822272011-09-10 01:40:52 +02006116 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006117 ** sched_setscheduler() returns 0 in Linux, but the previous
6118 ** scheduling policy under Solaris/Illumos, and others.
6119 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006120 */
Larry Hastings2f936352014-08-05 14:04:04 +10006121 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006122 return posix_error();
6123 Py_RETURN_NONE;
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
6128#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006129/*[clinic input]
6130os.sched_getparam
6131 pid: pid_t
6132 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006133
Larry Hastings2f936352014-08-05 14:04:04 +10006134Returns scheduling parameters for the process identified by pid.
6135
6136If pid is 0, returns parameters for the calling process.
6137Return value is an instance of sched_param.
6138[clinic start generated code]*/
6139
Larry Hastings2f936352014-08-05 14:04:04 +10006140static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006141os_sched_getparam_impl(PyObject *module, pid_t pid)
6142/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006143{
6144 struct sched_param param;
6145 PyObject *result;
6146 PyObject *priority;
6147
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006148 if (sched_getparam(pid, &param))
6149 return posix_error();
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006150 result = PyStructSequence_New(SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006151 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006152 return NULL;
6153 priority = PyLong_FromLong(param.sched_priority);
6154 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006155 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006156 return NULL;
6157 }
Larry Hastings2f936352014-08-05 14:04:04 +10006158 PyStructSequence_SET_ITEM(result, 0, priority);
6159 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006160}
6161
Larry Hastings2f936352014-08-05 14:04:04 +10006162
6163/*[clinic input]
6164os.sched_setparam
6165 pid: pid_t
6166 param: sched_param
6167 /
6168
6169Set scheduling parameters for the process identified by pid.
6170
6171If pid is 0, sets parameters for the calling process.
6172param should be an instance of sched_param.
6173[clinic start generated code]*/
6174
Larry Hastings2f936352014-08-05 14:04:04 +10006175static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006176os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006177 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006178/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006179{
6180 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006181 return posix_error();
6182 Py_RETURN_NONE;
6183}
Larry Hastings2f936352014-08-05 14:04:04 +10006184#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006185
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006186
6187#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006188/*[clinic input]
6189os.sched_rr_get_interval -> double
6190 pid: pid_t
6191 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006192
Larry Hastings2f936352014-08-05 14:04:04 +10006193Return the round-robin quantum for the process identified by pid, in seconds.
6194
6195Value returned is a float.
6196[clinic start generated code]*/
6197
Larry Hastings2f936352014-08-05 14:04:04 +10006198static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006199os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6200/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006201{
6202 struct timespec interval;
6203 if (sched_rr_get_interval(pid, &interval)) {
6204 posix_error();
6205 return -1.0;
6206 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006207#ifdef _Py_MEMORY_SANITIZER
6208 __msan_unpoison(&interval, sizeof(interval));
6209#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006210 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6211}
6212#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006213
Larry Hastings2f936352014-08-05 14:04:04 +10006214
6215/*[clinic input]
6216os.sched_yield
6217
6218Voluntarily relinquish the CPU.
6219[clinic start generated code]*/
6220
Larry Hastings2f936352014-08-05 14:04:04 +10006221static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006222os_sched_yield_impl(PyObject *module)
6223/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006224{
6225 if (sched_yield())
6226 return posix_error();
6227 Py_RETURN_NONE;
6228}
6229
Benjamin Peterson2740af82011-08-02 17:41:34 -05006230#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006231/* The minimum number of CPUs allocated in a cpu_set_t */
6232static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006233
Larry Hastings2f936352014-08-05 14:04:04 +10006234/*[clinic input]
6235os.sched_setaffinity
6236 pid: pid_t
6237 mask : object
6238 /
6239
6240Set the CPU affinity of the process identified by pid to mask.
6241
6242mask should be an iterable of integers identifying CPUs.
6243[clinic start generated code]*/
6244
Larry Hastings2f936352014-08-05 14:04:04 +10006245static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006246os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6247/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006248{
Antoine Pitrou84869872012-08-04 16:16:35 +02006249 int ncpus;
6250 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006251 cpu_set_t *cpu_set = NULL;
6252 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006253
Larry Hastings2f936352014-08-05 14:04:04 +10006254 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006255 if (iterator == NULL)
6256 return NULL;
6257
6258 ncpus = NCPUS_START;
6259 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006260 cpu_set = CPU_ALLOC(ncpus);
6261 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006262 PyErr_NoMemory();
6263 goto error;
6264 }
Larry Hastings2f936352014-08-05 14:04:04 +10006265 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006266
6267 while ((item = PyIter_Next(iterator))) {
6268 long cpu;
6269 if (!PyLong_Check(item)) {
6270 PyErr_Format(PyExc_TypeError,
6271 "expected an iterator of ints, "
6272 "but iterator yielded %R",
6273 Py_TYPE(item));
6274 Py_DECREF(item);
6275 goto error;
6276 }
6277 cpu = PyLong_AsLong(item);
6278 Py_DECREF(item);
6279 if (cpu < 0) {
6280 if (!PyErr_Occurred())
6281 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6282 goto error;
6283 }
6284 if (cpu > INT_MAX - 1) {
6285 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6286 goto error;
6287 }
6288 if (cpu >= ncpus) {
6289 /* Grow CPU mask to fit the CPU number */
6290 int newncpus = ncpus;
6291 cpu_set_t *newmask;
6292 size_t newsetsize;
6293 while (newncpus <= cpu) {
6294 if (newncpus > INT_MAX / 2)
6295 newncpus = cpu + 1;
6296 else
6297 newncpus = newncpus * 2;
6298 }
6299 newmask = CPU_ALLOC(newncpus);
6300 if (newmask == NULL) {
6301 PyErr_NoMemory();
6302 goto error;
6303 }
6304 newsetsize = CPU_ALLOC_SIZE(newncpus);
6305 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006306 memcpy(newmask, cpu_set, setsize);
6307 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006308 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006309 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006310 ncpus = newncpus;
6311 }
Larry Hastings2f936352014-08-05 14:04:04 +10006312 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006313 }
6314 Py_CLEAR(iterator);
6315
Larry Hastings2f936352014-08-05 14:04:04 +10006316 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006317 posix_error();
6318 goto error;
6319 }
Larry Hastings2f936352014-08-05 14:04:04 +10006320 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006321 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006322
6323error:
Larry Hastings2f936352014-08-05 14:04:04 +10006324 if (cpu_set)
6325 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006326 Py_XDECREF(iterator);
6327 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006328}
6329
Larry Hastings2f936352014-08-05 14:04:04 +10006330
6331/*[clinic input]
6332os.sched_getaffinity
6333 pid: pid_t
6334 /
6335
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006336Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006337
6338The affinity is returned as a set of CPU identifiers.
6339[clinic start generated code]*/
6340
Larry Hastings2f936352014-08-05 14:04:04 +10006341static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006342os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006343/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006344{
Antoine Pitrou84869872012-08-04 16:16:35 +02006345 int cpu, ncpus, count;
6346 size_t setsize;
6347 cpu_set_t *mask = NULL;
6348 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006349
Antoine Pitrou84869872012-08-04 16:16:35 +02006350 ncpus = NCPUS_START;
6351 while (1) {
6352 setsize = CPU_ALLOC_SIZE(ncpus);
6353 mask = CPU_ALLOC(ncpus);
6354 if (mask == NULL)
6355 return PyErr_NoMemory();
6356 if (sched_getaffinity(pid, setsize, mask) == 0)
6357 break;
6358 CPU_FREE(mask);
6359 if (errno != EINVAL)
6360 return posix_error();
6361 if (ncpus > INT_MAX / 2) {
6362 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6363 "a large enough CPU set");
6364 return NULL;
6365 }
6366 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006367 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006368
6369 res = PySet_New(NULL);
6370 if (res == NULL)
6371 goto error;
6372 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6373 if (CPU_ISSET_S(cpu, setsize, mask)) {
6374 PyObject *cpu_num = PyLong_FromLong(cpu);
6375 --count;
6376 if (cpu_num == NULL)
6377 goto error;
6378 if (PySet_Add(res, cpu_num)) {
6379 Py_DECREF(cpu_num);
6380 goto error;
6381 }
6382 Py_DECREF(cpu_num);
6383 }
6384 }
6385 CPU_FREE(mask);
6386 return res;
6387
6388error:
6389 if (mask)
6390 CPU_FREE(mask);
6391 Py_XDECREF(res);
6392 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006393}
6394
Benjamin Peterson2740af82011-08-02 17:41:34 -05006395#endif /* HAVE_SCHED_SETAFFINITY */
6396
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006397#endif /* HAVE_SCHED_H */
6398
Larry Hastings2f936352014-08-05 14:04:04 +10006399
Neal Norwitzb59798b2003-03-21 01:43:31 +00006400/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006401/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6402#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006403#define DEV_PTY_FILE "/dev/ptc"
6404#define HAVE_DEV_PTMX
6405#else
6406#define DEV_PTY_FILE "/dev/ptmx"
6407#endif
6408
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006409#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006410#ifdef HAVE_PTY_H
6411#include <pty.h>
6412#else
6413#ifdef HAVE_LIBUTIL_H
6414#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006415#else
6416#ifdef HAVE_UTIL_H
6417#include <util.h>
6418#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006419#endif /* HAVE_LIBUTIL_H */
6420#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006421#ifdef HAVE_STROPTS_H
6422#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006423#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006424#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006425
Larry Hastings2f936352014-08-05 14:04:04 +10006426
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006427#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006428/*[clinic input]
6429os.openpty
6430
6431Open a pseudo-terminal.
6432
6433Return a tuple of (master_fd, slave_fd) containing open file descriptors
6434for both the master and slave ends.
6435[clinic start generated code]*/
6436
Larry Hastings2f936352014-08-05 14:04:04 +10006437static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006438os_openpty_impl(PyObject *module)
6439/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006440{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006441 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006442#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006443 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006444#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006445#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006447#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006448 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006449#endif
6450#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006451
Thomas Wouters70c21a12000-07-14 14:28:33 +00006452#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006454 goto posix_error;
6455
6456 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6457 goto error;
6458 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6459 goto error;
6460
Neal Norwitzb59798b2003-03-21 01:43:31 +00006461#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006462 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6463 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006464 goto posix_error;
6465 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6466 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006467
Victor Stinnerdaf45552013-08-28 00:53:59 +02006468 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006469 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006470 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006471
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006472#else
Victor Stinner000de532013-11-25 23:19:58 +01006473 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006474 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006475 goto posix_error;
6476
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006478
Victor Stinner8c62be82010-05-06 00:08:46 +00006479 /* change permission of slave */
6480 if (grantpt(master_fd) < 0) {
6481 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006482 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006483 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006484
Victor Stinner8c62be82010-05-06 00:08:46 +00006485 /* unlock slave */
6486 if (unlockpt(master_fd) < 0) {
6487 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006488 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006489 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006490
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006492
Victor Stinner8c62be82010-05-06 00:08:46 +00006493 slave_name = ptsname(master_fd); /* get name of slave */
6494 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006495 goto posix_error;
6496
6497 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006498 if (slave_fd == -1)
6499 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006500
6501 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6502 goto posix_error;
6503
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006504#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006505 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6506 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006507#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006509#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006510#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006511#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006512
Victor Stinner8c62be82010-05-06 00:08:46 +00006513 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006514
Victor Stinnerdaf45552013-08-28 00:53:59 +02006515posix_error:
6516 posix_error();
6517error:
6518 if (master_fd != -1)
6519 close(master_fd);
6520 if (slave_fd != -1)
6521 close(slave_fd);
6522 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006523}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006524#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006525
Larry Hastings2f936352014-08-05 14:04:04 +10006526
Fred Drake8cef4cf2000-06-28 16:40:38 +00006527#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006528/*[clinic input]
6529os.forkpty
6530
6531Fork a new process with a new pseudo-terminal as controlling tty.
6532
6533Returns a tuple of (pid, master_fd).
6534Like fork(), return pid of 0 to the child process,
6535and pid of child to the parent process.
6536To both, return fd of newly opened pseudo-terminal.
6537[clinic start generated code]*/
6538
Larry Hastings2f936352014-08-05 14:04:04 +10006539static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006540os_forkpty_impl(PyObject *module)
6541/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006542{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006543 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006545
Eric Snow59032962018-09-14 14:17:20 -07006546 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6547 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6548 return NULL;
6549 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006550 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 pid = forkpty(&master_fd, NULL, NULL, NULL);
6552 if (pid == 0) {
6553 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006554 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006555 } else {
6556 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006557 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006558 }
6559 if (pid == -1)
6560 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006561 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006562}
Larry Hastings2f936352014-08-05 14:04:04 +10006563#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006564
Ross Lagerwall7807c352011-03-17 20:20:30 +02006565
Guido van Rossumad0ee831995-03-01 10:34:45 +00006566#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006567/*[clinic input]
6568os.getegid
6569
6570Return the current process's effective group id.
6571[clinic start generated code]*/
6572
Larry Hastings2f936352014-08-05 14:04:04 +10006573static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006574os_getegid_impl(PyObject *module)
6575/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006576{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006577 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006578}
Larry Hastings2f936352014-08-05 14:04:04 +10006579#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006580
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006581
Guido van Rossumad0ee831995-03-01 10:34:45 +00006582#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006583/*[clinic input]
6584os.geteuid
6585
6586Return the current process's effective user id.
6587[clinic start generated code]*/
6588
Larry Hastings2f936352014-08-05 14:04:04 +10006589static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006590os_geteuid_impl(PyObject *module)
6591/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006592{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006593 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006594}
Larry Hastings2f936352014-08-05 14:04:04 +10006595#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006596
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006597
Guido van Rossumad0ee831995-03-01 10:34:45 +00006598#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006599/*[clinic input]
6600os.getgid
6601
6602Return the current process's group id.
6603[clinic start generated code]*/
6604
Larry Hastings2f936352014-08-05 14:04:04 +10006605static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006606os_getgid_impl(PyObject *module)
6607/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006608{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006609 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006610}
Larry Hastings2f936352014-08-05 14:04:04 +10006611#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006612
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006613
Berker Peksag39404992016-09-15 20:45:16 +03006614#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006615/*[clinic input]
6616os.getpid
6617
6618Return the current process id.
6619[clinic start generated code]*/
6620
Larry Hastings2f936352014-08-05 14:04:04 +10006621static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006622os_getpid_impl(PyObject *module)
6623/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006624{
Victor Stinner8c62be82010-05-06 00:08:46 +00006625 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006626}
Berker Peksag39404992016-09-15 20:45:16 +03006627#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006628
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006629#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006630
6631/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006632PyDoc_STRVAR(posix_getgrouplist__doc__,
6633"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6634Returns a list of groups to which a user belongs.\n\n\
6635 user: username to lookup\n\
6636 group: base group id of the user");
6637
6638static PyObject *
6639posix_getgrouplist(PyObject *self, PyObject *args)
6640{
6641#ifdef NGROUPS_MAX
6642#define MAX_GROUPS NGROUPS_MAX
6643#else
6644 /* defined to be 16 on Solaris7, so this should be a small number */
6645#define MAX_GROUPS 64
6646#endif
6647
6648 const char *user;
6649 int i, ngroups;
6650 PyObject *list;
6651#ifdef __APPLE__
6652 int *groups, basegid;
6653#else
6654 gid_t *groups, basegid;
6655#endif
6656 ngroups = MAX_GROUPS;
6657
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006658#ifdef __APPLE__
6659 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006660 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006661#else
6662 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6663 _Py_Gid_Converter, &basegid))
6664 return NULL;
6665#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006666
6667#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006668 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006669#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006670 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006671#endif
6672 if (groups == NULL)
6673 return PyErr_NoMemory();
6674
6675 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6676 PyMem_Del(groups);
6677 return posix_error();
6678 }
6679
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006680#ifdef _Py_MEMORY_SANITIZER
6681 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6682 __msan_unpoison(&ngroups, sizeof(ngroups));
6683 __msan_unpoison(groups, ngroups*sizeof(*groups));
6684#endif
6685
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006686 list = PyList_New(ngroups);
6687 if (list == NULL) {
6688 PyMem_Del(groups);
6689 return NULL;
6690 }
6691
6692 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006693#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006694 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006695#else
6696 PyObject *o = _PyLong_FromGid(groups[i]);
6697#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006698 if (o == NULL) {
6699 Py_DECREF(list);
6700 PyMem_Del(groups);
6701 return NULL;
6702 }
6703 PyList_SET_ITEM(list, i, o);
6704 }
6705
6706 PyMem_Del(groups);
6707
6708 return list;
6709}
Larry Hastings2f936352014-08-05 14:04:04 +10006710#endif /* HAVE_GETGROUPLIST */
6711
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006712
Fred Drakec9680921999-12-13 16:37:25 +00006713#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006714/*[clinic input]
6715os.getgroups
6716
6717Return list of supplemental group IDs for the process.
6718[clinic start generated code]*/
6719
Larry Hastings2f936352014-08-05 14:04:04 +10006720static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006721os_getgroups_impl(PyObject *module)
6722/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006723{
6724 PyObject *result = NULL;
6725
Fred Drakec9680921999-12-13 16:37:25 +00006726#ifdef NGROUPS_MAX
6727#define MAX_GROUPS NGROUPS_MAX
6728#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006729 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006730#define MAX_GROUPS 64
6731#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006732 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006733
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006734 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006735 * This is a helper variable to store the intermediate result when
6736 * that happens.
6737 *
6738 * To keep the code readable the OSX behaviour is unconditional,
6739 * according to the POSIX spec this should be safe on all unix-y
6740 * systems.
6741 */
6742 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006743 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006744
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006745#ifdef __APPLE__
6746 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6747 * there are more groups than can fit in grouplist. Therefore, on OS X
6748 * always first call getgroups with length 0 to get the actual number
6749 * of groups.
6750 */
6751 n = getgroups(0, NULL);
6752 if (n < 0) {
6753 return posix_error();
6754 } else if (n <= MAX_GROUPS) {
6755 /* groups will fit in existing array */
6756 alt_grouplist = grouplist;
6757 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006758 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006759 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006760 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006761 }
6762 }
6763
6764 n = getgroups(n, alt_grouplist);
6765 if (n == -1) {
6766 if (alt_grouplist != grouplist) {
6767 PyMem_Free(alt_grouplist);
6768 }
6769 return posix_error();
6770 }
6771#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006772 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006773 if (n < 0) {
6774 if (errno == EINVAL) {
6775 n = getgroups(0, NULL);
6776 if (n == -1) {
6777 return posix_error();
6778 }
6779 if (n == 0) {
6780 /* Avoid malloc(0) */
6781 alt_grouplist = grouplist;
6782 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006783 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006784 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006785 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006786 }
6787 n = getgroups(n, alt_grouplist);
6788 if (n == -1) {
6789 PyMem_Free(alt_grouplist);
6790 return posix_error();
6791 }
6792 }
6793 } else {
6794 return posix_error();
6795 }
6796 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006797#endif
6798
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006799 result = PyList_New(n);
6800 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 int i;
6802 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006803 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006805 Py_DECREF(result);
6806 result = NULL;
6807 break;
Fred Drakec9680921999-12-13 16:37:25 +00006808 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006810 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006811 }
6812
6813 if (alt_grouplist != grouplist) {
6814 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006815 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006816
Fred Drakec9680921999-12-13 16:37:25 +00006817 return result;
6818}
Larry Hastings2f936352014-08-05 14:04:04 +10006819#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006820
Antoine Pitroub7572f02009-12-02 20:46:48 +00006821#ifdef HAVE_INITGROUPS
6822PyDoc_STRVAR(posix_initgroups__doc__,
6823"initgroups(username, gid) -> None\n\n\
6824Call the system initgroups() to initialize the group access list with all of\n\
6825the groups of which the specified username is a member, plus the specified\n\
6826group id.");
6827
Larry Hastings2f936352014-08-05 14:04:04 +10006828/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006829static PyObject *
6830posix_initgroups(PyObject *self, PyObject *args)
6831{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006832 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006833 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006834 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006835#ifdef __APPLE__
6836 int gid;
6837#else
6838 gid_t gid;
6839#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006840
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006841#ifdef __APPLE__
6842 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6843 PyUnicode_FSConverter, &oname,
6844 &gid))
6845#else
6846 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6847 PyUnicode_FSConverter, &oname,
6848 _Py_Gid_Converter, &gid))
6849#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006851 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006852
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006853 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006854 Py_DECREF(oname);
6855 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006857
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006858 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006859}
Larry Hastings2f936352014-08-05 14:04:04 +10006860#endif /* HAVE_INITGROUPS */
6861
Antoine Pitroub7572f02009-12-02 20:46:48 +00006862
Martin v. Löwis606edc12002-06-13 21:09:11 +00006863#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006864/*[clinic input]
6865os.getpgid
6866
6867 pid: pid_t
6868
6869Call the system call getpgid(), and return the result.
6870[clinic start generated code]*/
6871
Larry Hastings2f936352014-08-05 14:04:04 +10006872static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006873os_getpgid_impl(PyObject *module, pid_t pid)
6874/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006875{
6876 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 if (pgid < 0)
6878 return posix_error();
6879 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006880}
6881#endif /* HAVE_GETPGID */
6882
6883
Guido van Rossumb6775db1994-08-01 11:34:53 +00006884#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006885/*[clinic input]
6886os.getpgrp
6887
6888Return the current process group id.
6889[clinic start generated code]*/
6890
Larry Hastings2f936352014-08-05 14:04:04 +10006891static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006892os_getpgrp_impl(PyObject *module)
6893/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006894{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006895#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006896 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006897#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006899#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006900}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006901#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006902
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006903
Guido van Rossumb6775db1994-08-01 11:34:53 +00006904#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006905/*[clinic input]
6906os.setpgrp
6907
6908Make the current process the leader of its process group.
6909[clinic start generated code]*/
6910
Larry Hastings2f936352014-08-05 14:04:04 +10006911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006912os_setpgrp_impl(PyObject *module)
6913/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006914{
Guido van Rossum64933891994-10-20 21:56:42 +00006915#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006917#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006918 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006919#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006920 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006921 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006922}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006923#endif /* HAVE_SETPGRP */
6924
Guido van Rossumad0ee831995-03-01 10:34:45 +00006925#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006926
6927#ifdef MS_WINDOWS
6928#include <tlhelp32.h>
6929
6930static PyObject*
6931win32_getppid()
6932{
6933 HANDLE snapshot;
6934 pid_t mypid;
6935 PyObject* result = NULL;
6936 BOOL have_record;
6937 PROCESSENTRY32 pe;
6938
6939 mypid = getpid(); /* This function never fails */
6940
6941 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6942 if (snapshot == INVALID_HANDLE_VALUE)
6943 return PyErr_SetFromWindowsErr(GetLastError());
6944
6945 pe.dwSize = sizeof(pe);
6946 have_record = Process32First(snapshot, &pe);
6947 while (have_record) {
6948 if (mypid == (pid_t)pe.th32ProcessID) {
6949 /* We could cache the ulong value in a static variable. */
6950 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6951 break;
6952 }
6953
6954 have_record = Process32Next(snapshot, &pe);
6955 }
6956
6957 /* If our loop exits and our pid was not found (result will be NULL)
6958 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6959 * error anyway, so let's raise it. */
6960 if (!result)
6961 result = PyErr_SetFromWindowsErr(GetLastError());
6962
6963 CloseHandle(snapshot);
6964
6965 return result;
6966}
6967#endif /*MS_WINDOWS*/
6968
Larry Hastings2f936352014-08-05 14:04:04 +10006969
6970/*[clinic input]
6971os.getppid
6972
6973Return the parent's process id.
6974
6975If the parent process has already exited, Windows machines will still
6976return its id; others systems will return the id of the 'init' process (1).
6977[clinic start generated code]*/
6978
Larry Hastings2f936352014-08-05 14:04:04 +10006979static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006980os_getppid_impl(PyObject *module)
6981/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006982{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006983#ifdef MS_WINDOWS
6984 return win32_getppid();
6985#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006987#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006988}
6989#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006990
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006991
Fred Drake12c6e2d1999-12-14 21:25:03 +00006992#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006993/*[clinic input]
6994os.getlogin
6995
6996Return the actual login name.
6997[clinic start generated code]*/
6998
Larry Hastings2f936352014-08-05 14:04:04 +10006999static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007000os_getlogin_impl(PyObject *module)
7001/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007002{
Victor Stinner8c62be82010-05-06 00:08:46 +00007003 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007004#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007005 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007006 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007007
7008 if (GetUserNameW(user_name, &num_chars)) {
7009 /* num_chars is the number of unicode chars plus null terminator */
7010 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007011 }
7012 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007013 result = PyErr_SetFromWindowsErr(GetLastError());
7014#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007015 char *name;
7016 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007017
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 errno = 0;
7019 name = getlogin();
7020 if (name == NULL) {
7021 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007022 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007023 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007024 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007025 }
7026 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007027 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007029#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007030 return result;
7031}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007032#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007033
Larry Hastings2f936352014-08-05 14:04:04 +10007034
Guido van Rossumad0ee831995-03-01 10:34:45 +00007035#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007036/*[clinic input]
7037os.getuid
7038
7039Return the current process's user id.
7040[clinic start generated code]*/
7041
Larry Hastings2f936352014-08-05 14:04:04 +10007042static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007043os_getuid_impl(PyObject *module)
7044/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007045{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007046 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007047}
Larry Hastings2f936352014-08-05 14:04:04 +10007048#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007049
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007050
Brian Curtineb24d742010-04-12 17:16:38 +00007051#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007052#define HAVE_KILL
7053#endif /* MS_WINDOWS */
7054
7055#ifdef HAVE_KILL
7056/*[clinic input]
7057os.kill
7058
7059 pid: pid_t
7060 signal: Py_ssize_t
7061 /
7062
7063Kill a process with a signal.
7064[clinic start generated code]*/
7065
Larry Hastings2f936352014-08-05 14:04:04 +10007066static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007067os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7068/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007069#ifndef MS_WINDOWS
7070{
7071 if (kill(pid, (int)signal) == -1)
7072 return posix_error();
7073 Py_RETURN_NONE;
7074}
7075#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00007076{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007077 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007078 DWORD sig = (DWORD)signal;
7079 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007080 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007081
Victor Stinner8c62be82010-05-06 00:08:46 +00007082 /* Console processes which share a common console can be sent CTRL+C or
7083 CTRL+BREAK events, provided they handle said events. */
7084 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007085 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007086 err = GetLastError();
7087 PyErr_SetFromWindowsErr(err);
7088 }
7089 else
7090 Py_RETURN_NONE;
7091 }
Brian Curtineb24d742010-04-12 17:16:38 +00007092
Victor Stinner8c62be82010-05-06 00:08:46 +00007093 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7094 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007095 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007096 if (handle == NULL) {
7097 err = GetLastError();
7098 return PyErr_SetFromWindowsErr(err);
7099 }
Brian Curtineb24d742010-04-12 17:16:38 +00007100
Victor Stinner8c62be82010-05-06 00:08:46 +00007101 if (TerminateProcess(handle, sig) == 0) {
7102 err = GetLastError();
7103 result = PyErr_SetFromWindowsErr(err);
7104 } else {
7105 Py_INCREF(Py_None);
7106 result = Py_None;
7107 }
Brian Curtineb24d742010-04-12 17:16:38 +00007108
Victor Stinner8c62be82010-05-06 00:08:46 +00007109 CloseHandle(handle);
7110 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00007111}
Larry Hastings2f936352014-08-05 14:04:04 +10007112#endif /* !MS_WINDOWS */
7113#endif /* HAVE_KILL */
7114
7115
7116#ifdef HAVE_KILLPG
7117/*[clinic input]
7118os.killpg
7119
7120 pgid: pid_t
7121 signal: int
7122 /
7123
7124Kill a process group with a signal.
7125[clinic start generated code]*/
7126
Larry Hastings2f936352014-08-05 14:04:04 +10007127static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007128os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7129/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007130{
7131 /* XXX some man pages make the `pgid` parameter an int, others
7132 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7133 take the same type. Moreover, pid_t is always at least as wide as
7134 int (else compilation of this module fails), which is safe. */
7135 if (killpg(pgid, signal) == -1)
7136 return posix_error();
7137 Py_RETURN_NONE;
7138}
7139#endif /* HAVE_KILLPG */
7140
Brian Curtineb24d742010-04-12 17:16:38 +00007141
Guido van Rossumc0125471996-06-28 18:55:32 +00007142#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007143#ifdef HAVE_SYS_LOCK_H
7144#include <sys/lock.h>
7145#endif
7146
Larry Hastings2f936352014-08-05 14:04:04 +10007147/*[clinic input]
7148os.plock
7149 op: int
7150 /
7151
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007152Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007153[clinic start generated code]*/
7154
Larry Hastings2f936352014-08-05 14:04:04 +10007155static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007156os_plock_impl(PyObject *module, int op)
7157/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007158{
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 if (plock(op) == -1)
7160 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007161 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007162}
Larry Hastings2f936352014-08-05 14:04:04 +10007163#endif /* HAVE_PLOCK */
7164
Guido van Rossumc0125471996-06-28 18:55:32 +00007165
Guido van Rossumb6775db1994-08-01 11:34:53 +00007166#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007167/*[clinic input]
7168os.setuid
7169
7170 uid: uid_t
7171 /
7172
7173Set the current process's user id.
7174[clinic start generated code]*/
7175
Larry Hastings2f936352014-08-05 14:04:04 +10007176static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007177os_setuid_impl(PyObject *module, uid_t uid)
7178/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007179{
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 if (setuid(uid) < 0)
7181 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007182 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007183}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007184#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007185
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007186
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007187#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007188/*[clinic input]
7189os.seteuid
7190
7191 euid: uid_t
7192 /
7193
7194Set the current process's effective user id.
7195[clinic start generated code]*/
7196
Larry Hastings2f936352014-08-05 14:04:04 +10007197static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007198os_seteuid_impl(PyObject *module, uid_t euid)
7199/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007200{
7201 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007202 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007203 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007204}
7205#endif /* HAVE_SETEUID */
7206
Larry Hastings2f936352014-08-05 14:04:04 +10007207
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007208#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007209/*[clinic input]
7210os.setegid
7211
7212 egid: gid_t
7213 /
7214
7215Set the current process's effective group id.
7216[clinic start generated code]*/
7217
Larry Hastings2f936352014-08-05 14:04:04 +10007218static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007219os_setegid_impl(PyObject *module, gid_t egid)
7220/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007221{
7222 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007223 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007224 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007225}
7226#endif /* HAVE_SETEGID */
7227
Larry Hastings2f936352014-08-05 14:04:04 +10007228
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007229#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007230/*[clinic input]
7231os.setreuid
7232
7233 ruid: uid_t
7234 euid: uid_t
7235 /
7236
7237Set the current process's real and effective user ids.
7238[clinic start generated code]*/
7239
Larry Hastings2f936352014-08-05 14:04:04 +10007240static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007241os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7242/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007243{
Victor Stinner8c62be82010-05-06 00:08:46 +00007244 if (setreuid(ruid, euid) < 0) {
7245 return posix_error();
7246 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007247 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007248 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007249}
7250#endif /* HAVE_SETREUID */
7251
Larry Hastings2f936352014-08-05 14:04:04 +10007252
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007253#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007254/*[clinic input]
7255os.setregid
7256
7257 rgid: gid_t
7258 egid: gid_t
7259 /
7260
7261Set the current process's real and effective group ids.
7262[clinic start generated code]*/
7263
Larry Hastings2f936352014-08-05 14:04:04 +10007264static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007265os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7266/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007267{
7268 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007269 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007270 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007271}
7272#endif /* HAVE_SETREGID */
7273
Larry Hastings2f936352014-08-05 14:04:04 +10007274
Guido van Rossumb6775db1994-08-01 11:34:53 +00007275#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007276/*[clinic input]
7277os.setgid
7278 gid: gid_t
7279 /
7280
7281Set the current process's group id.
7282[clinic start generated code]*/
7283
Larry Hastings2f936352014-08-05 14:04:04 +10007284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007285os_setgid_impl(PyObject *module, gid_t gid)
7286/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007287{
Victor Stinner8c62be82010-05-06 00:08:46 +00007288 if (setgid(gid) < 0)
7289 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007290 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007291}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007292#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007293
Larry Hastings2f936352014-08-05 14:04:04 +10007294
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007295#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007296/*[clinic input]
7297os.setgroups
7298
7299 groups: object
7300 /
7301
7302Set the groups of the current process to list.
7303[clinic start generated code]*/
7304
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007305static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007306os_setgroups(PyObject *module, PyObject *groups)
7307/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007308{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007309 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007310 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007311
Victor Stinner8c62be82010-05-06 00:08:46 +00007312 if (!PySequence_Check(groups)) {
7313 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7314 return NULL;
7315 }
7316 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007317 if (len < 0) {
7318 return NULL;
7319 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007320 if (len > MAX_GROUPS) {
7321 PyErr_SetString(PyExc_ValueError, "too many groups");
7322 return NULL;
7323 }
7324 for(i = 0; i < len; i++) {
7325 PyObject *elem;
7326 elem = PySequence_GetItem(groups, i);
7327 if (!elem)
7328 return NULL;
7329 if (!PyLong_Check(elem)) {
7330 PyErr_SetString(PyExc_TypeError,
7331 "groups must be integers");
7332 Py_DECREF(elem);
7333 return NULL;
7334 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007335 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007336 Py_DECREF(elem);
7337 return NULL;
7338 }
7339 }
7340 Py_DECREF(elem);
7341 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007342
Victor Stinner8c62be82010-05-06 00:08:46 +00007343 if (setgroups(len, grouplist) < 0)
7344 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007345 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007346}
7347#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007348
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007349#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7350static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007351wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007352{
Victor Stinner8c62be82010-05-06 00:08:46 +00007353 PyObject *result;
7354 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007355 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007356
Victor Stinner8c62be82010-05-06 00:08:46 +00007357 if (pid == -1)
7358 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007359
Victor Stinner8c62be82010-05-06 00:08:46 +00007360 if (struct_rusage == NULL) {
7361 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7362 if (m == NULL)
7363 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007364 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007365 Py_DECREF(m);
7366 if (struct_rusage == NULL)
7367 return NULL;
7368 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007369
Victor Stinner8c62be82010-05-06 00:08:46 +00007370 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7371 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7372 if (!result)
7373 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007374
7375#ifndef doubletime
7376#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7377#endif
7378
Victor Stinner8c62be82010-05-06 00:08:46 +00007379 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007380 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007381 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007382 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007383#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007384 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7385 SET_INT(result, 2, ru->ru_maxrss);
7386 SET_INT(result, 3, ru->ru_ixrss);
7387 SET_INT(result, 4, ru->ru_idrss);
7388 SET_INT(result, 5, ru->ru_isrss);
7389 SET_INT(result, 6, ru->ru_minflt);
7390 SET_INT(result, 7, ru->ru_majflt);
7391 SET_INT(result, 8, ru->ru_nswap);
7392 SET_INT(result, 9, ru->ru_inblock);
7393 SET_INT(result, 10, ru->ru_oublock);
7394 SET_INT(result, 11, ru->ru_msgsnd);
7395 SET_INT(result, 12, ru->ru_msgrcv);
7396 SET_INT(result, 13, ru->ru_nsignals);
7397 SET_INT(result, 14, ru->ru_nvcsw);
7398 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007399#undef SET_INT
7400
Victor Stinner8c62be82010-05-06 00:08:46 +00007401 if (PyErr_Occurred()) {
7402 Py_DECREF(result);
7403 return NULL;
7404 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007405
Victor Stinner8c62be82010-05-06 00:08:46 +00007406 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007407}
7408#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7409
Larry Hastings2f936352014-08-05 14:04:04 +10007410
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007411#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007412/*[clinic input]
7413os.wait3
7414
7415 options: int
7416Wait for completion of a child process.
7417
7418Returns a tuple of information about the child process:
7419 (pid, status, rusage)
7420[clinic start generated code]*/
7421
Larry Hastings2f936352014-08-05 14:04:04 +10007422static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007423os_wait3_impl(PyObject *module, int options)
7424/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007425{
Victor Stinner8c62be82010-05-06 00:08:46 +00007426 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007427 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007428 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007429 WAIT_TYPE status;
7430 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007431
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007432 do {
7433 Py_BEGIN_ALLOW_THREADS
7434 pid = wait3(&status, options, &ru);
7435 Py_END_ALLOW_THREADS
7436 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7437 if (pid < 0)
7438 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007439
Victor Stinner4195b5c2012-02-08 23:03:19 +01007440 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007441}
7442#endif /* HAVE_WAIT3 */
7443
Larry Hastings2f936352014-08-05 14:04:04 +10007444
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007445#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007446/*[clinic input]
7447
7448os.wait4
7449
7450 pid: pid_t
7451 options: int
7452
7453Wait for completion of a specific child process.
7454
7455Returns a tuple of information about the child process:
7456 (pid, status, rusage)
7457[clinic start generated code]*/
7458
Larry Hastings2f936352014-08-05 14:04:04 +10007459static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007460os_wait4_impl(PyObject *module, pid_t pid, int options)
7461/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007462{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007463 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007464 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007465 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007466 WAIT_TYPE status;
7467 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007468
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007469 do {
7470 Py_BEGIN_ALLOW_THREADS
7471 res = wait4(pid, &status, options, &ru);
7472 Py_END_ALLOW_THREADS
7473 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7474 if (res < 0)
7475 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007476
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007477 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007478}
7479#endif /* HAVE_WAIT4 */
7480
Larry Hastings2f936352014-08-05 14:04:04 +10007481
Ross Lagerwall7807c352011-03-17 20:20:30 +02007482#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007483/*[clinic input]
7484os.waitid
7485
7486 idtype: idtype_t
7487 Must be one of be P_PID, P_PGID or P_ALL.
7488 id: id_t
7489 The id to wait on.
7490 options: int
7491 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7492 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7493 /
7494
7495Returns the result of waiting for a process or processes.
7496
7497Returns either waitid_result or None if WNOHANG is specified and there are
7498no children in a waitable state.
7499[clinic start generated code]*/
7500
Larry Hastings2f936352014-08-05 14:04:04 +10007501static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007502os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7503/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007504{
7505 PyObject *result;
7506 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007507 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007508 siginfo_t si;
7509 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007510
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007511 do {
7512 Py_BEGIN_ALLOW_THREADS
7513 res = waitid(idtype, id, &si, options);
7514 Py_END_ALLOW_THREADS
7515 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7516 if (res < 0)
7517 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007518
7519 if (si.si_pid == 0)
7520 Py_RETURN_NONE;
7521
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007522 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007523 if (!result)
7524 return NULL;
7525
7526 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007527 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007528 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7529 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7530 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7531 if (PyErr_Occurred()) {
7532 Py_DECREF(result);
7533 return NULL;
7534 }
7535
7536 return result;
7537}
Larry Hastings2f936352014-08-05 14:04:04 +10007538#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007539
Larry Hastings2f936352014-08-05 14:04:04 +10007540
7541#if defined(HAVE_WAITPID)
7542/*[clinic input]
7543os.waitpid
7544 pid: pid_t
7545 options: int
7546 /
7547
7548Wait for completion of a given child process.
7549
7550Returns a tuple of information regarding the child process:
7551 (pid, status)
7552
7553The options argument is ignored on Windows.
7554[clinic start generated code]*/
7555
Larry Hastings2f936352014-08-05 14:04:04 +10007556static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007557os_waitpid_impl(PyObject *module, pid_t pid, int options)
7558/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007559{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007560 pid_t res;
7561 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 WAIT_TYPE status;
7563 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007564
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007565 do {
7566 Py_BEGIN_ALLOW_THREADS
7567 res = waitpid(pid, &status, options);
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 Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007574}
Tim Petersab034fa2002-02-01 11:27:43 +00007575#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007576/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007577/*[clinic input]
7578os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007579 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007580 options: int
7581 /
7582
7583Wait for completion of a given process.
7584
7585Returns a tuple of information regarding the process:
7586 (pid, status << 8)
7587
7588The options argument is ignored on Windows.
7589[clinic start generated code]*/
7590
Larry Hastings2f936352014-08-05 14:04:04 +10007591static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007592os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007593/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007594{
7595 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007596 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007597 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007598
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007599 do {
7600 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007601 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007602 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007603 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007604 Py_END_ALLOW_THREADS
7605 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007606 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007607 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007608
Victor Stinner8c62be82010-05-06 00:08:46 +00007609 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007610 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007611}
Larry Hastings2f936352014-08-05 14:04:04 +10007612#endif
7613
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007614
Guido van Rossumad0ee831995-03-01 10:34:45 +00007615#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007616/*[clinic input]
7617os.wait
7618
7619Wait for completion of a child process.
7620
7621Returns a tuple of information about the child process:
7622 (pid, status)
7623[clinic start generated code]*/
7624
Larry Hastings2f936352014-08-05 14:04:04 +10007625static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007626os_wait_impl(PyObject *module)
7627/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007628{
Victor Stinner8c62be82010-05-06 00:08:46 +00007629 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007630 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007631 WAIT_TYPE status;
7632 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007633
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007634 do {
7635 Py_BEGIN_ALLOW_THREADS
7636 pid = wait(&status);
7637 Py_END_ALLOW_THREADS
7638 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7639 if (pid < 0)
7640 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007641
Victor Stinner8c62be82010-05-06 00:08:46 +00007642 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007643}
Larry Hastings2f936352014-08-05 14:04:04 +10007644#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007645
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007646
Larry Hastings9cf065c2012-06-22 16:30:09 -07007647#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007648/*[clinic input]
7649os.readlink
7650
7651 path: path_t
7652 *
7653 dir_fd: dir_fd(requires='readlinkat') = None
7654
7655Return a string representing the path to which the symbolic link points.
7656
7657If dir_fd is not None, it should be a file descriptor open to a directory,
7658and path should be relative; path will then be relative to that directory.
7659
7660dir_fd may not be implemented on your platform. If it is unavailable,
7661using it will raise a NotImplementedError.
7662[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007663
Barry Warsaw53699e91996-12-10 23:23:01 +00007664static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007665os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7666/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007667{
Berker Peksage0b5b202018-08-15 13:03:41 +03007668#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007669 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007670 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007671
7672 Py_BEGIN_ALLOW_THREADS
7673#ifdef HAVE_READLINKAT
7674 if (dir_fd != DEFAULT_DIR_FD)
7675 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7676 else
7677#endif
7678 length = readlink(path->narrow, buffer, MAXPATHLEN);
7679 Py_END_ALLOW_THREADS
7680
7681 if (length < 0) {
7682 return path_error(path);
7683 }
7684 buffer[length] = '\0';
7685
7686 if (PyUnicode_Check(path->object))
7687 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7688 else
7689 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007690#elif defined(MS_WINDOWS)
7691 DWORD n_bytes_returned;
7692 DWORD io_result;
7693 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007694 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7695 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
7696 const wchar_t *print_name;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007697 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007698
Larry Hastings2f936352014-08-05 14:04:04 +10007699 /* First get a handle to the reparse point */
7700 Py_BEGIN_ALLOW_THREADS
7701 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007702 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007703 0,
7704 0,
7705 0,
7706 OPEN_EXISTING,
7707 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7708 0);
7709 Py_END_ALLOW_THREADS
7710
Berker Peksage0b5b202018-08-15 13:03:41 +03007711 if (reparse_point_handle == INVALID_HANDLE_VALUE) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007712 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007713 }
Larry Hastings2f936352014-08-05 14:04:04 +10007714
7715 Py_BEGIN_ALLOW_THREADS
7716 /* New call DeviceIoControl to read the reparse point */
7717 io_result = DeviceIoControl(
7718 reparse_point_handle,
7719 FSCTL_GET_REPARSE_POINT,
7720 0, 0, /* in buffer */
7721 target_buffer, sizeof(target_buffer),
7722 &n_bytes_returned,
7723 0 /* we're not using OVERLAPPED_IO */
7724 );
7725 CloseHandle(reparse_point_handle);
7726 Py_END_ALLOW_THREADS
7727
Berker Peksage0b5b202018-08-15 13:03:41 +03007728 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007729 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007730 }
Larry Hastings2f936352014-08-05 14:04:04 +10007731
7732 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7733 {
7734 PyErr_SetString(PyExc_ValueError,
7735 "not a symbolic link");
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007736 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007737 }
SSE43c34aad2018-02-13 00:10:35 +07007738 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7739 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007740
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007741 result = PyUnicode_FromWideChar(print_name,
7742 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
7743 if (path->narrow) {
7744 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Berker Peksage0b5b202018-08-15 13:03:41 +03007745 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007746 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007747#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007748}
Berker Peksage0b5b202018-08-15 13:03:41 +03007749#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007750
Larry Hastings9cf065c2012-06-22 16:30:09 -07007751#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007752
7753#if defined(MS_WINDOWS)
7754
Steve Dower6921e732018-03-05 14:26:08 -08007755/* Remove the last portion of the path - return 0 on success */
7756static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007757_dirnameW(WCHAR *path)
7758{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007759 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007760 size_t length = wcsnlen_s(path, MAX_PATH);
7761 if (length == MAX_PATH) {
7762 return -1;
7763 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007764
7765 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007766 for(ptr = path + length; ptr != path; ptr--) {
7767 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007768 break;
Steve Dower6921e732018-03-05 14:26:08 -08007769 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007770 }
7771 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007772 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007773}
7774
Victor Stinner31b3b922013-06-05 01:49:17 +02007775/* Is this path absolute? */
7776static int
7777_is_absW(const WCHAR *path)
7778{
Steve Dower6921e732018-03-05 14:26:08 -08007779 return path[0] == L'\\' || path[0] == L'/' ||
7780 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007781}
7782
Steve Dower6921e732018-03-05 14:26:08 -08007783/* join root and rest with a backslash - return 0 on success */
7784static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007785_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7786{
Victor Stinner31b3b922013-06-05 01:49:17 +02007787 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007788 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007789 }
7790
Steve Dower6921e732018-03-05 14:26:08 -08007791 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7792 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007793 }
Steve Dower6921e732018-03-05 14:26:08 -08007794
7795 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7796 return -1;
7797 }
7798
7799 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007800}
7801
Victor Stinner31b3b922013-06-05 01:49:17 +02007802/* Return True if the path at src relative to dest is a directory */
7803static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007804_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007805{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007806 WIN32_FILE_ATTRIBUTE_DATA src_info;
7807 WCHAR dest_parent[MAX_PATH];
7808 WCHAR src_resolved[MAX_PATH] = L"";
7809
7810 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007811 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7812 _dirnameW(dest_parent)) {
7813 return 0;
7814 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007815 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007816 if (_joinW(src_resolved, dest_parent, src)) {
7817 return 0;
7818 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007819 return (
7820 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7821 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7822 );
7823}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007824#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007825
Larry Hastings2f936352014-08-05 14:04:04 +10007826
7827/*[clinic input]
7828os.symlink
7829 src: path_t
7830 dst: path_t
7831 target_is_directory: bool = False
7832 *
7833 dir_fd: dir_fd(requires='symlinkat')=None
7834
7835# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7836
7837Create a symbolic link pointing to src named dst.
7838
7839target_is_directory is required on Windows if the target is to be
7840 interpreted as a directory. (On Windows, symlink requires
7841 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7842 target_is_directory is ignored on non-Windows platforms.
7843
7844If dir_fd is not None, it should be a file descriptor open to a directory,
7845 and path should be relative; path will then be relative to that directory.
7846dir_fd may not be implemented on your platform.
7847 If it is unavailable, using it will raise a NotImplementedError.
7848
7849[clinic start generated code]*/
7850
Larry Hastings2f936352014-08-05 14:04:04 +10007851static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007852os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007853 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007854/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007855{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007856#ifdef MS_WINDOWS
7857 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007858 DWORD flags = 0;
7859
7860 /* Assumed true, set to false if detected to not be available. */
7861 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007862#else
7863 int result;
7864#endif
7865
Larry Hastings9cf065c2012-06-22 16:30:09 -07007866#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007867
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007868 if (windows_has_symlink_unprivileged_flag) {
7869 /* Allow non-admin symlinks if system allows it. */
7870 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
7871 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007872
Larry Hastings9cf065c2012-06-22 16:30:09 -07007873 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007874 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007875 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
7876 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
7877 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
7878 }
7879
7880 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08007881 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007882 Py_END_ALLOW_THREADS
7883
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007884 if (windows_has_symlink_unprivileged_flag && !result &&
7885 ERROR_INVALID_PARAMETER == GetLastError()) {
7886
7887 Py_BEGIN_ALLOW_THREADS
7888 _Py_BEGIN_SUPPRESS_IPH
7889 /* This error might be caused by
7890 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
7891 Try again, and update windows_has_symlink_unprivileged_flag if we
7892 are successful this time.
7893
7894 NOTE: There is a risk of a race condition here if there are other
7895 conditions than the flag causing ERROR_INVALID_PARAMETER, and
7896 another process (or thread) changes that condition in between our
7897 calls to CreateSymbolicLink.
7898 */
7899 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
7900 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
7901 _Py_END_SUPPRESS_IPH
7902 Py_END_ALLOW_THREADS
7903
7904 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
7905 windows_has_symlink_unprivileged_flag = FALSE;
7906 }
7907 }
7908
Larry Hastings2f936352014-08-05 14:04:04 +10007909 if (!result)
7910 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007911
7912#else
7913
Steve Dower6921e732018-03-05 14:26:08 -08007914 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7915 PyErr_SetString(PyExc_ValueError,
7916 "symlink: src and dst must be the same type");
7917 return NULL;
7918 }
7919
Larry Hastings9cf065c2012-06-22 16:30:09 -07007920 Py_BEGIN_ALLOW_THREADS
7921#if HAVE_SYMLINKAT
7922 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007923 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007924 else
7925#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007926 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007927 Py_END_ALLOW_THREADS
7928
Larry Hastings2f936352014-08-05 14:04:04 +10007929 if (result)
7930 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007931#endif
7932
Larry Hastings2f936352014-08-05 14:04:04 +10007933 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007934}
7935#endif /* HAVE_SYMLINK */
7936
Larry Hastings9cf065c2012-06-22 16:30:09 -07007937
Brian Curtind40e6f72010-07-08 21:39:08 +00007938
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007939
Larry Hastings605a62d2012-06-24 04:33:36 -07007940static PyStructSequence_Field times_result_fields[] = {
7941 {"user", "user time"},
7942 {"system", "system time"},
7943 {"children_user", "user time of children"},
7944 {"children_system", "system time of children"},
7945 {"elapsed", "elapsed time since an arbitrary point in the past"},
7946 {NULL}
7947};
7948
7949PyDoc_STRVAR(times_result__doc__,
7950"times_result: Result from os.times().\n\n\
7951This object may be accessed either as a tuple of\n\
7952 (user, system, children_user, children_system, elapsed),\n\
7953or via the attributes user, system, children_user, children_system,\n\
7954and elapsed.\n\
7955\n\
7956See os.times for more information.");
7957
7958static PyStructSequence_Desc times_result_desc = {
7959 "times_result", /* name */
7960 times_result__doc__, /* doc */
7961 times_result_fields,
7962 5
7963};
7964
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007965static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07007966
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007967#ifdef MS_WINDOWS
7968#define HAVE_TIMES /* mandatory, for the method table */
7969#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007970
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007971#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007972
7973static PyObject *
7974build_times_result(double user, double system,
7975 double children_user, double children_system,
7976 double elapsed)
7977{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007978 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07007979 if (value == NULL)
7980 return NULL;
7981
7982#define SET(i, field) \
7983 { \
7984 PyObject *o = PyFloat_FromDouble(field); \
7985 if (!o) { \
7986 Py_DECREF(value); \
7987 return NULL; \
7988 } \
7989 PyStructSequence_SET_ITEM(value, i, o); \
7990 } \
7991
7992 SET(0, user);
7993 SET(1, system);
7994 SET(2, children_user);
7995 SET(3, children_system);
7996 SET(4, elapsed);
7997
7998#undef SET
7999
8000 return value;
8001}
8002
Larry Hastings605a62d2012-06-24 04:33:36 -07008003
Larry Hastings2f936352014-08-05 14:04:04 +10008004#ifndef MS_WINDOWS
8005#define NEED_TICKS_PER_SECOND
8006static long ticks_per_second = -1;
8007#endif /* MS_WINDOWS */
8008
8009/*[clinic input]
8010os.times
8011
8012Return a collection containing process timing information.
8013
8014The object returned behaves like a named tuple with these fields:
8015 (utime, stime, cutime, cstime, elapsed_time)
8016All fields are floating point numbers.
8017[clinic start generated code]*/
8018
Larry Hastings2f936352014-08-05 14:04:04 +10008019static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008020os_times_impl(PyObject *module)
8021/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008022#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008023{
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 FILETIME create, exit, kernel, user;
8025 HANDLE hProc;
8026 hProc = GetCurrentProcess();
8027 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8028 /* The fields of a FILETIME structure are the hi and lo part
8029 of a 64-bit value expressed in 100 nanosecond units.
8030 1e7 is one second in such units; 1e-7 the inverse.
8031 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8032 */
Larry Hastings605a62d2012-06-24 04:33:36 -07008033 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00008034 (double)(user.dwHighDateTime*429.4967296 +
8035 user.dwLowDateTime*1e-7),
8036 (double)(kernel.dwHighDateTime*429.4967296 +
8037 kernel.dwLowDateTime*1e-7),
8038 (double)0,
8039 (double)0,
8040 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008041}
Larry Hastings2f936352014-08-05 14:04:04 +10008042#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008043{
Larry Hastings2f936352014-08-05 14:04:04 +10008044
8045
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008046 struct tms t;
8047 clock_t c;
8048 errno = 0;
8049 c = times(&t);
8050 if (c == (clock_t) -1)
8051 return posix_error();
8052 return build_times_result(
8053 (double)t.tms_utime / ticks_per_second,
8054 (double)t.tms_stime / ticks_per_second,
8055 (double)t.tms_cutime / ticks_per_second,
8056 (double)t.tms_cstime / ticks_per_second,
8057 (double)c / ticks_per_second);
8058}
Larry Hastings2f936352014-08-05 14:04:04 +10008059#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008060#endif /* HAVE_TIMES */
8061
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008062
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008063#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008064/*[clinic input]
8065os.getsid
8066
8067 pid: pid_t
8068 /
8069
8070Call the system call getsid(pid) and return the result.
8071[clinic start generated code]*/
8072
Larry Hastings2f936352014-08-05 14:04:04 +10008073static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008074os_getsid_impl(PyObject *module, pid_t pid)
8075/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008076{
Victor Stinner8c62be82010-05-06 00:08:46 +00008077 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008078 sid = getsid(pid);
8079 if (sid < 0)
8080 return posix_error();
8081 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008082}
8083#endif /* HAVE_GETSID */
8084
8085
Guido van Rossumb6775db1994-08-01 11:34:53 +00008086#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008087/*[clinic input]
8088os.setsid
8089
8090Call the system call setsid().
8091[clinic start generated code]*/
8092
Larry Hastings2f936352014-08-05 14:04:04 +10008093static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008094os_setsid_impl(PyObject *module)
8095/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008096{
Victor Stinner8c62be82010-05-06 00:08:46 +00008097 if (setsid() < 0)
8098 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008099 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008100}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008101#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008102
Larry Hastings2f936352014-08-05 14:04:04 +10008103
Guido van Rossumb6775db1994-08-01 11:34:53 +00008104#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008105/*[clinic input]
8106os.setpgid
8107
8108 pid: pid_t
8109 pgrp: pid_t
8110 /
8111
8112Call the system call setpgid(pid, pgrp).
8113[clinic start generated code]*/
8114
Larry Hastings2f936352014-08-05 14:04:04 +10008115static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008116os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8117/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008118{
Victor Stinner8c62be82010-05-06 00:08:46 +00008119 if (setpgid(pid, pgrp) < 0)
8120 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008121 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008122}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008123#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008124
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008125
Guido van Rossumb6775db1994-08-01 11:34:53 +00008126#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008127/*[clinic input]
8128os.tcgetpgrp
8129
8130 fd: int
8131 /
8132
8133Return the process group associated with the terminal specified by fd.
8134[clinic start generated code]*/
8135
Larry Hastings2f936352014-08-05 14:04:04 +10008136static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008137os_tcgetpgrp_impl(PyObject *module, int fd)
8138/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008139{
8140 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008141 if (pgid < 0)
8142 return posix_error();
8143 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008144}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008145#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008146
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008147
Guido van Rossumb6775db1994-08-01 11:34:53 +00008148#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008149/*[clinic input]
8150os.tcsetpgrp
8151
8152 fd: int
8153 pgid: pid_t
8154 /
8155
8156Set the process group associated with the terminal specified by fd.
8157[clinic start generated code]*/
8158
Larry Hastings2f936352014-08-05 14:04:04 +10008159static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008160os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8161/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008162{
Victor Stinner8c62be82010-05-06 00:08:46 +00008163 if (tcsetpgrp(fd, pgid) < 0)
8164 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008165 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008166}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008167#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008168
Guido van Rossum687dd131993-05-17 08:34:16 +00008169/* Functions acting on file descriptors */
8170
Victor Stinnerdaf45552013-08-28 00:53:59 +02008171#ifdef O_CLOEXEC
8172extern int _Py_open_cloexec_works;
8173#endif
8174
Larry Hastings2f936352014-08-05 14:04:04 +10008175
8176/*[clinic input]
8177os.open -> int
8178 path: path_t
8179 flags: int
8180 mode: int = 0o777
8181 *
8182 dir_fd: dir_fd(requires='openat') = None
8183
8184# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8185
8186Open a file for low level IO. Returns a file descriptor (integer).
8187
8188If dir_fd is not None, it should be a file descriptor open to a directory,
8189 and path should be relative; path will then be relative to that directory.
8190dir_fd may not be implemented on your platform.
8191 If it is unavailable, using it will raise a NotImplementedError.
8192[clinic start generated code]*/
8193
Larry Hastings2f936352014-08-05 14:04:04 +10008194static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008195os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8196/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008197{
8198 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008199 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008200
Victor Stinnerdaf45552013-08-28 00:53:59 +02008201#ifdef O_CLOEXEC
8202 int *atomic_flag_works = &_Py_open_cloexec_works;
8203#elif !defined(MS_WINDOWS)
8204 int *atomic_flag_works = NULL;
8205#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008206
Victor Stinnerdaf45552013-08-28 00:53:59 +02008207#ifdef MS_WINDOWS
8208 flags |= O_NOINHERIT;
8209#elif defined(O_CLOEXEC)
8210 flags |= O_CLOEXEC;
8211#endif
8212
Steve Dower8fc89802015-04-12 00:26:27 -04008213 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008214 do {
8215 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008216#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008217 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008218#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008219#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008220 if (dir_fd != DEFAULT_DIR_FD)
8221 fd = openat(dir_fd, path->narrow, flags, mode);
8222 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008223#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008224 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008225#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008226 Py_END_ALLOW_THREADS
8227 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008228 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008229
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008230 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008231 if (!async_err)
8232 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008233 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008234 }
8235
Victor Stinnerdaf45552013-08-28 00:53:59 +02008236#ifndef MS_WINDOWS
8237 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8238 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008239 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008240 }
8241#endif
8242
Larry Hastings2f936352014-08-05 14:04:04 +10008243 return fd;
8244}
8245
8246
8247/*[clinic input]
8248os.close
8249
8250 fd: int
8251
8252Close a file descriptor.
8253[clinic start generated code]*/
8254
Barry Warsaw53699e91996-12-10 23:23:01 +00008255static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008256os_close_impl(PyObject *module, int fd)
8257/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008258{
Larry Hastings2f936352014-08-05 14:04:04 +10008259 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008260 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8261 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8262 * for more details.
8263 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008264 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008265 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008266 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008267 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008268 Py_END_ALLOW_THREADS
8269 if (res < 0)
8270 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008271 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008272}
8273
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008274
Larry Hastings2f936352014-08-05 14:04:04 +10008275/*[clinic input]
8276os.closerange
8277
8278 fd_low: int
8279 fd_high: int
8280 /
8281
8282Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8283[clinic start generated code]*/
8284
Larry Hastings2f936352014-08-05 14:04:04 +10008285static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008286os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8287/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008288{
8289 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008290 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008291 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008292 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008293 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008294 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008295 Py_END_ALLOW_THREADS
8296 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008297}
8298
8299
Larry Hastings2f936352014-08-05 14:04:04 +10008300/*[clinic input]
8301os.dup -> int
8302
8303 fd: int
8304 /
8305
8306Return a duplicate of a file descriptor.
8307[clinic start generated code]*/
8308
Larry Hastings2f936352014-08-05 14:04:04 +10008309static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008310os_dup_impl(PyObject *module, int fd)
8311/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008312{
8313 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008314}
8315
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008316
Larry Hastings2f936352014-08-05 14:04:04 +10008317/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008318os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008319 fd: int
8320 fd2: int
8321 inheritable: bool=True
8322
8323Duplicate file descriptor.
8324[clinic start generated code]*/
8325
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008326static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008327os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008328/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008329{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008330 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008331#if defined(HAVE_DUP3) && \
8332 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8333 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008334 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008335#endif
8336
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008337 if (fd < 0 || fd2 < 0) {
8338 posix_error();
8339 return -1;
8340 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008341
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008342 /* dup2() can fail with EINTR if the target FD is already open, because it
8343 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8344 * upon close(), and therefore below.
8345 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008346#ifdef MS_WINDOWS
8347 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008348 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008349 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008350 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008351 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008352 if (res < 0) {
8353 posix_error();
8354 return -1;
8355 }
8356 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008357
8358 /* Character files like console cannot be make non-inheritable */
8359 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8360 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008361 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008362 }
8363
8364#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8365 Py_BEGIN_ALLOW_THREADS
8366 if (!inheritable)
8367 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8368 else
8369 res = dup2(fd, fd2);
8370 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008371 if (res < 0) {
8372 posix_error();
8373 return -1;
8374 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008375
8376#else
8377
8378#ifdef HAVE_DUP3
8379 if (!inheritable && dup3_works != 0) {
8380 Py_BEGIN_ALLOW_THREADS
8381 res = dup3(fd, fd2, O_CLOEXEC);
8382 Py_END_ALLOW_THREADS
8383 if (res < 0) {
8384 if (dup3_works == -1)
8385 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008386 if (dup3_works) {
8387 posix_error();
8388 return -1;
8389 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008390 }
8391 }
8392
8393 if (inheritable || dup3_works == 0)
8394 {
8395#endif
8396 Py_BEGIN_ALLOW_THREADS
8397 res = dup2(fd, fd2);
8398 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008399 if (res < 0) {
8400 posix_error();
8401 return -1;
8402 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008403
8404 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8405 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008406 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008407 }
8408#ifdef HAVE_DUP3
8409 }
8410#endif
8411
8412#endif
8413
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008414 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008415}
8416
Larry Hastings2f936352014-08-05 14:04:04 +10008417
Ross Lagerwall7807c352011-03-17 20:20:30 +02008418#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008419/*[clinic input]
8420os.lockf
8421
8422 fd: int
8423 An open file descriptor.
8424 command: int
8425 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8426 length: Py_off_t
8427 The number of bytes to lock, starting at the current position.
8428 /
8429
8430Apply, test or remove a POSIX lock on an open file descriptor.
8431
8432[clinic start generated code]*/
8433
Larry Hastings2f936352014-08-05 14:04:04 +10008434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008435os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8436/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008437{
8438 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008439
8440 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008441 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008442 Py_END_ALLOW_THREADS
8443
8444 if (res < 0)
8445 return posix_error();
8446
8447 Py_RETURN_NONE;
8448}
Larry Hastings2f936352014-08-05 14:04:04 +10008449#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008450
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008451
Larry Hastings2f936352014-08-05 14:04:04 +10008452/*[clinic input]
8453os.lseek -> Py_off_t
8454
8455 fd: int
8456 position: Py_off_t
8457 how: int
8458 /
8459
8460Set the position of a file descriptor. Return the new position.
8461
8462Return the new cursor position in number of bytes
8463relative to the beginning of the file.
8464[clinic start generated code]*/
8465
Larry Hastings2f936352014-08-05 14:04:04 +10008466static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008467os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8468/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008469{
8470 Py_off_t result;
8471
Guido van Rossum687dd131993-05-17 08:34:16 +00008472#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008473 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8474 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008475 case 0: how = SEEK_SET; break;
8476 case 1: how = SEEK_CUR; break;
8477 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008478 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008479#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008480
Victor Stinner8c62be82010-05-06 00:08:46 +00008481 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008482 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008483#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008484 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008485#else
Larry Hastings2f936352014-08-05 14:04:04 +10008486 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008487#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008488 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008489 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008490 if (result < 0)
8491 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008492
Larry Hastings2f936352014-08-05 14:04:04 +10008493 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008494}
8495
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008496
Larry Hastings2f936352014-08-05 14:04:04 +10008497/*[clinic input]
8498os.read
8499 fd: int
8500 length: Py_ssize_t
8501 /
8502
8503Read from a file descriptor. Returns a bytes object.
8504[clinic start generated code]*/
8505
Larry Hastings2f936352014-08-05 14:04:04 +10008506static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008507os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8508/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008509{
Victor Stinner8c62be82010-05-06 00:08:46 +00008510 Py_ssize_t n;
8511 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008512
8513 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008514 errno = EINVAL;
8515 return posix_error();
8516 }
Larry Hastings2f936352014-08-05 14:04:04 +10008517
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008518 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008519
8520 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008521 if (buffer == NULL)
8522 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008523
Victor Stinner66aab0c2015-03-19 22:53:20 +01008524 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8525 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008526 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008527 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008528 }
Larry Hastings2f936352014-08-05 14:04:04 +10008529
8530 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008531 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008532
Victor Stinner8c62be82010-05-06 00:08:46 +00008533 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008534}
8535
Ross Lagerwall7807c352011-03-17 20:20:30 +02008536#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008537 || defined(__APPLE__))) \
8538 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8539 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8540static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008541iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008542{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008543 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008544
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008545 *iov = PyMem_New(struct iovec, cnt);
8546 if (*iov == NULL) {
8547 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008548 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008549 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008550
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008551 *buf = PyMem_New(Py_buffer, cnt);
8552 if (*buf == NULL) {
8553 PyMem_Del(*iov);
8554 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008555 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008556 }
8557
8558 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008559 PyObject *item = PySequence_GetItem(seq, i);
8560 if (item == NULL)
8561 goto fail;
8562 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8563 Py_DECREF(item);
8564 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008565 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008566 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008567 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008568 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008569 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008570 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008571
8572fail:
8573 PyMem_Del(*iov);
8574 for (j = 0; j < i; j++) {
8575 PyBuffer_Release(&(*buf)[j]);
8576 }
8577 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008578 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008579}
8580
8581static void
8582iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8583{
8584 int i;
8585 PyMem_Del(iov);
8586 for (i = 0; i < cnt; i++) {
8587 PyBuffer_Release(&buf[i]);
8588 }
8589 PyMem_Del(buf);
8590}
8591#endif
8592
Larry Hastings2f936352014-08-05 14:04:04 +10008593
Ross Lagerwall7807c352011-03-17 20:20:30 +02008594#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008595/*[clinic input]
8596os.readv -> Py_ssize_t
8597
8598 fd: int
8599 buffers: object
8600 /
8601
8602Read from a file descriptor fd into an iterable of buffers.
8603
8604The buffers should be mutable buffers accepting bytes.
8605readv will transfer data into each buffer until it is full
8606and then move on to the next buffer in the sequence to hold
8607the rest of the data.
8608
8609readv returns the total number of bytes read,
8610which may be less than the total capacity of all the buffers.
8611[clinic start generated code]*/
8612
Larry Hastings2f936352014-08-05 14:04:04 +10008613static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008614os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8615/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008616{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008617 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008618 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008619 struct iovec *iov;
8620 Py_buffer *buf;
8621
Larry Hastings2f936352014-08-05 14:04:04 +10008622 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008623 PyErr_SetString(PyExc_TypeError,
8624 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008625 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008626 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008627
Larry Hastings2f936352014-08-05 14:04:04 +10008628 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008629 if (cnt < 0)
8630 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008631
8632 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8633 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008634
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008635 do {
8636 Py_BEGIN_ALLOW_THREADS
8637 n = readv(fd, iov, cnt);
8638 Py_END_ALLOW_THREADS
8639 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008640
8641 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008642 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008643 if (!async_err)
8644 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008645 return -1;
8646 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008647
Larry Hastings2f936352014-08-05 14:04:04 +10008648 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008649}
Larry Hastings2f936352014-08-05 14:04:04 +10008650#endif /* HAVE_READV */
8651
Ross Lagerwall7807c352011-03-17 20:20:30 +02008652
8653#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008654/*[clinic input]
8655# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8656os.pread
8657
8658 fd: int
8659 length: int
8660 offset: Py_off_t
8661 /
8662
8663Read a number of bytes from a file descriptor starting at a particular offset.
8664
8665Read length bytes from file descriptor fd, starting at offset bytes from
8666the beginning of the file. The file offset remains unchanged.
8667[clinic start generated code]*/
8668
Larry Hastings2f936352014-08-05 14:04:04 +10008669static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008670os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8671/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008672{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008673 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008674 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008675 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008676
Larry Hastings2f936352014-08-05 14:04:04 +10008677 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008678 errno = EINVAL;
8679 return posix_error();
8680 }
Larry Hastings2f936352014-08-05 14:04:04 +10008681 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008682 if (buffer == NULL)
8683 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008684
8685 do {
8686 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008687 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008688 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008689 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008690 Py_END_ALLOW_THREADS
8691 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8692
Ross Lagerwall7807c352011-03-17 20:20:30 +02008693 if (n < 0) {
8694 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008695 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008696 }
Larry Hastings2f936352014-08-05 14:04:04 +10008697 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008698 _PyBytes_Resize(&buffer, n);
8699 return buffer;
8700}
Larry Hastings2f936352014-08-05 14:04:04 +10008701#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008702
Pablo Galindo4defba32018-01-27 16:16:37 +00008703#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8704/*[clinic input]
8705os.preadv -> Py_ssize_t
8706
8707 fd: int
8708 buffers: object
8709 offset: Py_off_t
8710 flags: int = 0
8711 /
8712
8713Reads from a file descriptor into a number of mutable bytes-like objects.
8714
8715Combines the functionality of readv() and pread(). As readv(), it will
8716transfer data into each buffer until it is full and then move on to the next
8717buffer in the sequence to hold the rest of the data. Its fourth argument,
8718specifies the file offset at which the input operation is to be performed. It
8719will return the total number of bytes read (which can be less than the total
8720capacity of all the objects).
8721
8722The flags argument contains a bitwise OR of zero or more of the following flags:
8723
8724- RWF_HIPRI
8725- RWF_NOWAIT
8726
8727Using non-zero flags requires Linux 4.6 or newer.
8728[clinic start generated code]*/
8729
8730static Py_ssize_t
8731os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8732 int flags)
8733/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8734{
8735 Py_ssize_t cnt, n;
8736 int async_err = 0;
8737 struct iovec *iov;
8738 Py_buffer *buf;
8739
8740 if (!PySequence_Check(buffers)) {
8741 PyErr_SetString(PyExc_TypeError,
8742 "preadv2() arg 2 must be a sequence");
8743 return -1;
8744 }
8745
8746 cnt = PySequence_Size(buffers);
8747 if (cnt < 0) {
8748 return -1;
8749 }
8750
8751#ifndef HAVE_PREADV2
8752 if(flags != 0) {
8753 argument_unavailable_error("preadv2", "flags");
8754 return -1;
8755 }
8756#endif
8757
8758 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8759 return -1;
8760 }
8761#ifdef HAVE_PREADV2
8762 do {
8763 Py_BEGIN_ALLOW_THREADS
8764 _Py_BEGIN_SUPPRESS_IPH
8765 n = preadv2(fd, iov, cnt, offset, flags);
8766 _Py_END_SUPPRESS_IPH
8767 Py_END_ALLOW_THREADS
8768 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8769#else
8770 do {
8771 Py_BEGIN_ALLOW_THREADS
8772 _Py_BEGIN_SUPPRESS_IPH
8773 n = preadv(fd, iov, cnt, offset);
8774 _Py_END_SUPPRESS_IPH
8775 Py_END_ALLOW_THREADS
8776 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8777#endif
8778
8779 iov_cleanup(iov, buf, cnt);
8780 if (n < 0) {
8781 if (!async_err) {
8782 posix_error();
8783 }
8784 return -1;
8785 }
8786
8787 return n;
8788}
8789#endif /* HAVE_PREADV */
8790
Larry Hastings2f936352014-08-05 14:04:04 +10008791
8792/*[clinic input]
8793os.write -> Py_ssize_t
8794
8795 fd: int
8796 data: Py_buffer
8797 /
8798
8799Write a bytes object to a file descriptor.
8800[clinic start generated code]*/
8801
Larry Hastings2f936352014-08-05 14:04:04 +10008802static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008803os_write_impl(PyObject *module, int fd, Py_buffer *data)
8804/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008805{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008806 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008807}
8808
8809#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008810PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008811"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008812sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008813 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008814Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008815
Larry Hastings2f936352014-08-05 14:04:04 +10008816/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008817static PyObject *
8818posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8819{
8820 int in, out;
8821 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008822 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008823 off_t offset;
8824
8825#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8826#ifndef __APPLE__
8827 Py_ssize_t len;
8828#endif
8829 PyObject *headers = NULL, *trailers = NULL;
8830 Py_buffer *hbuf, *tbuf;
8831 off_t sbytes;
8832 struct sf_hdtr sf;
8833 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008834 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008835 static char *keywords[] = {"out", "in",
8836 "offset", "count",
8837 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008838
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008839 sf.headers = NULL;
8840 sf.trailers = NULL;
8841
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008842#ifdef __APPLE__
8843 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008844 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008845#else
8846 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008847 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008848#endif
8849 &headers, &trailers, &flags))
8850 return NULL;
8851 if (headers != NULL) {
8852 if (!PySequence_Check(headers)) {
8853 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008854 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008855 return NULL;
8856 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008857 Py_ssize_t i = PySequence_Size(headers);
8858 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008859 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008860 if (i > INT_MAX) {
8861 PyErr_SetString(PyExc_OverflowError,
8862 "sendfile() header is too large");
8863 return NULL;
8864 }
8865 if (i > 0) {
8866 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008867 if (iov_setup(&(sf.headers), &hbuf,
8868 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008869 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008870#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008871 for (i = 0; i < sf.hdr_cnt; i++) {
8872 Py_ssize_t blen = sf.headers[i].iov_len;
8873# define OFF_T_MAX 0x7fffffffffffffff
8874 if (sbytes >= OFF_T_MAX - blen) {
8875 PyErr_SetString(PyExc_OverflowError,
8876 "sendfile() header is too large");
8877 return NULL;
8878 }
8879 sbytes += blen;
8880 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008881#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008882 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008883 }
8884 }
8885 if (trailers != NULL) {
8886 if (!PySequence_Check(trailers)) {
8887 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008888 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008889 return NULL;
8890 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008891 Py_ssize_t i = PySequence_Size(trailers);
8892 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008893 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008894 if (i > INT_MAX) {
8895 PyErr_SetString(PyExc_OverflowError,
8896 "sendfile() trailer is too large");
8897 return NULL;
8898 }
8899 if (i > 0) {
8900 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008901 if (iov_setup(&(sf.trailers), &tbuf,
8902 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008903 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008904 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008905 }
8906 }
8907
Steve Dower8fc89802015-04-12 00:26:27 -04008908 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008909 do {
8910 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008911#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008912 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008913#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008914 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008915#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008916 Py_END_ALLOW_THREADS
8917 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008918 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008919
8920 if (sf.headers != NULL)
8921 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8922 if (sf.trailers != NULL)
8923 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8924
8925 if (ret < 0) {
8926 if ((errno == EAGAIN) || (errno == EBUSY)) {
8927 if (sbytes != 0) {
8928 // some data has been sent
8929 goto done;
8930 }
8931 else {
8932 // no data has been sent; upper application is supposed
8933 // to retry on EAGAIN or EBUSY
8934 return posix_error();
8935 }
8936 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008937 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008938 }
8939 goto done;
8940
8941done:
8942 #if !defined(HAVE_LARGEFILE_SUPPORT)
8943 return Py_BuildValue("l", sbytes);
8944 #else
8945 return Py_BuildValue("L", sbytes);
8946 #endif
8947
8948#else
8949 Py_ssize_t count;
8950 PyObject *offobj;
8951 static char *keywords[] = {"out", "in",
8952 "offset", "count", NULL};
8953 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8954 keywords, &out, &in, &offobj, &count))
8955 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008956#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008957 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008958 do {
8959 Py_BEGIN_ALLOW_THREADS
8960 ret = sendfile(out, in, NULL, count);
8961 Py_END_ALLOW_THREADS
8962 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008963 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008964 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008965 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008966 }
8967#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008968 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008969 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008970
8971 do {
8972 Py_BEGIN_ALLOW_THREADS
8973 ret = sendfile(out, in, &offset, count);
8974 Py_END_ALLOW_THREADS
8975 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008976 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008977 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008978 return Py_BuildValue("n", ret);
8979#endif
8980}
Larry Hastings2f936352014-08-05 14:04:04 +10008981#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008982
Larry Hastings2f936352014-08-05 14:04:04 +10008983
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008984#if defined(__APPLE__)
8985/*[clinic input]
8986os._fcopyfile
8987
8988 infd: int
8989 outfd: int
8990 flags: int
8991 /
8992
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008993Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008994[clinic start generated code]*/
8995
8996static PyObject *
8997os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008998/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008999{
9000 int ret;
9001
9002 Py_BEGIN_ALLOW_THREADS
9003 ret = fcopyfile(infd, outfd, NULL, flags);
9004 Py_END_ALLOW_THREADS
9005 if (ret < 0)
9006 return posix_error();
9007 Py_RETURN_NONE;
9008}
9009#endif
9010
9011
Larry Hastings2f936352014-08-05 14:04:04 +10009012/*[clinic input]
9013os.fstat
9014
9015 fd : int
9016
9017Perform a stat system call on the given file descriptor.
9018
9019Like stat(), but for an open file descriptor.
9020Equivalent to os.stat(fd).
9021[clinic start generated code]*/
9022
Larry Hastings2f936352014-08-05 14:04:04 +10009023static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009024os_fstat_impl(PyObject *module, int fd)
9025/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009026{
Victor Stinner8c62be82010-05-06 00:08:46 +00009027 STRUCT_STAT st;
9028 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009029 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009030
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009031 do {
9032 Py_BEGIN_ALLOW_THREADS
9033 res = FSTAT(fd, &st);
9034 Py_END_ALLOW_THREADS
9035 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009036 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009037#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009038 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009039#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009040 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009041#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009042 }
Tim Peters5aa91602002-01-30 05:46:57 +00009043
Victor Stinner4195b5c2012-02-08 23:03:19 +01009044 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009045}
9046
Larry Hastings2f936352014-08-05 14:04:04 +10009047
9048/*[clinic input]
9049os.isatty -> bool
9050 fd: int
9051 /
9052
9053Return True if the fd is connected to a terminal.
9054
9055Return True if the file descriptor is an open file descriptor
9056connected to the slave end of a terminal.
9057[clinic start generated code]*/
9058
Larry Hastings2f936352014-08-05 14:04:04 +10009059static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009060os_isatty_impl(PyObject *module, int fd)
9061/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009062{
Steve Dower8fc89802015-04-12 00:26:27 -04009063 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009064 _Py_BEGIN_SUPPRESS_IPH
9065 return_value = isatty(fd);
9066 _Py_END_SUPPRESS_IPH
9067 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009068}
9069
9070
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009071#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009072/*[clinic input]
9073os.pipe
9074
9075Create a pipe.
9076
9077Returns a tuple of two file descriptors:
9078 (read_fd, write_fd)
9079[clinic start generated code]*/
9080
Larry Hastings2f936352014-08-05 14:04:04 +10009081static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009082os_pipe_impl(PyObject *module)
9083/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009084{
Victor Stinner8c62be82010-05-06 00:08:46 +00009085 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009086#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009088 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009090#else
9091 int res;
9092#endif
9093
9094#ifdef MS_WINDOWS
9095 attr.nLength = sizeof(attr);
9096 attr.lpSecurityDescriptor = NULL;
9097 attr.bInheritHandle = FALSE;
9098
9099 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009100 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009101 ok = CreatePipe(&read, &write, &attr, 0);
9102 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009103 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9104 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009105 if (fds[0] == -1 || fds[1] == -1) {
9106 CloseHandle(read);
9107 CloseHandle(write);
9108 ok = 0;
9109 }
9110 }
Steve Dowerc3630612016-11-19 18:41:16 -08009111 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009112 Py_END_ALLOW_THREADS
9113
Victor Stinner8c62be82010-05-06 00:08:46 +00009114 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009115 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009116#else
9117
9118#ifdef HAVE_PIPE2
9119 Py_BEGIN_ALLOW_THREADS
9120 res = pipe2(fds, O_CLOEXEC);
9121 Py_END_ALLOW_THREADS
9122
9123 if (res != 0 && errno == ENOSYS)
9124 {
9125#endif
9126 Py_BEGIN_ALLOW_THREADS
9127 res = pipe(fds);
9128 Py_END_ALLOW_THREADS
9129
9130 if (res == 0) {
9131 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9132 close(fds[0]);
9133 close(fds[1]);
9134 return NULL;
9135 }
9136 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9137 close(fds[0]);
9138 close(fds[1]);
9139 return NULL;
9140 }
9141 }
9142#ifdef HAVE_PIPE2
9143 }
9144#endif
9145
9146 if (res != 0)
9147 return PyErr_SetFromErrno(PyExc_OSError);
9148#endif /* !MS_WINDOWS */
9149 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009150}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009151#endif /* HAVE_PIPE */
9152
Larry Hastings2f936352014-08-05 14:04:04 +10009153
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009154#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009155/*[clinic input]
9156os.pipe2
9157
9158 flags: int
9159 /
9160
9161Create a pipe with flags set atomically.
9162
9163Returns a tuple of two file descriptors:
9164 (read_fd, write_fd)
9165
9166flags can be constructed by ORing together one or more of these values:
9167O_NONBLOCK, O_CLOEXEC.
9168[clinic start generated code]*/
9169
Larry Hastings2f936352014-08-05 14:04:04 +10009170static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009171os_pipe2_impl(PyObject *module, int flags)
9172/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009173{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009174 int fds[2];
9175 int res;
9176
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009177 res = pipe2(fds, flags);
9178 if (res != 0)
9179 return posix_error();
9180 return Py_BuildValue("(ii)", fds[0], fds[1]);
9181}
9182#endif /* HAVE_PIPE2 */
9183
Larry Hastings2f936352014-08-05 14:04:04 +10009184
Ross Lagerwall7807c352011-03-17 20:20:30 +02009185#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009186/*[clinic input]
9187os.writev -> Py_ssize_t
9188 fd: int
9189 buffers: object
9190 /
9191
9192Iterate over buffers, and write the contents of each to a file descriptor.
9193
9194Returns the total number of bytes written.
9195buffers must be a sequence of bytes-like objects.
9196[clinic start generated code]*/
9197
Larry Hastings2f936352014-08-05 14:04:04 +10009198static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009199os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9200/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009201{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009202 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009203 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009204 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009205 struct iovec *iov;
9206 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009207
9208 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009209 PyErr_SetString(PyExc_TypeError,
9210 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009211 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009212 }
Larry Hastings2f936352014-08-05 14:04:04 +10009213 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009214 if (cnt < 0)
9215 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009216
Larry Hastings2f936352014-08-05 14:04:04 +10009217 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9218 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009219 }
9220
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009221 do {
9222 Py_BEGIN_ALLOW_THREADS
9223 result = writev(fd, iov, cnt);
9224 Py_END_ALLOW_THREADS
9225 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009226
9227 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009228 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009229 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009230
Georg Brandl306336b2012-06-24 12:55:33 +02009231 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009232}
Larry Hastings2f936352014-08-05 14:04:04 +10009233#endif /* HAVE_WRITEV */
9234
9235
9236#ifdef HAVE_PWRITE
9237/*[clinic input]
9238os.pwrite -> Py_ssize_t
9239
9240 fd: int
9241 buffer: Py_buffer
9242 offset: Py_off_t
9243 /
9244
9245Write bytes to a file descriptor starting at a particular offset.
9246
9247Write buffer to fd, starting at offset bytes from the beginning of
9248the file. Returns the number of bytes writte. Does not change the
9249current file offset.
9250[clinic start generated code]*/
9251
Larry Hastings2f936352014-08-05 14:04:04 +10009252static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009253os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9254/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009255{
9256 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009257 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009258
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009259 do {
9260 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009261 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009262 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009263 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009264 Py_END_ALLOW_THREADS
9265 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009266
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009267 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009268 posix_error();
9269 return size;
9270}
9271#endif /* HAVE_PWRITE */
9272
Pablo Galindo4defba32018-01-27 16:16:37 +00009273#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9274/*[clinic input]
9275os.pwritev -> Py_ssize_t
9276
9277 fd: int
9278 buffers: object
9279 offset: Py_off_t
9280 flags: int = 0
9281 /
9282
9283Writes the contents of bytes-like objects to a file descriptor at a given offset.
9284
9285Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9286of bytes-like objects. Buffers are processed in array order. Entire contents of first
9287buffer is written before proceeding to second, and so on. The operating system may
9288set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9289This function writes the contents of each object to the file descriptor and returns
9290the total number of bytes written.
9291
9292The flags argument contains a bitwise OR of zero or more of the following flags:
9293
9294- RWF_DSYNC
9295- RWF_SYNC
9296
9297Using non-zero flags requires Linux 4.7 or newer.
9298[clinic start generated code]*/
9299
9300static Py_ssize_t
9301os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9302 int flags)
9303/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9304{
9305 Py_ssize_t cnt;
9306 Py_ssize_t result;
9307 int async_err = 0;
9308 struct iovec *iov;
9309 Py_buffer *buf;
9310
9311 if (!PySequence_Check(buffers)) {
9312 PyErr_SetString(PyExc_TypeError,
9313 "pwritev() arg 2 must be a sequence");
9314 return -1;
9315 }
9316
9317 cnt = PySequence_Size(buffers);
9318 if (cnt < 0) {
9319 return -1;
9320 }
9321
9322#ifndef HAVE_PWRITEV2
9323 if(flags != 0) {
9324 argument_unavailable_error("pwritev2", "flags");
9325 return -1;
9326 }
9327#endif
9328
9329 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9330 return -1;
9331 }
9332#ifdef HAVE_PWRITEV2
9333 do {
9334 Py_BEGIN_ALLOW_THREADS
9335 _Py_BEGIN_SUPPRESS_IPH
9336 result = pwritev2(fd, iov, cnt, offset, flags);
9337 _Py_END_SUPPRESS_IPH
9338 Py_END_ALLOW_THREADS
9339 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9340#else
9341 do {
9342 Py_BEGIN_ALLOW_THREADS
9343 _Py_BEGIN_SUPPRESS_IPH
9344 result = pwritev(fd, iov, cnt, offset);
9345 _Py_END_SUPPRESS_IPH
9346 Py_END_ALLOW_THREADS
9347 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9348#endif
9349
9350 iov_cleanup(iov, buf, cnt);
9351 if (result < 0) {
9352 if (!async_err) {
9353 posix_error();
9354 }
9355 return -1;
9356 }
9357
9358 return result;
9359}
9360#endif /* HAVE_PWRITEV */
9361
9362
9363
Larry Hastings2f936352014-08-05 14:04:04 +10009364
9365#ifdef HAVE_MKFIFO
9366/*[clinic input]
9367os.mkfifo
9368
9369 path: path_t
9370 mode: int=0o666
9371 *
9372 dir_fd: dir_fd(requires='mkfifoat')=None
9373
9374Create a "fifo" (a POSIX named pipe).
9375
9376If dir_fd is not None, it should be a file descriptor open to a directory,
9377 and path should be relative; path will then be relative to that directory.
9378dir_fd may not be implemented on your platform.
9379 If it is unavailable, using it will raise a NotImplementedError.
9380[clinic start generated code]*/
9381
Larry Hastings2f936352014-08-05 14:04:04 +10009382static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009383os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9384/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009385{
9386 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009387 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009388
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009389 do {
9390 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009391#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009392 if (dir_fd != DEFAULT_DIR_FD)
9393 result = mkfifoat(dir_fd, path->narrow, mode);
9394 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009395#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009396 result = mkfifo(path->narrow, mode);
9397 Py_END_ALLOW_THREADS
9398 } while (result != 0 && errno == EINTR &&
9399 !(async_err = PyErr_CheckSignals()));
9400 if (result != 0)
9401 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009402
9403 Py_RETURN_NONE;
9404}
9405#endif /* HAVE_MKFIFO */
9406
9407
9408#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9409/*[clinic input]
9410os.mknod
9411
9412 path: path_t
9413 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009414 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009415 *
9416 dir_fd: dir_fd(requires='mknodat')=None
9417
9418Create a node in the file system.
9419
9420Create a node in the file system (file, device special file or named pipe)
9421at path. mode specifies both the permissions to use and the
9422type of node to be created, being combined (bitwise OR) with one of
9423S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9424device defines the newly created device special file (probably using
9425os.makedev()). Otherwise device is ignored.
9426
9427If dir_fd is not None, it should be a file descriptor open to a directory,
9428 and path should be relative; path will then be relative to that directory.
9429dir_fd may not be implemented on your platform.
9430 If it is unavailable, using it will raise a NotImplementedError.
9431[clinic start generated code]*/
9432
Larry Hastings2f936352014-08-05 14:04:04 +10009433static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009434os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009435 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009436/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009437{
9438 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009439 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009440
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009441 do {
9442 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009443#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009444 if (dir_fd != DEFAULT_DIR_FD)
9445 result = mknodat(dir_fd, path->narrow, mode, device);
9446 else
Larry Hastings2f936352014-08-05 14:04:04 +10009447#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009448 result = mknod(path->narrow, mode, device);
9449 Py_END_ALLOW_THREADS
9450 } while (result != 0 && errno == EINTR &&
9451 !(async_err = PyErr_CheckSignals()));
9452 if (result != 0)
9453 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009454
9455 Py_RETURN_NONE;
9456}
9457#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9458
9459
9460#ifdef HAVE_DEVICE_MACROS
9461/*[clinic input]
9462os.major -> unsigned_int
9463
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009464 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009465 /
9466
9467Extracts a device major number from a raw device number.
9468[clinic start generated code]*/
9469
Larry Hastings2f936352014-08-05 14:04:04 +10009470static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009471os_major_impl(PyObject *module, dev_t device)
9472/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009473{
9474 return major(device);
9475}
9476
9477
9478/*[clinic input]
9479os.minor -> unsigned_int
9480
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009481 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009482 /
9483
9484Extracts a device minor number from a raw device number.
9485[clinic start generated code]*/
9486
Larry Hastings2f936352014-08-05 14:04:04 +10009487static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009488os_minor_impl(PyObject *module, dev_t device)
9489/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009490{
9491 return minor(device);
9492}
9493
9494
9495/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009496os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009497
9498 major: int
9499 minor: int
9500 /
9501
9502Composes a raw device number from the major and minor device numbers.
9503[clinic start generated code]*/
9504
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009505static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009506os_makedev_impl(PyObject *module, int major, int minor)
9507/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009508{
9509 return makedev(major, minor);
9510}
9511#endif /* HAVE_DEVICE_MACROS */
9512
9513
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009514#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009515/*[clinic input]
9516os.ftruncate
9517
9518 fd: int
9519 length: Py_off_t
9520 /
9521
9522Truncate a file, specified by file descriptor, to a specific length.
9523[clinic start generated code]*/
9524
Larry Hastings2f936352014-08-05 14:04:04 +10009525static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009526os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9527/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009528{
9529 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009530 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009531
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009532 do {
9533 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009534 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009535#ifdef MS_WINDOWS
9536 result = _chsize_s(fd, length);
9537#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009538 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009539#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009540 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009541 Py_END_ALLOW_THREADS
9542 } while (result != 0 && errno == EINTR &&
9543 !(async_err = PyErr_CheckSignals()));
9544 if (result != 0)
9545 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009546 Py_RETURN_NONE;
9547}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009548#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009549
9550
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009551#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009552/*[clinic input]
9553os.truncate
9554 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9555 length: Py_off_t
9556
9557Truncate a file, specified by path, to a specific length.
9558
9559On some platforms, path may also be specified as an open file descriptor.
9560 If this functionality is unavailable, using it raises an exception.
9561[clinic start generated code]*/
9562
Larry Hastings2f936352014-08-05 14:04:04 +10009563static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009564os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9565/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009566{
9567 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009568#ifdef MS_WINDOWS
9569 int fd;
9570#endif
9571
9572 if (path->fd != -1)
9573 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009574
9575 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009576 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009577#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009578 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009579 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009580 result = -1;
9581 else {
9582 result = _chsize_s(fd, length);
9583 close(fd);
9584 if (result < 0)
9585 errno = result;
9586 }
9587#else
9588 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009589#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009590 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009591 Py_END_ALLOW_THREADS
9592 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009593 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009594
9595 Py_RETURN_NONE;
9596}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009597#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009598
Ross Lagerwall7807c352011-03-17 20:20:30 +02009599
Victor Stinnerd6b17692014-09-30 12:20:05 +02009600/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9601 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9602 defined, which is the case in Python on AIX. AIX bug report:
9603 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9604#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9605# define POSIX_FADVISE_AIX_BUG
9606#endif
9607
Victor Stinnerec39e262014-09-30 12:35:58 +02009608
Victor Stinnerd6b17692014-09-30 12:20:05 +02009609#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009610/*[clinic input]
9611os.posix_fallocate
9612
9613 fd: int
9614 offset: Py_off_t
9615 length: Py_off_t
9616 /
9617
9618Ensure a file has allocated at least a particular number of bytes on disk.
9619
9620Ensure that the file specified by fd encompasses a range of bytes
9621starting at offset bytes from the beginning and continuing for length bytes.
9622[clinic start generated code]*/
9623
Larry Hastings2f936352014-08-05 14:04:04 +10009624static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009625os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009626 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009627/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009628{
9629 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009630 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009631
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009632 do {
9633 Py_BEGIN_ALLOW_THREADS
9634 result = posix_fallocate(fd, offset, length);
9635 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009636 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9637
9638 if (result == 0)
9639 Py_RETURN_NONE;
9640
9641 if (async_err)
9642 return NULL;
9643
9644 errno = result;
9645 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009646}
Victor Stinnerec39e262014-09-30 12:35:58 +02009647#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009648
Ross Lagerwall7807c352011-03-17 20:20:30 +02009649
Victor Stinnerd6b17692014-09-30 12:20:05 +02009650#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009651/*[clinic input]
9652os.posix_fadvise
9653
9654 fd: int
9655 offset: Py_off_t
9656 length: Py_off_t
9657 advice: int
9658 /
9659
9660Announce an intention to access data in a specific pattern.
9661
9662Announce an intention to access data in a specific pattern, thus allowing
9663the kernel to make optimizations.
9664The advice applies to the region of the file specified by fd starting at
9665offset and continuing for length bytes.
9666advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9667POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9668POSIX_FADV_DONTNEED.
9669[clinic start generated code]*/
9670
Larry Hastings2f936352014-08-05 14:04:04 +10009671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009672os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009673 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009674/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009675{
9676 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009677 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009678
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009679 do {
9680 Py_BEGIN_ALLOW_THREADS
9681 result = posix_fadvise(fd, offset, length, advice);
9682 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009683 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9684
9685 if (result == 0)
9686 Py_RETURN_NONE;
9687
9688 if (async_err)
9689 return NULL;
9690
9691 errno = result;
9692 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009693}
Victor Stinnerec39e262014-09-30 12:35:58 +02009694#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009695
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009696#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009697
Fred Drake762e2061999-08-26 17:23:54 +00009698/* Save putenv() parameters as values here, so we can collect them when they
9699 * get re-set with another call for the same key. */
9700static PyObject *posix_putenv_garbage;
9701
Larry Hastings2f936352014-08-05 14:04:04 +10009702static void
9703posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009704{
Larry Hastings2f936352014-08-05 14:04:04 +10009705 /* Install the first arg and newstr in posix_putenv_garbage;
9706 * this will cause previous value to be collected. This has to
9707 * happen after the real putenv() call because the old value
9708 * was still accessible until then. */
9709 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9710 /* really not much we can do; just leak */
9711 PyErr_Clear();
9712 else
9713 Py_DECREF(value);
9714}
9715
9716
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009717#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009718/*[clinic input]
9719os.putenv
9720
9721 name: unicode
9722 value: unicode
9723 /
9724
9725Change or add an environment variable.
9726[clinic start generated code]*/
9727
Larry Hastings2f936352014-08-05 14:04:04 +10009728static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009729os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9730/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009731{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009732 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009733 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009734
Serhiy Storchaka77703942017-06-25 07:33:01 +03009735 /* Search from index 1 because on Windows starting '=' is allowed for
9736 defining hidden environment variables. */
9737 if (PyUnicode_GET_LENGTH(name) == 0 ||
9738 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9739 {
9740 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9741 return NULL;
9742 }
Larry Hastings2f936352014-08-05 14:04:04 +10009743 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9744 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009745 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009746 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009747
9748 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9749 if (env == NULL)
9750 goto error;
9751 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009752 PyErr_Format(PyExc_ValueError,
9753 "the environment variable is longer than %u characters",
9754 _MAX_ENV);
9755 goto error;
9756 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009757 if (wcslen(env) != (size_t)size) {
9758 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009759 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009760 }
9761
Larry Hastings2f936352014-08-05 14:04:04 +10009762 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009764 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009766
Larry Hastings2f936352014-08-05 14:04:04 +10009767 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009768 Py_RETURN_NONE;
9769
9770error:
Larry Hastings2f936352014-08-05 14:04:04 +10009771 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009772 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009773}
Larry Hastings2f936352014-08-05 14:04:04 +10009774#else /* MS_WINDOWS */
9775/*[clinic input]
9776os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009777
Larry Hastings2f936352014-08-05 14:04:04 +10009778 name: FSConverter
9779 value: FSConverter
9780 /
9781
9782Change or add an environment variable.
9783[clinic start generated code]*/
9784
Larry Hastings2f936352014-08-05 14:04:04 +10009785static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009786os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9787/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009788{
9789 PyObject *bytes = NULL;
9790 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009791 const char *name_string = PyBytes_AS_STRING(name);
9792 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009793
Serhiy Storchaka77703942017-06-25 07:33:01 +03009794 if (strchr(name_string, '=') != NULL) {
9795 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9796 return NULL;
9797 }
Larry Hastings2f936352014-08-05 14:04:04 +10009798 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9799 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009800 return NULL;
9801 }
9802
9803 env = PyBytes_AS_STRING(bytes);
9804 if (putenv(env)) {
9805 Py_DECREF(bytes);
9806 return posix_error();
9807 }
9808
9809 posix_putenv_garbage_setitem(name, bytes);
9810 Py_RETURN_NONE;
9811}
9812#endif /* MS_WINDOWS */
9813#endif /* HAVE_PUTENV */
9814
9815
9816#ifdef HAVE_UNSETENV
9817/*[clinic input]
9818os.unsetenv
9819 name: FSConverter
9820 /
9821
9822Delete an environment variable.
9823[clinic start generated code]*/
9824
Larry Hastings2f936352014-08-05 14:04:04 +10009825static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009826os_unsetenv_impl(PyObject *module, PyObject *name)
9827/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009828{
Victor Stinner984890f2011-11-24 13:53:38 +01009829#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009830 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009831#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009832
Victor Stinner984890f2011-11-24 13:53:38 +01009833#ifdef HAVE_BROKEN_UNSETENV
9834 unsetenv(PyBytes_AS_STRING(name));
9835#else
Victor Stinner65170952011-11-22 22:16:17 +01009836 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009837 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009838 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009839#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009840
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 /* Remove the key from posix_putenv_garbage;
9842 * this will cause it to be collected. This has to
9843 * happen after the real unsetenv() call because the
9844 * old value was still accessible until then.
9845 */
Victor Stinner65170952011-11-22 22:16:17 +01009846 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 /* really not much we can do; just leak */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02009848 if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
9849 return NULL;
9850 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 PyErr_Clear();
9852 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009853 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009854}
Larry Hastings2f936352014-08-05 14:04:04 +10009855#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009856
Larry Hastings2f936352014-08-05 14:04:04 +10009857
9858/*[clinic input]
9859os.strerror
9860
9861 code: int
9862 /
9863
9864Translate an error code to a message string.
9865[clinic start generated code]*/
9866
Larry Hastings2f936352014-08-05 14:04:04 +10009867static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009868os_strerror_impl(PyObject *module, int code)
9869/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009870{
9871 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 if (message == NULL) {
9873 PyErr_SetString(PyExc_ValueError,
9874 "strerror() argument out of range");
9875 return NULL;
9876 }
Victor Stinner1b579672011-12-17 05:47:23 +01009877 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009878}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009879
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009880
Guido van Rossumc9641791998-08-04 15:26:23 +00009881#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009882#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009883/*[clinic input]
9884os.WCOREDUMP -> bool
9885
9886 status: int
9887 /
9888
9889Return True if the process returning status was dumped to a core file.
9890[clinic start generated code]*/
9891
Larry Hastings2f936352014-08-05 14:04:04 +10009892static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009893os_WCOREDUMP_impl(PyObject *module, int status)
9894/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009895{
9896 WAIT_TYPE wait_status;
9897 WAIT_STATUS_INT(wait_status) = status;
9898 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009899}
9900#endif /* WCOREDUMP */
9901
Larry Hastings2f936352014-08-05 14:04:04 +10009902
Fred Drake106c1a02002-04-23 15:58:02 +00009903#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009904/*[clinic input]
9905os.WIFCONTINUED -> bool
9906
9907 status: int
9908
9909Return True if a particular process was continued from a job control stop.
9910
9911Return True if the process returning status was continued from a
9912job control stop.
9913[clinic start generated code]*/
9914
Larry Hastings2f936352014-08-05 14:04:04 +10009915static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009916os_WIFCONTINUED_impl(PyObject *module, int status)
9917/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009918{
9919 WAIT_TYPE wait_status;
9920 WAIT_STATUS_INT(wait_status) = status;
9921 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009922}
9923#endif /* WIFCONTINUED */
9924
Larry Hastings2f936352014-08-05 14:04:04 +10009925
Guido van Rossumc9641791998-08-04 15:26:23 +00009926#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009927/*[clinic input]
9928os.WIFSTOPPED -> bool
9929
9930 status: int
9931
9932Return True if the process returning status was stopped.
9933[clinic start generated code]*/
9934
Larry Hastings2f936352014-08-05 14:04:04 +10009935static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009936os_WIFSTOPPED_impl(PyObject *module, int status)
9937/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009938{
9939 WAIT_TYPE wait_status;
9940 WAIT_STATUS_INT(wait_status) = status;
9941 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009942}
9943#endif /* WIFSTOPPED */
9944
Larry Hastings2f936352014-08-05 14:04:04 +10009945
Guido van Rossumc9641791998-08-04 15:26:23 +00009946#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009947/*[clinic input]
9948os.WIFSIGNALED -> bool
9949
9950 status: int
9951
9952Return True if the process returning status was terminated by a signal.
9953[clinic start generated code]*/
9954
Larry Hastings2f936352014-08-05 14:04:04 +10009955static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009956os_WIFSIGNALED_impl(PyObject *module, int status)
9957/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009958{
9959 WAIT_TYPE wait_status;
9960 WAIT_STATUS_INT(wait_status) = status;
9961 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009962}
9963#endif /* WIFSIGNALED */
9964
Larry Hastings2f936352014-08-05 14:04:04 +10009965
Guido van Rossumc9641791998-08-04 15:26:23 +00009966#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009967/*[clinic input]
9968os.WIFEXITED -> bool
9969
9970 status: int
9971
9972Return True if the process returning status exited via the exit() system call.
9973[clinic start generated code]*/
9974
Larry Hastings2f936352014-08-05 14:04:04 +10009975static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009976os_WIFEXITED_impl(PyObject *module, int status)
9977/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009978{
9979 WAIT_TYPE wait_status;
9980 WAIT_STATUS_INT(wait_status) = status;
9981 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009982}
9983#endif /* WIFEXITED */
9984
Larry Hastings2f936352014-08-05 14:04:04 +10009985
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009986#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009987/*[clinic input]
9988os.WEXITSTATUS -> int
9989
9990 status: int
9991
9992Return the process return code from status.
9993[clinic start generated code]*/
9994
Larry Hastings2f936352014-08-05 14:04:04 +10009995static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009996os_WEXITSTATUS_impl(PyObject *module, int status)
9997/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009998{
9999 WAIT_TYPE wait_status;
10000 WAIT_STATUS_INT(wait_status) = status;
10001 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010002}
10003#endif /* WEXITSTATUS */
10004
Larry Hastings2f936352014-08-05 14:04:04 +100010005
Guido van Rossumc9641791998-08-04 15:26:23 +000010006#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010007/*[clinic input]
10008os.WTERMSIG -> int
10009
10010 status: int
10011
10012Return the signal that terminated the process that provided the status value.
10013[clinic start generated code]*/
10014
Larry Hastings2f936352014-08-05 14:04:04 +100010015static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010016os_WTERMSIG_impl(PyObject *module, int status)
10017/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010018{
10019 WAIT_TYPE wait_status;
10020 WAIT_STATUS_INT(wait_status) = status;
10021 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010022}
10023#endif /* WTERMSIG */
10024
Larry Hastings2f936352014-08-05 14:04:04 +100010025
Guido van Rossumc9641791998-08-04 15:26:23 +000010026#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010027/*[clinic input]
10028os.WSTOPSIG -> int
10029
10030 status: int
10031
10032Return the signal that stopped the process that provided the status value.
10033[clinic start generated code]*/
10034
Larry Hastings2f936352014-08-05 14:04:04 +100010035static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010036os_WSTOPSIG_impl(PyObject *module, int status)
10037/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010038{
10039 WAIT_TYPE wait_status;
10040 WAIT_STATUS_INT(wait_status) = status;
10041 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010042}
10043#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010044#endif /* HAVE_SYS_WAIT_H */
10045
10046
Thomas Wouters477c8d52006-05-27 19:21:47 +000010047#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010048#ifdef _SCO_DS
10049/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10050 needed definitions in sys/statvfs.h */
10051#define _SVID3
10052#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010053#include <sys/statvfs.h>
10054
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010055static PyObject*
10056_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -080010057 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 if (v == NULL)
10059 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010060
10061#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10063 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10064 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10065 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10066 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10067 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10068 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10069 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10070 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10071 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010072#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10074 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10075 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010076 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010078 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010080 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010082 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010084 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010086 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10088 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010089#endif
Michael Felt502d5512018-01-05 13:01:58 +010010090/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10091 * (issue #32390). */
10092#if defined(_AIX) && defined(_ALL_SOURCE)
10093 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10094#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010095 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010096#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010097 if (PyErr_Occurred()) {
10098 Py_DECREF(v);
10099 return NULL;
10100 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010101
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010103}
10104
Larry Hastings2f936352014-08-05 14:04:04 +100010105
10106/*[clinic input]
10107os.fstatvfs
10108 fd: int
10109 /
10110
10111Perform an fstatvfs system call on the given fd.
10112
10113Equivalent to statvfs(fd).
10114[clinic start generated code]*/
10115
Larry Hastings2f936352014-08-05 14:04:04 +100010116static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010117os_fstatvfs_impl(PyObject *module, int fd)
10118/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010119{
10120 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010121 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010123
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010124 do {
10125 Py_BEGIN_ALLOW_THREADS
10126 result = fstatvfs(fd, &st);
10127 Py_END_ALLOW_THREADS
10128 } while (result != 0 && errno == EINTR &&
10129 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010130 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010131 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010132
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010134}
Larry Hastings2f936352014-08-05 14:04:04 +100010135#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010136
10137
Thomas Wouters477c8d52006-05-27 19:21:47 +000010138#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010139#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010140/*[clinic input]
10141os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010142
Larry Hastings2f936352014-08-05 14:04:04 +100010143 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10144
10145Perform a statvfs system call on the given path.
10146
10147path may always be specified as a string.
10148On some platforms, path may also be specified as an open file descriptor.
10149 If this functionality is unavailable, using it raises an exception.
10150[clinic start generated code]*/
10151
Larry Hastings2f936352014-08-05 14:04:04 +100010152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010153os_statvfs_impl(PyObject *module, path_t *path)
10154/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010155{
10156 int result;
10157 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010158
10159 Py_BEGIN_ALLOW_THREADS
10160#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010161 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010162#ifdef __APPLE__
10163 /* handle weak-linking on Mac OS X 10.3 */
10164 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010165 fd_specified("statvfs", path->fd);
10166 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010167 }
10168#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010169 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010170 }
10171 else
10172#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010173 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010174 Py_END_ALLOW_THREADS
10175
10176 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010177 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010178 }
10179
Larry Hastings2f936352014-08-05 14:04:04 +100010180 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010181}
Larry Hastings2f936352014-08-05 14:04:04 +100010182#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10183
Guido van Rossum94f6f721999-01-06 18:42:14 +000010184
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010185#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010186/*[clinic input]
10187os._getdiskusage
10188
Steve Dower23ad6d02018-02-22 10:39:10 -080010189 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010190
10191Return disk usage statistics about the given path as a (total, free) tuple.
10192[clinic start generated code]*/
10193
Larry Hastings2f936352014-08-05 14:04:04 +100010194static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010195os__getdiskusage_impl(PyObject *module, path_t *path)
10196/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010197{
10198 BOOL retval;
10199 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010200 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010201
10202 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010203 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010204 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010205 if (retval == 0) {
10206 if (GetLastError() == ERROR_DIRECTORY) {
10207 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010208
Joe Pamerc8c02492018-09-25 10:57:36 -040010209 dir_path = PyMem_New(wchar_t, path->length + 1);
10210 if (dir_path == NULL) {
10211 return PyErr_NoMemory();
10212 }
10213
10214 wcscpy_s(dir_path, path->length + 1, path->wide);
10215
10216 if (_dirnameW(dir_path) != -1) {
10217 Py_BEGIN_ALLOW_THREADS
10218 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10219 Py_END_ALLOW_THREADS
10220 }
10221 /* Record the last error in case it's modified by PyMem_Free. */
10222 err = GetLastError();
10223 PyMem_Free(dir_path);
10224 if (retval) {
10225 goto success;
10226 }
10227 }
10228 return PyErr_SetFromWindowsErr(err);
10229 }
10230
10231success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010232 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10233}
Larry Hastings2f936352014-08-05 14:04:04 +100010234#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010235
10236
Fred Drakec9680921999-12-13 16:37:25 +000010237/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10238 * It maps strings representing configuration variable names to
10239 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010240 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010241 * rarely-used constants. There are three separate tables that use
10242 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010243 *
10244 * This code is always included, even if none of the interfaces that
10245 * need it are included. The #if hackery needed to avoid it would be
10246 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010247 */
10248struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010249 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010250 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010251};
10252
Fred Drake12c6e2d1999-12-14 21:25:03 +000010253static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010254conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010255 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010256{
Christian Heimes217cfd12007-12-02 14:31:20 +000010257 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010258 int value = _PyLong_AsInt(arg);
10259 if (value == -1 && PyErr_Occurred())
10260 return 0;
10261 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010262 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010263 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010264 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010265 /* look up the value in the table using a binary search */
10266 size_t lo = 0;
10267 size_t mid;
10268 size_t hi = tablesize;
10269 int cmp;
10270 const char *confname;
10271 if (!PyUnicode_Check(arg)) {
10272 PyErr_SetString(PyExc_TypeError,
10273 "configuration names must be strings or integers");
10274 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010276 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010277 if (confname == NULL)
10278 return 0;
10279 while (lo < hi) {
10280 mid = (lo + hi) / 2;
10281 cmp = strcmp(confname, table[mid].name);
10282 if (cmp < 0)
10283 hi = mid;
10284 else if (cmp > 0)
10285 lo = mid + 1;
10286 else {
10287 *valuep = table[mid].value;
10288 return 1;
10289 }
10290 }
10291 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10292 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010294}
10295
10296
10297#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10298static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010299#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010300 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010301#endif
10302#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010304#endif
Fred Drakec9680921999-12-13 16:37:25 +000010305#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010307#endif
10308#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010309 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010310#endif
10311#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010313#endif
10314#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010316#endif
10317#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010318 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010319#endif
10320#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010321 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010322#endif
10323#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010325#endif
10326#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010327 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010328#endif
10329#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010331#endif
10332#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010334#endif
10335#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010336 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010337#endif
10338#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010340#endif
10341#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010343#endif
10344#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010346#endif
10347#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010349#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010350#ifdef _PC_ACL_ENABLED
10351 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10352#endif
10353#ifdef _PC_MIN_HOLE_SIZE
10354 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10355#endif
10356#ifdef _PC_ALLOC_SIZE_MIN
10357 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10358#endif
10359#ifdef _PC_REC_INCR_XFER_SIZE
10360 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10361#endif
10362#ifdef _PC_REC_MAX_XFER_SIZE
10363 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10364#endif
10365#ifdef _PC_REC_MIN_XFER_SIZE
10366 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10367#endif
10368#ifdef _PC_REC_XFER_ALIGN
10369 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10370#endif
10371#ifdef _PC_SYMLINK_MAX
10372 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10373#endif
10374#ifdef _PC_XATTR_ENABLED
10375 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10376#endif
10377#ifdef _PC_XATTR_EXISTS
10378 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10379#endif
10380#ifdef _PC_TIMESTAMP_RESOLUTION
10381 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10382#endif
Fred Drakec9680921999-12-13 16:37:25 +000010383};
10384
Fred Drakec9680921999-12-13 16:37:25 +000010385static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010386conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010387{
10388 return conv_confname(arg, valuep, posix_constants_pathconf,
10389 sizeof(posix_constants_pathconf)
10390 / sizeof(struct constdef));
10391}
10392#endif
10393
Larry Hastings2f936352014-08-05 14:04:04 +100010394
Fred Drakec9680921999-12-13 16:37:25 +000010395#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010396/*[clinic input]
10397os.fpathconf -> long
10398
10399 fd: int
10400 name: path_confname
10401 /
10402
10403Return the configuration limit name for the file descriptor fd.
10404
10405If there is no limit, return -1.
10406[clinic start generated code]*/
10407
Larry Hastings2f936352014-08-05 14:04:04 +100010408static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010409os_fpathconf_impl(PyObject *module, int fd, int name)
10410/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010411{
10412 long limit;
10413
10414 errno = 0;
10415 limit = fpathconf(fd, name);
10416 if (limit == -1 && errno != 0)
10417 posix_error();
10418
10419 return limit;
10420}
10421#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010422
10423
10424#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010425/*[clinic input]
10426os.pathconf -> long
10427 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10428 name: path_confname
10429
10430Return the configuration limit name for the file or directory path.
10431
10432If there is no limit, return -1.
10433On some platforms, path may also be specified as an open file descriptor.
10434 If this functionality is unavailable, using it raises an exception.
10435[clinic start generated code]*/
10436
Larry Hastings2f936352014-08-05 14:04:04 +100010437static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010438os_pathconf_impl(PyObject *module, path_t *path, int name)
10439/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010440{
Victor Stinner8c62be82010-05-06 00:08:46 +000010441 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010442
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010444#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010445 if (path->fd != -1)
10446 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010447 else
10448#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010449 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010450 if (limit == -1 && errno != 0) {
10451 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010452 /* could be a path or name problem */
10453 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010454 else
Larry Hastings2f936352014-08-05 14:04:04 +100010455 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010456 }
Larry Hastings2f936352014-08-05 14:04:04 +100010457
10458 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010459}
Larry Hastings2f936352014-08-05 14:04:04 +100010460#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010461
10462#ifdef HAVE_CONFSTR
10463static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010464#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010466#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010467#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010468 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010469#endif
10470#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010471 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010472#endif
Fred Draked86ed291999-12-15 15:34:33 +000010473#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010474 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010475#endif
10476#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010477 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010478#endif
10479#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010480 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010481#endif
10482#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010483 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010484#endif
Fred Drakec9680921999-12-13 16:37:25 +000010485#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010487#endif
10488#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010489 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010490#endif
10491#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010492 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010493#endif
10494#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010495 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010496#endif
10497#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010498 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010499#endif
10500#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010501 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010502#endif
10503#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010504 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010505#endif
10506#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010507 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010508#endif
Fred Draked86ed291999-12-15 15:34:33 +000010509#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010510 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010511#endif
Fred Drakec9680921999-12-13 16:37:25 +000010512#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010513 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010514#endif
Fred Draked86ed291999-12-15 15:34:33 +000010515#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010516 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010517#endif
10518#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010519 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010520#endif
10521#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010523#endif
10524#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010526#endif
Fred Drakec9680921999-12-13 16:37:25 +000010527#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010529#endif
10530#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010531 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010532#endif
10533#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010534 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010535#endif
10536#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010538#endif
10539#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010540 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010541#endif
10542#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010544#endif
10545#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010546 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010547#endif
10548#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010550#endif
10551#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010552 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010553#endif
10554#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010555 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010556#endif
10557#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010558 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010559#endif
10560#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010561 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010562#endif
10563#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010564 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010565#endif
10566#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010567 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010568#endif
10569#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010570 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010571#endif
10572#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010573 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010574#endif
Fred Draked86ed291999-12-15 15:34:33 +000010575#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010576 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010577#endif
10578#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010579 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010580#endif
10581#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010582 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010583#endif
10584#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010585 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010586#endif
10587#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010589#endif
10590#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010591 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010592#endif
10593#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010594 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010595#endif
10596#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010597 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010598#endif
10599#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010600 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010601#endif
10602#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010604#endif
10605#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010606 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010607#endif
10608#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010609 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010610#endif
10611#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010612 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010613#endif
Fred Drakec9680921999-12-13 16:37:25 +000010614};
10615
10616static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010617conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010618{
10619 return conv_confname(arg, valuep, posix_constants_confstr,
10620 sizeof(posix_constants_confstr)
10621 / sizeof(struct constdef));
10622}
10623
Larry Hastings2f936352014-08-05 14:04:04 +100010624
10625/*[clinic input]
10626os.confstr
10627
10628 name: confstr_confname
10629 /
10630
10631Return a string-valued system configuration variable.
10632[clinic start generated code]*/
10633
Larry Hastings2f936352014-08-05 14:04:04 +100010634static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010635os_confstr_impl(PyObject *module, int name)
10636/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010637{
10638 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010639 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010640 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010641
Victor Stinnercb043522010-09-10 23:49:04 +000010642 errno = 0;
10643 len = confstr(name, buffer, sizeof(buffer));
10644 if (len == 0) {
10645 if (errno) {
10646 posix_error();
10647 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010648 }
10649 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010650 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010651 }
10652 }
Victor Stinnercb043522010-09-10 23:49:04 +000010653
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010654 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010655 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010656 char *buf = PyMem_Malloc(len);
10657 if (buf == NULL)
10658 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010659 len2 = confstr(name, buf, len);
10660 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010661 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010662 PyMem_Free(buf);
10663 }
10664 else
10665 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010666 return result;
10667}
Larry Hastings2f936352014-08-05 14:04:04 +100010668#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010669
10670
10671#ifdef HAVE_SYSCONF
10672static struct constdef posix_constants_sysconf[] = {
10673#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010674 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010675#endif
10676#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010677 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010678#endif
10679#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010680 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010681#endif
10682#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010683 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010684#endif
10685#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010686 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010687#endif
10688#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010689 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010690#endif
10691#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010692 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010693#endif
10694#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010695 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010696#endif
10697#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010698 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010699#endif
10700#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010701 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010702#endif
Fred Draked86ed291999-12-15 15:34:33 +000010703#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010704 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010705#endif
10706#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010707 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010708#endif
Fred Drakec9680921999-12-13 16:37:25 +000010709#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010710 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010711#endif
Fred Drakec9680921999-12-13 16:37:25 +000010712#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010713 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010714#endif
10715#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010716 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010717#endif
10718#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010719 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010720#endif
10721#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010722 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010723#endif
10724#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010725 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010726#endif
Fred Draked86ed291999-12-15 15:34:33 +000010727#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010728 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010729#endif
Fred Drakec9680921999-12-13 16:37:25 +000010730#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010731 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010732#endif
10733#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010734 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010735#endif
10736#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010737 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010738#endif
10739#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010740 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010741#endif
10742#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010743 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010744#endif
Fred Draked86ed291999-12-15 15:34:33 +000010745#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010746 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010747#endif
Fred Drakec9680921999-12-13 16:37:25 +000010748#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010749 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010750#endif
10751#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010752 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010753#endif
10754#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010755 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010756#endif
10757#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010758 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010759#endif
10760#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010761 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010762#endif
10763#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010764 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010765#endif
10766#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010767 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010768#endif
10769#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010770 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010771#endif
10772#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010773 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010774#endif
10775#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010776 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010777#endif
10778#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010779 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010780#endif
10781#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010782 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010783#endif
10784#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010785 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010786#endif
10787#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010788 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010789#endif
10790#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010791 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010792#endif
10793#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010794 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010795#endif
10796#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010797 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010798#endif
10799#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010800 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010801#endif
10802#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010803 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010804#endif
10805#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010806 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010807#endif
10808#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010809 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010810#endif
10811#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010812 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010813#endif
10814#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010815 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010816#endif
Fred Draked86ed291999-12-15 15:34:33 +000010817#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010818 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010819#endif
Fred Drakec9680921999-12-13 16:37:25 +000010820#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010821 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010822#endif
10823#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010824 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010825#endif
10826#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010827 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010828#endif
Fred Draked86ed291999-12-15 15:34:33 +000010829#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010830 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010831#endif
Fred Drakec9680921999-12-13 16:37:25 +000010832#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010833 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010834#endif
Fred Draked86ed291999-12-15 15:34:33 +000010835#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010836 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010837#endif
10838#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010839 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010840#endif
Fred Drakec9680921999-12-13 16:37:25 +000010841#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010842 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010843#endif
10844#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010845 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010846#endif
10847#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010848 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010849#endif
10850#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010851 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010852#endif
Fred Draked86ed291999-12-15 15:34:33 +000010853#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010855#endif
Fred Drakec9680921999-12-13 16:37:25 +000010856#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010857 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010858#endif
10859#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010860 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010861#endif
10862#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010863 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010864#endif
10865#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010866 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010867#endif
10868#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010869 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010870#endif
10871#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010873#endif
10874#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010875 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010876#endif
Fred Draked86ed291999-12-15 15:34:33 +000010877#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010878 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010879#endif
Fred Drakec9680921999-12-13 16:37:25 +000010880#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010881 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010882#endif
10883#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010884 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010885#endif
Fred Draked86ed291999-12-15 15:34:33 +000010886#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010887 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010888#endif
Fred Drakec9680921999-12-13 16:37:25 +000010889#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010890 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010891#endif
10892#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010893 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010894#endif
10895#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010896 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010897#endif
10898#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010899 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010900#endif
10901#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010902 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010903#endif
10904#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010906#endif
10907#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010908 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010909#endif
10910#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010911 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010912#endif
10913#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010914 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010915#endif
Fred Draked86ed291999-12-15 15:34:33 +000010916#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010917 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010918#endif
10919#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010920 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010921#endif
Fred Drakec9680921999-12-13 16:37:25 +000010922#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010923 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010924#endif
10925#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010926 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010927#endif
10928#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010929 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010930#endif
10931#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010932 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010933#endif
10934#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010936#endif
10937#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010939#endif
10940#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010942#endif
10943#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010945#endif
10946#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010947 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010948#endif
10949#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010950 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010951#endif
10952#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010953 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010954#endif
10955#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010957#endif
10958#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010960#endif
10961#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010962 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010963#endif
10964#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010965 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010966#endif
10967#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010968 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010969#endif
10970#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010972#endif
10973#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010975#endif
10976#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010977 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010978#endif
10979#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010981#endif
10982#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010984#endif
10985#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010986 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010987#endif
10988#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010989 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010990#endif
10991#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010992 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010993#endif
10994#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010996#endif
10997#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010998 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010999#endif
11000#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011001 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011002#endif
11003#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011005#endif
11006#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011007 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011008#endif
11009#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011011#endif
11012#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011013 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011014#endif
11015#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011016 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011017#endif
11018#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011019 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011020#endif
11021#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011023#endif
11024#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011025 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011026#endif
Fred Draked86ed291999-12-15 15:34:33 +000011027#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011028 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011029#endif
Fred Drakec9680921999-12-13 16:37:25 +000011030#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011031 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011032#endif
11033#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011034 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011035#endif
11036#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011037 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011038#endif
11039#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011040 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011041#endif
11042#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011043 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011044#endif
11045#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011046 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011047#endif
11048#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011049 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011050#endif
11051#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011052 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011053#endif
11054#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011055 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011056#endif
11057#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011058 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011059#endif
11060#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011061 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011062#endif
11063#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011065#endif
11066#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011068#endif
11069#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011070 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011071#endif
11072#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011073 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011074#endif
11075#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011076 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011077#endif
11078#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011079 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011080#endif
11081#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011082 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011083#endif
11084#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011086#endif
11087#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011088 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011089#endif
11090#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011091 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011092#endif
11093#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011094 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011095#endif
11096#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011097 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011098#endif
11099#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011100 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011101#endif
11102#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011103 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011104#endif
11105#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011106 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011107#endif
11108#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011110#endif
11111#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011112 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011113#endif
11114#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011115 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011116#endif
11117#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011118 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011119#endif
11120#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011121 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011122#endif
11123#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011124 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011125#endif
11126#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011127 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011128#endif
11129#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011130 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011131#endif
11132#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011133 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011134#endif
11135#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011136 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011137#endif
11138#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011139 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011140#endif
11141#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011142 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011143#endif
11144#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011145 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011146#endif
11147#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011149#endif
11150#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011151 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011152#endif
11153#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011155#endif
11156#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011158#endif
11159#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011161#endif
11162#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011164#endif
11165};
11166
11167static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011168conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011169{
11170 return conv_confname(arg, valuep, posix_constants_sysconf,
11171 sizeof(posix_constants_sysconf)
11172 / sizeof(struct constdef));
11173}
11174
Larry Hastings2f936352014-08-05 14:04:04 +100011175
11176/*[clinic input]
11177os.sysconf -> long
11178 name: sysconf_confname
11179 /
11180
11181Return an integer-valued system configuration variable.
11182[clinic start generated code]*/
11183
Larry Hastings2f936352014-08-05 14:04:04 +100011184static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011185os_sysconf_impl(PyObject *module, int name)
11186/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011187{
11188 long value;
11189
11190 errno = 0;
11191 value = sysconf(name);
11192 if (value == -1 && errno != 0)
11193 posix_error();
11194 return value;
11195}
11196#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011197
11198
Fred Drakebec628d1999-12-15 18:31:10 +000011199/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011200 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011201 * the exported dictionaries that are used to publish information about the
11202 * names available on the host platform.
11203 *
11204 * Sorting the table at runtime ensures that the table is properly ordered
11205 * when used, even for platforms we're not able to test on. It also makes
11206 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011207 */
Fred Drakebec628d1999-12-15 18:31:10 +000011208
11209static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011210cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011211{
11212 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011213 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011214 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011215 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011216
11217 return strcmp(c1->name, c2->name);
11218}
11219
11220static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011221setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011222 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011223{
Fred Drakebec628d1999-12-15 18:31:10 +000011224 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011225 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011226
11227 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11228 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011229 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011231
Barry Warsaw3155db32000-04-13 15:20:40 +000011232 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 PyObject *o = PyLong_FromLong(table[i].value);
11234 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11235 Py_XDECREF(o);
11236 Py_DECREF(d);
11237 return -1;
11238 }
11239 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011240 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011241 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011242}
11243
Fred Drakebec628d1999-12-15 18:31:10 +000011244/* Return -1 on failure, 0 on success. */
11245static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011246setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011247{
11248#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011249 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011250 sizeof(posix_constants_pathconf)
11251 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011252 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011253 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011254#endif
11255#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011256 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011257 sizeof(posix_constants_confstr)
11258 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011259 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011260 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011261#endif
11262#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011263 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011264 sizeof(posix_constants_sysconf)
11265 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011266 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011267 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011268#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011269 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011270}
Fred Draked86ed291999-12-15 15:34:33 +000011271
11272
Larry Hastings2f936352014-08-05 14:04:04 +100011273/*[clinic input]
11274os.abort
11275
11276Abort the interpreter immediately.
11277
11278This function 'dumps core' or otherwise fails in the hardest way possible
11279on the hosting operating system. This function never returns.
11280[clinic start generated code]*/
11281
Larry Hastings2f936352014-08-05 14:04:04 +100011282static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011283os_abort_impl(PyObject *module)
11284/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011285{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011286 abort();
11287 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011288#ifndef __clang__
11289 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11290 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11291 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011292 Py_FatalError("abort() called from Python code didn't abort!");
11293 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011294#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011295}
Fred Drakebec628d1999-12-15 18:31:10 +000011296
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011297#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011298/* Grab ShellExecute dynamically from shell32 */
11299static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011300static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11301 LPCWSTR, INT);
11302static int
11303check_ShellExecute()
11304{
11305 HINSTANCE hShell32;
11306
11307 /* only recheck */
11308 if (-1 == has_ShellExecute) {
11309 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011310 /* Security note: this call is not vulnerable to "DLL hijacking".
11311 SHELL32 is part of "KnownDLLs" and so Windows always load
11312 the system SHELL32.DLL, even if there is another SHELL32.DLL
11313 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011314 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011315 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011316 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11317 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011318 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011319 } else {
11320 has_ShellExecute = 0;
11321 }
Tony Roberts4860f012019-02-02 18:16:42 +010011322 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011323 }
11324 return has_ShellExecute;
11325}
11326
11327
Steve Dowercc16be82016-09-08 10:35:16 -070011328/*[clinic input]
11329os.startfile
11330 filepath: path_t
11331 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011332
Steve Dowercc16be82016-09-08 10:35:16 -070011333startfile(filepath [, operation])
11334
11335Start a file with its associated application.
11336
11337When "operation" is not specified or "open", this acts like
11338double-clicking the file in Explorer, or giving the file name as an
11339argument to the DOS "start" command: the file is opened with whatever
11340application (if any) its extension is associated.
11341When another "operation" is given, it specifies what should be done with
11342the file. A typical operation is "print".
11343
11344startfile returns as soon as the associated application is launched.
11345There is no option to wait for the application to close, and no way
11346to retrieve the application's exit status.
11347
11348The filepath is relative to the current directory. If you want to use
11349an absolute path, make sure the first character is not a slash ("/");
11350the underlying Win32 ShellExecute function doesn't work if it is.
11351[clinic start generated code]*/
11352
11353static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011354os_startfile_impl(PyObject *module, path_t *filepath,
11355 const Py_UNICODE *operation)
11356/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011357{
11358 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011359
11360 if(!check_ShellExecute()) {
11361 /* If the OS doesn't have ShellExecute, return a
11362 NotImplementedError. */
11363 return PyErr_Format(PyExc_NotImplementedError,
11364 "startfile not available on this platform");
11365 }
11366
Victor Stinner8c62be82010-05-06 00:08:46 +000011367 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011368 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011369 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011370 Py_END_ALLOW_THREADS
11371
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011373 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011374 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 }
Steve Dowercc16be82016-09-08 10:35:16 -070011376 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011377}
Larry Hastings2f936352014-08-05 14:04:04 +100011378#endif /* MS_WINDOWS */
11379
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011380
Martin v. Löwis438b5342002-12-27 10:16:42 +000011381#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011382/*[clinic input]
11383os.getloadavg
11384
11385Return average recent system load information.
11386
11387Return the number of processes in the system run queue averaged over
11388the last 1, 5, and 15 minutes as a tuple of three floats.
11389Raises OSError if the load average was unobtainable.
11390[clinic start generated code]*/
11391
Larry Hastings2f936352014-08-05 14:04:04 +100011392static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011393os_getloadavg_impl(PyObject *module)
11394/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011395{
11396 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011397 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011398 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11399 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011400 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011401 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011402}
Larry Hastings2f936352014-08-05 14:04:04 +100011403#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011404
Larry Hastings2f936352014-08-05 14:04:04 +100011405
11406/*[clinic input]
11407os.device_encoding
11408 fd: int
11409
11410Return a string describing the encoding of a terminal's file descriptor.
11411
11412The file descriptor must be attached to a terminal.
11413If the device is not a terminal, return None.
11414[clinic start generated code]*/
11415
Larry Hastings2f936352014-08-05 14:04:04 +100011416static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011417os_device_encoding_impl(PyObject *module, int fd)
11418/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011419{
Brett Cannonefb00c02012-02-29 18:31:31 -050011420 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011421}
11422
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011423
Larry Hastings2f936352014-08-05 14:04:04 +100011424#ifdef HAVE_SETRESUID
11425/*[clinic input]
11426os.setresuid
11427
11428 ruid: uid_t
11429 euid: uid_t
11430 suid: uid_t
11431 /
11432
11433Set the current process's real, effective, and saved user ids.
11434[clinic start generated code]*/
11435
Larry Hastings2f936352014-08-05 14:04:04 +100011436static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011437os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11438/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011439{
Victor Stinner8c62be82010-05-06 00:08:46 +000011440 if (setresuid(ruid, euid, suid) < 0)
11441 return posix_error();
11442 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011443}
Larry Hastings2f936352014-08-05 14:04:04 +100011444#endif /* HAVE_SETRESUID */
11445
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011446
11447#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011448/*[clinic input]
11449os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011450
Larry Hastings2f936352014-08-05 14:04:04 +100011451 rgid: gid_t
11452 egid: gid_t
11453 sgid: gid_t
11454 /
11455
11456Set the current process's real, effective, and saved group ids.
11457[clinic start generated code]*/
11458
Larry Hastings2f936352014-08-05 14:04:04 +100011459static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011460os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11461/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011462{
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 if (setresgid(rgid, egid, sgid) < 0)
11464 return posix_error();
11465 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011466}
Larry Hastings2f936352014-08-05 14:04:04 +100011467#endif /* HAVE_SETRESGID */
11468
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011469
11470#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011471/*[clinic input]
11472os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011473
Larry Hastings2f936352014-08-05 14:04:04 +100011474Return a tuple of the current process's real, effective, and saved user ids.
11475[clinic start generated code]*/
11476
Larry Hastings2f936352014-08-05 14:04:04 +100011477static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011478os_getresuid_impl(PyObject *module)
11479/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011480{
Victor Stinner8c62be82010-05-06 00:08:46 +000011481 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011482 if (getresuid(&ruid, &euid, &suid) < 0)
11483 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011484 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11485 _PyLong_FromUid(euid),
11486 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011487}
Larry Hastings2f936352014-08-05 14:04:04 +100011488#endif /* HAVE_GETRESUID */
11489
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011490
11491#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011492/*[clinic input]
11493os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011494
Larry Hastings2f936352014-08-05 14:04:04 +100011495Return a tuple of the current process's real, effective, and saved group ids.
11496[clinic start generated code]*/
11497
Larry Hastings2f936352014-08-05 14:04:04 +100011498static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011499os_getresgid_impl(PyObject *module)
11500/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011501{
11502 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011503 if (getresgid(&rgid, &egid, &sgid) < 0)
11504 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011505 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11506 _PyLong_FromGid(egid),
11507 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011508}
Larry Hastings2f936352014-08-05 14:04:04 +100011509#endif /* HAVE_GETRESGID */
11510
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011511
Benjamin Peterson9428d532011-09-14 11:45:52 -040011512#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011513/*[clinic input]
11514os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011515
Larry Hastings2f936352014-08-05 14:04:04 +100011516 path: path_t(allow_fd=True)
11517 attribute: path_t
11518 *
11519 follow_symlinks: bool = True
11520
11521Return the value of extended attribute attribute on path.
11522
BNMetricsb9427072018-11-02 15:20:19 +000011523path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011524If follow_symlinks is False, and the last element of the path is a symbolic
11525 link, getxattr will examine the symbolic link itself instead of the file
11526 the link points to.
11527
11528[clinic start generated code]*/
11529
Larry Hastings2f936352014-08-05 14:04:04 +100011530static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011531os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011532 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011533/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011534{
11535 Py_ssize_t i;
11536 PyObject *buffer = NULL;
11537
11538 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11539 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011540
Larry Hastings9cf065c2012-06-22 16:30:09 -070011541 for (i = 0; ; i++) {
11542 void *ptr;
11543 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011544 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011545 Py_ssize_t buffer_size = buffer_sizes[i];
11546 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011547 path_error(path);
11548 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011549 }
11550 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11551 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011552 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011553 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011554
Larry Hastings9cf065c2012-06-22 16:30:09 -070011555 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011556 if (path->fd >= 0)
11557 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011558 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011559 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011560 else
Larry Hastings2f936352014-08-05 14:04:04 +100011561 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011562 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011563
Larry Hastings9cf065c2012-06-22 16:30:09 -070011564 if (result < 0) {
11565 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011566 if (errno == ERANGE)
11567 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011568 path_error(path);
11569 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011570 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011571
Larry Hastings9cf065c2012-06-22 16:30:09 -070011572 if (result != buffer_size) {
11573 /* Can only shrink. */
11574 _PyBytes_Resize(&buffer, result);
11575 }
11576 break;
11577 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011578
Larry Hastings9cf065c2012-06-22 16:30:09 -070011579 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011580}
11581
Larry Hastings2f936352014-08-05 14:04:04 +100011582
11583/*[clinic input]
11584os.setxattr
11585
11586 path: path_t(allow_fd=True)
11587 attribute: path_t
11588 value: Py_buffer
11589 flags: int = 0
11590 *
11591 follow_symlinks: bool = True
11592
11593Set extended attribute attribute on path to value.
11594
BNMetricsb9427072018-11-02 15:20:19 +000011595path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011596If follow_symlinks is False, and the last element of the path is a symbolic
11597 link, setxattr will modify the symbolic link itself instead of the file
11598 the link points to.
11599
11600[clinic start generated code]*/
11601
Benjamin Peterson799bd802011-08-31 22:15:17 -040011602static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011603os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011604 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011605/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011606{
Larry Hastings2f936352014-08-05 14:04:04 +100011607 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011608
Larry Hastings2f936352014-08-05 14:04:04 +100011609 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011610 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011611
Benjamin Peterson799bd802011-08-31 22:15:17 -040011612 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011613 if (path->fd > -1)
11614 result = fsetxattr(path->fd, attribute->narrow,
11615 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011616 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011617 result = setxattr(path->narrow, attribute->narrow,
11618 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011619 else
Larry Hastings2f936352014-08-05 14:04:04 +100011620 result = lsetxattr(path->narrow, attribute->narrow,
11621 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011622 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011623
Larry Hastings9cf065c2012-06-22 16:30:09 -070011624 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011625 path_error(path);
11626 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011627 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011628
Larry Hastings2f936352014-08-05 14:04:04 +100011629 Py_RETURN_NONE;
11630}
11631
11632
11633/*[clinic input]
11634os.removexattr
11635
11636 path: path_t(allow_fd=True)
11637 attribute: path_t
11638 *
11639 follow_symlinks: bool = True
11640
11641Remove extended attribute attribute on path.
11642
BNMetricsb9427072018-11-02 15:20:19 +000011643path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011644If follow_symlinks is False, and the last element of the path is a symbolic
11645 link, removexattr will modify the symbolic link itself instead of the file
11646 the link points to.
11647
11648[clinic start generated code]*/
11649
Larry Hastings2f936352014-08-05 14:04:04 +100011650static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011651os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011652 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011653/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011654{
11655 ssize_t result;
11656
11657 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11658 return NULL;
11659
11660 Py_BEGIN_ALLOW_THREADS;
11661 if (path->fd > -1)
11662 result = fremovexattr(path->fd, attribute->narrow);
11663 else if (follow_symlinks)
11664 result = removexattr(path->narrow, attribute->narrow);
11665 else
11666 result = lremovexattr(path->narrow, attribute->narrow);
11667 Py_END_ALLOW_THREADS;
11668
11669 if (result) {
11670 return path_error(path);
11671 }
11672
11673 Py_RETURN_NONE;
11674}
11675
11676
11677/*[clinic input]
11678os.listxattr
11679
11680 path: path_t(allow_fd=True, nullable=True) = None
11681 *
11682 follow_symlinks: bool = True
11683
11684Return a list of extended attributes on path.
11685
BNMetricsb9427072018-11-02 15:20:19 +000011686path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011687if path is None, listxattr will examine the current directory.
11688If follow_symlinks is False, and the last element of the path is a symbolic
11689 link, listxattr will examine the symbolic link itself instead of the file
11690 the link points to.
11691[clinic start generated code]*/
11692
Larry Hastings2f936352014-08-05 14:04:04 +100011693static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011694os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011695/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011696{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011697 Py_ssize_t i;
11698 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011699 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011700 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011701
Larry Hastings2f936352014-08-05 14:04:04 +100011702 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011703 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011704
Larry Hastings2f936352014-08-05 14:04:04 +100011705 name = path->narrow ? path->narrow : ".";
11706
Larry Hastings9cf065c2012-06-22 16:30:09 -070011707 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011708 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011709 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011710 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011711 Py_ssize_t buffer_size = buffer_sizes[i];
11712 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011713 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011714 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011715 break;
11716 }
11717 buffer = PyMem_MALLOC(buffer_size);
11718 if (!buffer) {
11719 PyErr_NoMemory();
11720 break;
11721 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011722
Larry Hastings9cf065c2012-06-22 16:30:09 -070011723 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011724 if (path->fd > -1)
11725 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011726 else if (follow_symlinks)
11727 length = listxattr(name, buffer, buffer_size);
11728 else
11729 length = llistxattr(name, buffer, buffer_size);
11730 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011731
Larry Hastings9cf065c2012-06-22 16:30:09 -070011732 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011733 if (errno == ERANGE) {
11734 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011735 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011736 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011737 }
Larry Hastings2f936352014-08-05 14:04:04 +100011738 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011739 break;
11740 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011741
Larry Hastings9cf065c2012-06-22 16:30:09 -070011742 result = PyList_New(0);
11743 if (!result) {
11744 goto exit;
11745 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011746
Larry Hastings9cf065c2012-06-22 16:30:09 -070011747 end = buffer + length;
11748 for (trace = start = buffer; trace != end; trace++) {
11749 if (!*trace) {
11750 int error;
11751 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11752 trace - start);
11753 if (!attribute) {
11754 Py_DECREF(result);
11755 result = NULL;
11756 goto exit;
11757 }
11758 error = PyList_Append(result, attribute);
11759 Py_DECREF(attribute);
11760 if (error) {
11761 Py_DECREF(result);
11762 result = NULL;
11763 goto exit;
11764 }
11765 start = trace + 1;
11766 }
11767 }
11768 break;
11769 }
11770exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011771 if (buffer)
11772 PyMem_FREE(buffer);
11773 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011774}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011775#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011776
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011777
Larry Hastings2f936352014-08-05 14:04:04 +100011778/*[clinic input]
11779os.urandom
11780
11781 size: Py_ssize_t
11782 /
11783
11784Return a bytes object containing random bytes suitable for cryptographic use.
11785[clinic start generated code]*/
11786
Larry Hastings2f936352014-08-05 14:04:04 +100011787static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011788os_urandom_impl(PyObject *module, Py_ssize_t size)
11789/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011790{
11791 PyObject *bytes;
11792 int result;
11793
Georg Brandl2fb477c2012-02-21 00:33:36 +010011794 if (size < 0)
11795 return PyErr_Format(PyExc_ValueError,
11796 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011797 bytes = PyBytes_FromStringAndSize(NULL, size);
11798 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011799 return NULL;
11800
Victor Stinnere66987e2016-09-06 16:33:52 -070011801 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011802 if (result == -1) {
11803 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011804 return NULL;
11805 }
Larry Hastings2f936352014-08-05 14:04:04 +100011806 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011807}
11808
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011809/* Terminal size querying */
11810
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011811static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011812
11813PyDoc_STRVAR(TerminalSize_docstring,
11814 "A tuple of (columns, lines) for holding terminal window size");
11815
11816static PyStructSequence_Field TerminalSize_fields[] = {
11817 {"columns", "width of the terminal window in characters"},
11818 {"lines", "height of the terminal window in characters"},
11819 {NULL, NULL}
11820};
11821
11822static PyStructSequence_Desc TerminalSize_desc = {
11823 "os.terminal_size",
11824 TerminalSize_docstring,
11825 TerminalSize_fields,
11826 2,
11827};
11828
11829#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011830/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011831PyDoc_STRVAR(termsize__doc__,
11832 "Return the size of the terminal window as (columns, lines).\n" \
11833 "\n" \
11834 "The optional argument fd (default standard output) specifies\n" \
11835 "which file descriptor should be queried.\n" \
11836 "\n" \
11837 "If the file descriptor is not connected to a terminal, an OSError\n" \
11838 "is thrown.\n" \
11839 "\n" \
11840 "This function will only be defined if an implementation is\n" \
11841 "available for this system.\n" \
11842 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080011843 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011844 "normally be used, os.get_terminal_size is the low-level implementation.");
11845
11846static PyObject*
11847get_terminal_size(PyObject *self, PyObject *args)
11848{
11849 int columns, lines;
11850 PyObject *termsize;
11851
11852 int fd = fileno(stdout);
11853 /* Under some conditions stdout may not be connected and
11854 * fileno(stdout) may point to an invalid file descriptor. For example
11855 * GUI apps don't have valid standard streams by default.
11856 *
11857 * If this happens, and the optional fd argument is not present,
11858 * the ioctl below will fail returning EBADF. This is what we want.
11859 */
11860
11861 if (!PyArg_ParseTuple(args, "|i", &fd))
11862 return NULL;
11863
11864#ifdef TERMSIZE_USE_IOCTL
11865 {
11866 struct winsize w;
11867 if (ioctl(fd, TIOCGWINSZ, &w))
11868 return PyErr_SetFromErrno(PyExc_OSError);
11869 columns = w.ws_col;
11870 lines = w.ws_row;
11871 }
11872#endif /* TERMSIZE_USE_IOCTL */
11873
11874#ifdef TERMSIZE_USE_CONIO
11875 {
11876 DWORD nhandle;
11877 HANDLE handle;
11878 CONSOLE_SCREEN_BUFFER_INFO csbi;
11879 switch (fd) {
11880 case 0: nhandle = STD_INPUT_HANDLE;
11881 break;
11882 case 1: nhandle = STD_OUTPUT_HANDLE;
11883 break;
11884 case 2: nhandle = STD_ERROR_HANDLE;
11885 break;
11886 default:
11887 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11888 }
11889 handle = GetStdHandle(nhandle);
11890 if (handle == NULL)
11891 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11892 if (handle == INVALID_HANDLE_VALUE)
11893 return PyErr_SetFromWindowsErr(0);
11894
11895 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11896 return PyErr_SetFromWindowsErr(0);
11897
11898 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11899 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11900 }
11901#endif /* TERMSIZE_USE_CONIO */
11902
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011903 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011904 if (termsize == NULL)
11905 return NULL;
11906 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11907 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11908 if (PyErr_Occurred()) {
11909 Py_DECREF(termsize);
11910 return NULL;
11911 }
11912 return termsize;
11913}
11914#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11915
Larry Hastings2f936352014-08-05 14:04:04 +100011916
11917/*[clinic input]
11918os.cpu_count
11919
Charles-François Natali80d62e62015-08-13 20:37:08 +010011920Return the number of CPUs in the system; return None if indeterminable.
11921
11922This number is not equivalent to the number of CPUs the current process can
11923use. The number of usable CPUs can be obtained with
11924``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011925[clinic start generated code]*/
11926
Larry Hastings2f936352014-08-05 14:04:04 +100011927static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011928os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011929/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011930{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011931 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011932#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011933 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11934 Need to fallback to Vista behavior if this call isn't present */
11935 HINSTANCE hKernel32;
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011936 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
Tony Roberts4860f012019-02-02 18:16:42 +010011937 Py_BEGIN_ALLOW_THREADS
11938 hKernel32 = GetModuleHandleW(L"KERNEL32");
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011939 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11940 "GetMaximumProcessorCount");
Tony Roberts4860f012019-02-02 18:16:42 +010011941 Py_END_ALLOW_THREADS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011942 if (_GetMaximumProcessorCount != NULL) {
11943 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11944 }
11945 else {
11946 SYSTEM_INFO sysinfo;
11947 GetSystemInfo(&sysinfo);
11948 ncpu = sysinfo.dwNumberOfProcessors;
11949 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011950#elif defined(__hpux)
11951 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11952#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11953 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011954#elif defined(__DragonFly__) || \
11955 defined(__OpenBSD__) || \
11956 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011957 defined(__NetBSD__) || \
11958 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011959 int mib[2];
11960 size_t len = sizeof(ncpu);
11961 mib[0] = CTL_HW;
11962 mib[1] = HW_NCPU;
11963 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11964 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011965#endif
11966 if (ncpu >= 1)
11967 return PyLong_FromLong(ncpu);
11968 else
11969 Py_RETURN_NONE;
11970}
11971
Victor Stinnerdaf45552013-08-28 00:53:59 +020011972
Larry Hastings2f936352014-08-05 14:04:04 +100011973/*[clinic input]
11974os.get_inheritable -> bool
11975
11976 fd: int
11977 /
11978
11979Get the close-on-exe flag of the specified file descriptor.
11980[clinic start generated code]*/
11981
Larry Hastings2f936352014-08-05 14:04:04 +100011982static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011983os_get_inheritable_impl(PyObject *module, int fd)
11984/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011985{
Steve Dower8fc89802015-04-12 00:26:27 -040011986 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011987 _Py_BEGIN_SUPPRESS_IPH
11988 return_value = _Py_get_inheritable(fd);
11989 _Py_END_SUPPRESS_IPH
11990 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011991}
11992
11993
11994/*[clinic input]
11995os.set_inheritable
11996 fd: int
11997 inheritable: int
11998 /
11999
12000Set the inheritable flag of the specified file descriptor.
12001[clinic start generated code]*/
12002
Larry Hastings2f936352014-08-05 14:04:04 +100012003static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012004os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12005/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012006{
Steve Dower8fc89802015-04-12 00:26:27 -040012007 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012008
Steve Dower8fc89802015-04-12 00:26:27 -040012009 _Py_BEGIN_SUPPRESS_IPH
12010 result = _Py_set_inheritable(fd, inheritable, NULL);
12011 _Py_END_SUPPRESS_IPH
12012 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012013 return NULL;
12014 Py_RETURN_NONE;
12015}
12016
12017
12018#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012019/*[clinic input]
12020os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012021 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012022 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012023
Larry Hastings2f936352014-08-05 14:04:04 +100012024Get the close-on-exe flag of the specified file descriptor.
12025[clinic start generated code]*/
12026
Larry Hastings2f936352014-08-05 14:04:04 +100012027static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012028os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012029/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012030{
12031 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012032
12033 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12034 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012035 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012036 }
12037
Larry Hastings2f936352014-08-05 14:04:04 +100012038 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012039}
12040
Victor Stinnerdaf45552013-08-28 00:53:59 +020012041
Larry Hastings2f936352014-08-05 14:04:04 +100012042/*[clinic input]
12043os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012044 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012045 inheritable: bool
12046 /
12047
12048Set the inheritable flag of the specified handle.
12049[clinic start generated code]*/
12050
Larry Hastings2f936352014-08-05 14:04:04 +100012051static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012052os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012053 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012054/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012055{
12056 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012057 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12058 PyErr_SetFromWindowsErr(0);
12059 return NULL;
12060 }
12061 Py_RETURN_NONE;
12062}
Larry Hastings2f936352014-08-05 14:04:04 +100012063#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012064
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012065#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012066/*[clinic input]
12067os.get_blocking -> bool
12068 fd: int
12069 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012070
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012071Get the blocking mode of the file descriptor.
12072
12073Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12074[clinic start generated code]*/
12075
12076static int
12077os_get_blocking_impl(PyObject *module, int fd)
12078/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012079{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012080 int blocking;
12081
Steve Dower8fc89802015-04-12 00:26:27 -040012082 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012083 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012084 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012085 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012086}
12087
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012088/*[clinic input]
12089os.set_blocking
12090 fd: int
12091 blocking: bool(accept={int})
12092 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012093
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012094Set the blocking mode of the specified file descriptor.
12095
12096Set the O_NONBLOCK flag if blocking is False,
12097clear the O_NONBLOCK flag otherwise.
12098[clinic start generated code]*/
12099
12100static PyObject *
12101os_set_blocking_impl(PyObject *module, int fd, int blocking)
12102/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012103{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012104 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012105
Steve Dower8fc89802015-04-12 00:26:27 -040012106 _Py_BEGIN_SUPPRESS_IPH
12107 result = _Py_set_blocking(fd, blocking);
12108 _Py_END_SUPPRESS_IPH
12109 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012110 return NULL;
12111 Py_RETURN_NONE;
12112}
12113#endif /* !MS_WINDOWS */
12114
12115
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012116/*[clinic input]
12117class os.DirEntry "DirEntry *" "&DirEntryType"
12118[clinic start generated code]*/
12119/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012120
12121typedef struct {
12122 PyObject_HEAD
12123 PyObject *name;
12124 PyObject *path;
12125 PyObject *stat;
12126 PyObject *lstat;
12127#ifdef MS_WINDOWS
12128 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012129 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012130 int got_file_index;
12131#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012132#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012133 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012134#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012135 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012136 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012137#endif
12138} DirEntry;
12139
12140static void
12141DirEntry_dealloc(DirEntry *entry)
12142{
12143 Py_XDECREF(entry->name);
12144 Py_XDECREF(entry->path);
12145 Py_XDECREF(entry->stat);
12146 Py_XDECREF(entry->lstat);
12147 Py_TYPE(entry)->tp_free((PyObject *)entry);
12148}
12149
12150/* Forward reference */
12151static int
12152DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12153
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012154/*[clinic input]
12155os.DirEntry.is_symlink -> bool
12156
12157Return True if the entry is a symbolic link; cached per entry.
12158[clinic start generated code]*/
12159
Victor Stinner6036e442015-03-08 01:58:04 +010012160static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012161os_DirEntry_is_symlink_impl(DirEntry *self)
12162/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012163{
12164#ifdef MS_WINDOWS
12165 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012166#elif defined(HAVE_DIRENT_D_TYPE)
12167 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012168 if (self->d_type != DT_UNKNOWN)
12169 return self->d_type == DT_LNK;
12170 else
12171 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012172#else
12173 /* POSIX without d_type */
12174 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012175#endif
12176}
12177
12178static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012179DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12180{
12181 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012182 STRUCT_STAT st;
12183 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012184
12185#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012186 if (!PyUnicode_FSDecoder(self->path, &ub))
12187 return NULL;
12188 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012189#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012190 if (!PyUnicode_FSConverter(self->path, &ub))
12191 return NULL;
12192 const char *path = PyBytes_AS_STRING(ub);
12193 if (self->dir_fd != DEFAULT_DIR_FD) {
12194#ifdef HAVE_FSTATAT
12195 result = fstatat(self->dir_fd, path, &st,
12196 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12197#else
12198 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12199 return NULL;
12200#endif /* HAVE_FSTATAT */
12201 }
12202 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012203#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012204 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012205 if (follow_symlinks)
12206 result = STAT(path, &st);
12207 else
12208 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012209 }
12210 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012211
12212 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012213 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012214
12215 return _pystat_fromstructstat(&st);
12216}
12217
12218static PyObject *
12219DirEntry_get_lstat(DirEntry *self)
12220{
12221 if (!self->lstat) {
12222#ifdef MS_WINDOWS
12223 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12224#else /* POSIX */
12225 self->lstat = DirEntry_fetch_stat(self, 0);
12226#endif
12227 }
12228 Py_XINCREF(self->lstat);
12229 return self->lstat;
12230}
12231
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012232/*[clinic input]
12233os.DirEntry.stat
12234 *
12235 follow_symlinks: bool = True
12236
12237Return stat_result object for the entry; cached per entry.
12238[clinic start generated code]*/
12239
Victor Stinner6036e442015-03-08 01:58:04 +010012240static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012241os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12242/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012243{
12244 if (!follow_symlinks)
12245 return DirEntry_get_lstat(self);
12246
12247 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012248 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012249 if (result == -1)
12250 return NULL;
12251 else if (result)
12252 self->stat = DirEntry_fetch_stat(self, 1);
12253 else
12254 self->stat = DirEntry_get_lstat(self);
12255 }
12256
12257 Py_XINCREF(self->stat);
12258 return self->stat;
12259}
12260
Victor Stinner6036e442015-03-08 01:58:04 +010012261/* Set exception and return -1 on error, 0 for False, 1 for True */
12262static int
12263DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12264{
12265 PyObject *stat = NULL;
12266 PyObject *st_mode = NULL;
12267 long mode;
12268 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012269#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012270 int is_symlink;
12271 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012272#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012273#ifdef MS_WINDOWS
12274 unsigned long dir_bits;
12275#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012276 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012277
12278#ifdef MS_WINDOWS
12279 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12280 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012281#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012282 is_symlink = self->d_type == DT_LNK;
12283 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12284#endif
12285
Victor Stinner35a97c02015-03-08 02:59:09 +010012286#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012287 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012288#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012289 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012290 if (!stat) {
12291 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12292 /* If file doesn't exist (anymore), then return False
12293 (i.e., say it's not a file/directory) */
12294 PyErr_Clear();
12295 return 0;
12296 }
12297 goto error;
12298 }
12299 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12300 if (!st_mode)
12301 goto error;
12302
12303 mode = PyLong_AsLong(st_mode);
12304 if (mode == -1 && PyErr_Occurred())
12305 goto error;
12306 Py_CLEAR(st_mode);
12307 Py_CLEAR(stat);
12308 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012309#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012310 }
12311 else if (is_symlink) {
12312 assert(mode_bits != S_IFLNK);
12313 result = 0;
12314 }
12315 else {
12316 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12317#ifdef MS_WINDOWS
12318 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12319 if (mode_bits == S_IFDIR)
12320 result = dir_bits != 0;
12321 else
12322 result = dir_bits == 0;
12323#else /* POSIX */
12324 if (mode_bits == S_IFDIR)
12325 result = self->d_type == DT_DIR;
12326 else
12327 result = self->d_type == DT_REG;
12328#endif
12329 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012330#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012331
12332 return result;
12333
12334error:
12335 Py_XDECREF(st_mode);
12336 Py_XDECREF(stat);
12337 return -1;
12338}
12339
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012340/*[clinic input]
12341os.DirEntry.is_dir -> bool
12342 *
12343 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012344
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012345Return True if the entry is a directory; cached per entry.
12346[clinic start generated code]*/
12347
12348static int
12349os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12350/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12351{
12352 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012353}
12354
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012355/*[clinic input]
12356os.DirEntry.is_file -> bool
12357 *
12358 follow_symlinks: bool = True
12359
12360Return True if the entry is a file; cached per entry.
12361[clinic start generated code]*/
12362
12363static int
12364os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12365/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012366{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012367 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012368}
12369
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012370/*[clinic input]
12371os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012372
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012373Return inode of the entry; cached per entry.
12374[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012375
12376static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012377os_DirEntry_inode_impl(DirEntry *self)
12378/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012379{
12380#ifdef MS_WINDOWS
12381 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012382 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012383 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012384 STRUCT_STAT stat;
12385 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012386
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012387 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012388 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012389 path = PyUnicode_AsUnicode(unicode);
12390 result = LSTAT(path, &stat);
12391 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012392
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012393 if (result != 0)
12394 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012395
12396 self->win32_file_index = stat.st_ino;
12397 self->got_file_index = 1;
12398 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012399 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12400 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012401#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012402 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12403 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012404#endif
12405}
12406
12407static PyObject *
12408DirEntry_repr(DirEntry *self)
12409{
12410 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12411}
12412
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012413/*[clinic input]
12414os.DirEntry.__fspath__
12415
12416Returns the path for the entry.
12417[clinic start generated code]*/
12418
Brett Cannon96881cd2016-06-10 14:37:21 -070012419static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012420os_DirEntry___fspath___impl(DirEntry *self)
12421/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012422{
12423 Py_INCREF(self->path);
12424 return self->path;
12425}
12426
Victor Stinner6036e442015-03-08 01:58:04 +010012427static PyMemberDef DirEntry_members[] = {
12428 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12429 "the entry's base filename, relative to scandir() \"path\" argument"},
12430 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12431 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12432 {NULL}
12433};
12434
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012435#include "clinic/posixmodule.c.h"
12436
Victor Stinner6036e442015-03-08 01:58:04 +010012437static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012438 OS_DIRENTRY_IS_DIR_METHODDEF
12439 OS_DIRENTRY_IS_FILE_METHODDEF
12440 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12441 OS_DIRENTRY_STAT_METHODDEF
12442 OS_DIRENTRY_INODE_METHODDEF
12443 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012444 {NULL}
12445};
12446
Benjamin Peterson5646de42015-04-12 17:56:34 -040012447static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012448 PyVarObject_HEAD_INIT(NULL, 0)
12449 MODNAME ".DirEntry", /* tp_name */
12450 sizeof(DirEntry), /* tp_basicsize */
12451 0, /* tp_itemsize */
12452 /* methods */
12453 (destructor)DirEntry_dealloc, /* tp_dealloc */
12454 0, /* tp_print */
12455 0, /* tp_getattr */
12456 0, /* tp_setattr */
12457 0, /* tp_compare */
12458 (reprfunc)DirEntry_repr, /* tp_repr */
12459 0, /* tp_as_number */
12460 0, /* tp_as_sequence */
12461 0, /* tp_as_mapping */
12462 0, /* tp_hash */
12463 0, /* tp_call */
12464 0, /* tp_str */
12465 0, /* tp_getattro */
12466 0, /* tp_setattro */
12467 0, /* tp_as_buffer */
12468 Py_TPFLAGS_DEFAULT, /* tp_flags */
12469 0, /* tp_doc */
12470 0, /* tp_traverse */
12471 0, /* tp_clear */
12472 0, /* tp_richcompare */
12473 0, /* tp_weaklistoffset */
12474 0, /* tp_iter */
12475 0, /* tp_iternext */
12476 DirEntry_methods, /* tp_methods */
12477 DirEntry_members, /* tp_members */
12478};
12479
12480#ifdef MS_WINDOWS
12481
12482static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012483join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012484{
12485 Py_ssize_t path_len;
12486 Py_ssize_t size;
12487 wchar_t *result;
12488 wchar_t ch;
12489
12490 if (!path_wide) { /* Default arg: "." */
12491 path_wide = L".";
12492 path_len = 1;
12493 }
12494 else {
12495 path_len = wcslen(path_wide);
12496 }
12497
12498 /* The +1's are for the path separator and the NUL */
12499 size = path_len + 1 + wcslen(filename) + 1;
12500 result = PyMem_New(wchar_t, size);
12501 if (!result) {
12502 PyErr_NoMemory();
12503 return NULL;
12504 }
12505 wcscpy(result, path_wide);
12506 if (path_len > 0) {
12507 ch = result[path_len - 1];
12508 if (ch != SEP && ch != ALTSEP && ch != L':')
12509 result[path_len++] = SEP;
12510 wcscpy(result + path_len, filename);
12511 }
12512 return result;
12513}
12514
12515static PyObject *
12516DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12517{
12518 DirEntry *entry;
12519 BY_HANDLE_FILE_INFORMATION file_info;
12520 ULONG reparse_tag;
12521 wchar_t *joined_path;
12522
12523 entry = PyObject_New(DirEntry, &DirEntryType);
12524 if (!entry)
12525 return NULL;
12526 entry->name = NULL;
12527 entry->path = NULL;
12528 entry->stat = NULL;
12529 entry->lstat = NULL;
12530 entry->got_file_index = 0;
12531
12532 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12533 if (!entry->name)
12534 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012535 if (path->narrow) {
12536 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12537 if (!entry->name)
12538 goto error;
12539 }
Victor Stinner6036e442015-03-08 01:58:04 +010012540
12541 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12542 if (!joined_path)
12543 goto error;
12544
12545 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12546 PyMem_Free(joined_path);
12547 if (!entry->path)
12548 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012549 if (path->narrow) {
12550 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12551 if (!entry->path)
12552 goto error;
12553 }
Victor Stinner6036e442015-03-08 01:58:04 +010012554
Steve Dowercc16be82016-09-08 10:35:16 -070012555 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012556 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12557
12558 return (PyObject *)entry;
12559
12560error:
12561 Py_DECREF(entry);
12562 return NULL;
12563}
12564
12565#else /* POSIX */
12566
12567static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012568join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012569{
12570 Py_ssize_t path_len;
12571 Py_ssize_t size;
12572 char *result;
12573
12574 if (!path_narrow) { /* Default arg: "." */
12575 path_narrow = ".";
12576 path_len = 1;
12577 }
12578 else {
12579 path_len = strlen(path_narrow);
12580 }
12581
12582 if (filename_len == -1)
12583 filename_len = strlen(filename);
12584
12585 /* The +1's are for the path separator and the NUL */
12586 size = path_len + 1 + filename_len + 1;
12587 result = PyMem_New(char, size);
12588 if (!result) {
12589 PyErr_NoMemory();
12590 return NULL;
12591 }
12592 strcpy(result, path_narrow);
12593 if (path_len > 0 && result[path_len - 1] != '/')
12594 result[path_len++] = '/';
12595 strcpy(result + path_len, filename);
12596 return result;
12597}
12598
12599static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012600DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012601 ino_t d_ino
12602#ifdef HAVE_DIRENT_D_TYPE
12603 , unsigned char d_type
12604#endif
12605 )
Victor Stinner6036e442015-03-08 01:58:04 +010012606{
12607 DirEntry *entry;
12608 char *joined_path;
12609
12610 entry = PyObject_New(DirEntry, &DirEntryType);
12611 if (!entry)
12612 return NULL;
12613 entry->name = NULL;
12614 entry->path = NULL;
12615 entry->stat = NULL;
12616 entry->lstat = NULL;
12617
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012618 if (path->fd != -1) {
12619 entry->dir_fd = path->fd;
12620 joined_path = NULL;
12621 }
12622 else {
12623 entry->dir_fd = DEFAULT_DIR_FD;
12624 joined_path = join_path_filename(path->narrow, name, name_len);
12625 if (!joined_path)
12626 goto error;
12627 }
Victor Stinner6036e442015-03-08 01:58:04 +010012628
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012629 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012630 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012631 if (joined_path)
12632 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012633 }
12634 else {
12635 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012636 if (joined_path)
12637 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012638 }
12639 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012640 if (!entry->name)
12641 goto error;
12642
12643 if (path->fd != -1) {
12644 entry->path = entry->name;
12645 Py_INCREF(entry->path);
12646 }
12647 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012648 goto error;
12649
Victor Stinner35a97c02015-03-08 02:59:09 +010012650#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012651 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012652#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012653 entry->d_ino = d_ino;
12654
12655 return (PyObject *)entry;
12656
12657error:
12658 Py_XDECREF(entry);
12659 return NULL;
12660}
12661
12662#endif
12663
12664
12665typedef struct {
12666 PyObject_HEAD
12667 path_t path;
12668#ifdef MS_WINDOWS
12669 HANDLE handle;
12670 WIN32_FIND_DATAW file_data;
12671 int first_time;
12672#else /* POSIX */
12673 DIR *dirp;
12674#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012675#ifdef HAVE_FDOPENDIR
12676 int fd;
12677#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012678} ScandirIterator;
12679
12680#ifdef MS_WINDOWS
12681
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012682static int
12683ScandirIterator_is_closed(ScandirIterator *iterator)
12684{
12685 return iterator->handle == INVALID_HANDLE_VALUE;
12686}
12687
Victor Stinner6036e442015-03-08 01:58:04 +010012688static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012689ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012690{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012691 HANDLE handle = iterator->handle;
12692
12693 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012694 return;
12695
Victor Stinner6036e442015-03-08 01:58:04 +010012696 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012697 Py_BEGIN_ALLOW_THREADS
12698 FindClose(handle);
12699 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012700}
12701
12702static PyObject *
12703ScandirIterator_iternext(ScandirIterator *iterator)
12704{
12705 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12706 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012707 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012708
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012709 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012710 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012711 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012712
12713 while (1) {
12714 if (!iterator->first_time) {
12715 Py_BEGIN_ALLOW_THREADS
12716 success = FindNextFileW(iterator->handle, file_data);
12717 Py_END_ALLOW_THREADS
12718 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012719 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012720 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012721 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012722 break;
12723 }
12724 }
12725 iterator->first_time = 0;
12726
12727 /* Skip over . and .. */
12728 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012729 wcscmp(file_data->cFileName, L"..") != 0) {
12730 entry = DirEntry_from_find_data(&iterator->path, file_data);
12731 if (!entry)
12732 break;
12733 return entry;
12734 }
Victor Stinner6036e442015-03-08 01:58:04 +010012735
12736 /* Loop till we get a non-dot directory or finish iterating */
12737 }
12738
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012739 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012740 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012741 return NULL;
12742}
12743
12744#else /* POSIX */
12745
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012746static int
12747ScandirIterator_is_closed(ScandirIterator *iterator)
12748{
12749 return !iterator->dirp;
12750}
12751
Victor Stinner6036e442015-03-08 01:58:04 +010012752static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012753ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012754{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012755 DIR *dirp = iterator->dirp;
12756
12757 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012758 return;
12759
Victor Stinner6036e442015-03-08 01:58:04 +010012760 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012761 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012762#ifdef HAVE_FDOPENDIR
12763 if (iterator->path.fd != -1)
12764 rewinddir(dirp);
12765#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012766 closedir(dirp);
12767 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012768 return;
12769}
12770
12771static PyObject *
12772ScandirIterator_iternext(ScandirIterator *iterator)
12773{
12774 struct dirent *direntp;
12775 Py_ssize_t name_len;
12776 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012777 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012778
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012779 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012780 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012781 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012782
12783 while (1) {
12784 errno = 0;
12785 Py_BEGIN_ALLOW_THREADS
12786 direntp = readdir(iterator->dirp);
12787 Py_END_ALLOW_THREADS
12788
12789 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012790 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012791 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012792 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012793 break;
12794 }
12795
12796 /* Skip over . and .. */
12797 name_len = NAMLEN(direntp);
12798 is_dot = direntp->d_name[0] == '.' &&
12799 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12800 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012801 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012802 name_len, direntp->d_ino
12803#ifdef HAVE_DIRENT_D_TYPE
12804 , direntp->d_type
12805#endif
12806 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012807 if (!entry)
12808 break;
12809 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012810 }
12811
12812 /* Loop till we get a non-dot directory or finish iterating */
12813 }
12814
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012815 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012816 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012817 return NULL;
12818}
12819
12820#endif
12821
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012822static PyObject *
12823ScandirIterator_close(ScandirIterator *self, PyObject *args)
12824{
12825 ScandirIterator_closedir(self);
12826 Py_RETURN_NONE;
12827}
12828
12829static PyObject *
12830ScandirIterator_enter(PyObject *self, PyObject *args)
12831{
12832 Py_INCREF(self);
12833 return self;
12834}
12835
12836static PyObject *
12837ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12838{
12839 ScandirIterator_closedir(self);
12840 Py_RETURN_NONE;
12841}
12842
Victor Stinner6036e442015-03-08 01:58:04 +010012843static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012844ScandirIterator_finalize(ScandirIterator *iterator)
12845{
12846 PyObject *error_type, *error_value, *error_traceback;
12847
12848 /* Save the current exception, if any. */
12849 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12850
12851 if (!ScandirIterator_is_closed(iterator)) {
12852 ScandirIterator_closedir(iterator);
12853
12854 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12855 "unclosed scandir iterator %R", iterator)) {
12856 /* Spurious errors can appear at shutdown */
12857 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12858 PyErr_WriteUnraisable((PyObject *) iterator);
12859 }
12860 }
12861 }
12862
Victor Stinner7bfa4092016-03-23 00:43:54 +010012863 path_cleanup(&iterator->path);
12864
12865 /* Restore the saved exception. */
12866 PyErr_Restore(error_type, error_value, error_traceback);
12867}
12868
12869static void
Victor Stinner6036e442015-03-08 01:58:04 +010012870ScandirIterator_dealloc(ScandirIterator *iterator)
12871{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012872 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12873 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012874
Victor Stinner6036e442015-03-08 01:58:04 +010012875 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12876}
12877
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012878static PyMethodDef ScandirIterator_methods[] = {
12879 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12880 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12881 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12882 {NULL}
12883};
12884
Benjamin Peterson5646de42015-04-12 17:56:34 -040012885static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012886 PyVarObject_HEAD_INIT(NULL, 0)
12887 MODNAME ".ScandirIterator", /* tp_name */
12888 sizeof(ScandirIterator), /* tp_basicsize */
12889 0, /* tp_itemsize */
12890 /* methods */
12891 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12892 0, /* tp_print */
12893 0, /* tp_getattr */
12894 0, /* tp_setattr */
12895 0, /* tp_compare */
12896 0, /* tp_repr */
12897 0, /* tp_as_number */
12898 0, /* tp_as_sequence */
12899 0, /* tp_as_mapping */
12900 0, /* tp_hash */
12901 0, /* tp_call */
12902 0, /* tp_str */
12903 0, /* tp_getattro */
12904 0, /* tp_setattro */
12905 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012906 Py_TPFLAGS_DEFAULT
12907 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012908 0, /* tp_doc */
12909 0, /* tp_traverse */
12910 0, /* tp_clear */
12911 0, /* tp_richcompare */
12912 0, /* tp_weaklistoffset */
12913 PyObject_SelfIter, /* tp_iter */
12914 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012915 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012916 0, /* tp_members */
12917 0, /* tp_getset */
12918 0, /* tp_base */
12919 0, /* tp_dict */
12920 0, /* tp_descr_get */
12921 0, /* tp_descr_set */
12922 0, /* tp_dictoffset */
12923 0, /* tp_init */
12924 0, /* tp_alloc */
12925 0, /* tp_new */
12926 0, /* tp_free */
12927 0, /* tp_is_gc */
12928 0, /* tp_bases */
12929 0, /* tp_mro */
12930 0, /* tp_cache */
12931 0, /* tp_subclasses */
12932 0, /* tp_weaklist */
12933 0, /* tp_del */
12934 0, /* tp_version_tag */
12935 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012936};
12937
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012938/*[clinic input]
12939os.scandir
12940
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012941 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012942
12943Return an iterator of DirEntry objects for given path.
12944
BNMetricsb9427072018-11-02 15:20:19 +000012945path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012946is bytes, the names of yielded DirEntry objects will also be bytes; in
12947all other circumstances they will be str.
12948
12949If path is None, uses the path='.'.
12950[clinic start generated code]*/
12951
Victor Stinner6036e442015-03-08 01:58:04 +010012952static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012953os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000012954/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012955{
12956 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012957#ifdef MS_WINDOWS
12958 wchar_t *path_strW;
12959#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012960 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012961#ifdef HAVE_FDOPENDIR
12962 int fd = -1;
12963#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012964#endif
12965
12966 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12967 if (!iterator)
12968 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012969
12970#ifdef MS_WINDOWS
12971 iterator->handle = INVALID_HANDLE_VALUE;
12972#else
12973 iterator->dirp = NULL;
12974#endif
12975
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012976 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012977 /* Move the ownership to iterator->path */
12978 path->object = NULL;
12979 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012980
12981#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012982 iterator->first_time = 1;
12983
12984 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12985 if (!path_strW)
12986 goto error;
12987
12988 Py_BEGIN_ALLOW_THREADS
12989 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12990 Py_END_ALLOW_THREADS
12991
12992 PyMem_Free(path_strW);
12993
12994 if (iterator->handle == INVALID_HANDLE_VALUE) {
12995 path_error(&iterator->path);
12996 goto error;
12997 }
12998#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012999 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013000#ifdef HAVE_FDOPENDIR
13001 if (path->fd != -1) {
13002 /* closedir() closes the FD, so we duplicate it */
13003 fd = _Py_dup(path->fd);
13004 if (fd == -1)
13005 goto error;
13006
13007 Py_BEGIN_ALLOW_THREADS
13008 iterator->dirp = fdopendir(fd);
13009 Py_END_ALLOW_THREADS
13010 }
13011 else
13012#endif
13013 {
13014 if (iterator->path.narrow)
13015 path_str = iterator->path.narrow;
13016 else
13017 path_str = ".";
13018
13019 Py_BEGIN_ALLOW_THREADS
13020 iterator->dirp = opendir(path_str);
13021 Py_END_ALLOW_THREADS
13022 }
Victor Stinner6036e442015-03-08 01:58:04 +010013023
13024 if (!iterator->dirp) {
13025 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013026#ifdef HAVE_FDOPENDIR
13027 if (fd != -1) {
13028 Py_BEGIN_ALLOW_THREADS
13029 close(fd);
13030 Py_END_ALLOW_THREADS
13031 }
13032#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013033 goto error;
13034 }
13035#endif
13036
13037 return (PyObject *)iterator;
13038
13039error:
13040 Py_DECREF(iterator);
13041 return NULL;
13042}
13043
Ethan Furman410ef8e2016-06-04 12:06:26 -070013044/*
13045 Return the file system path representation of the object.
13046
13047 If the object is str or bytes, then allow it to pass through with
13048 an incremented refcount. If the object defines __fspath__(), then
13049 return the result of that method. All other types raise a TypeError.
13050*/
13051PyObject *
13052PyOS_FSPath(PyObject *path)
13053{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013054 /* For error message reasons, this function is manually inlined in
13055 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013056 _Py_IDENTIFIER(__fspath__);
13057 PyObject *func = NULL;
13058 PyObject *path_repr = NULL;
13059
13060 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13061 Py_INCREF(path);
13062 return path;
13063 }
13064
13065 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13066 if (NULL == func) {
13067 return PyErr_Format(PyExc_TypeError,
13068 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013069 "not %.200s",
13070 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013071 }
13072
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013073 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013074 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013075 if (NULL == path_repr) {
13076 return NULL;
13077 }
13078
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013079 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13080 PyErr_Format(PyExc_TypeError,
13081 "expected %.200s.__fspath__() to return str or bytes, "
13082 "not %.200s", Py_TYPE(path)->tp_name,
13083 Py_TYPE(path_repr)->tp_name);
13084 Py_DECREF(path_repr);
13085 return NULL;
13086 }
13087
Ethan Furman410ef8e2016-06-04 12:06:26 -070013088 return path_repr;
13089}
13090
13091/*[clinic input]
13092os.fspath
13093
13094 path: object
13095
13096Return the file system path representation of the object.
13097
Brett Cannonb4f43e92016-06-09 14:32:08 -070013098If the object is str or bytes, then allow it to pass through as-is. If the
13099object defines __fspath__(), then return the result of that method. All other
13100types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013101[clinic start generated code]*/
13102
13103static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013104os_fspath_impl(PyObject *module, PyObject *path)
13105/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013106{
13107 return PyOS_FSPath(path);
13108}
Victor Stinner6036e442015-03-08 01:58:04 +010013109
Victor Stinner9b1f4742016-09-06 16:18:52 -070013110#ifdef HAVE_GETRANDOM_SYSCALL
13111/*[clinic input]
13112os.getrandom
13113
13114 size: Py_ssize_t
13115 flags: int=0
13116
13117Obtain a series of random bytes.
13118[clinic start generated code]*/
13119
13120static PyObject *
13121os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13122/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13123{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013124 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013125 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013126
13127 if (size < 0) {
13128 errno = EINVAL;
13129 return posix_error();
13130 }
13131
Victor Stinnerec2319c2016-09-20 23:00:59 +020013132 bytes = PyBytes_FromStringAndSize(NULL, size);
13133 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013134 PyErr_NoMemory();
13135 return NULL;
13136 }
13137
13138 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013139 n = syscall(SYS_getrandom,
13140 PyBytes_AS_STRING(bytes),
13141 PyBytes_GET_SIZE(bytes),
13142 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013143 if (n < 0 && errno == EINTR) {
13144 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013145 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013146 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013147
13148 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013149 continue;
13150 }
13151 break;
13152 }
13153
13154 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013155 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013156 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013157 }
13158
Victor Stinnerec2319c2016-09-20 23:00:59 +020013159 if (n != size) {
13160 _PyBytes_Resize(&bytes, n);
13161 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013162
13163 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013164
13165error:
13166 Py_DECREF(bytes);
13167 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013168}
13169#endif /* HAVE_GETRANDOM_SYSCALL */
13170
Steve Dower2438cdf2019-03-29 16:37:16 -070013171#ifdef MS_WINDOWS
13172/* bpo-36085: Helper functions for managing DLL search directories
13173 * on win32
13174 */
13175
13176typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13177typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13178
13179/*[clinic input]
13180os._add_dll_directory
13181
13182 path: path_t
13183
13184Add a path to the DLL search path.
13185
13186This search path is used when resolving dependencies for imported
13187extension modules (the module itself is resolved through sys.path),
13188and also by ctypes.
13189
13190Returns an opaque value that may be passed to os.remove_dll_directory
13191to remove this directory from the search path.
13192[clinic start generated code]*/
13193
13194static PyObject *
13195os__add_dll_directory_impl(PyObject *module, path_t *path)
13196/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13197{
13198 HMODULE hKernel32;
13199 PAddDllDirectory AddDllDirectory;
13200 DLL_DIRECTORY_COOKIE cookie = 0;
13201 DWORD err = 0;
13202
13203 /* For Windows 7, we have to load this. As this will be a fairly
13204 infrequent operation, just do it each time. Kernel32 is always
13205 loaded. */
13206 Py_BEGIN_ALLOW_THREADS
13207 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13208 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13209 hKernel32, "AddDllDirectory")) ||
13210 !(cookie = (*AddDllDirectory)(path->wide))) {
13211 err = GetLastError();
13212 }
13213 Py_END_ALLOW_THREADS
13214
13215 if (err) {
13216 return win32_error_object_err("add_dll_directory",
13217 path->object, err);
13218 }
13219
13220 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13221}
13222
13223/*[clinic input]
13224os._remove_dll_directory
13225
13226 cookie: object
13227
13228Removes a path from the DLL search path.
13229
13230The parameter is an opaque value that was returned from
13231os.add_dll_directory. You can only remove directories that you added
13232yourself.
13233[clinic start generated code]*/
13234
13235static PyObject *
13236os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13237/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13238{
13239 HMODULE hKernel32;
13240 PRemoveDllDirectory RemoveDllDirectory;
13241 DLL_DIRECTORY_COOKIE cookieValue;
13242 DWORD err = 0;
13243
13244 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13245 PyErr_SetString(PyExc_TypeError,
13246 "Provided cookie was not returned from os.add_dll_directory");
13247 return NULL;
13248 }
13249
13250 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13251 cookie, "DLL directory cookie");
13252
13253 /* For Windows 7, we have to load this. As this will be a fairly
13254 infrequent operation, just do it each time. Kernel32 is always
13255 loaded. */
13256 Py_BEGIN_ALLOW_THREADS
13257 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13258 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13259 hKernel32, "RemoveDllDirectory")) ||
13260 !(*RemoveDllDirectory)(cookieValue)) {
13261 err = GetLastError();
13262 }
13263 Py_END_ALLOW_THREADS
13264
13265 if (err) {
13266 return win32_error_object_err("remove_dll_directory",
13267 NULL, err);
13268 }
13269
13270 if (PyCapsule_SetName(cookie, NULL)) {
13271 return NULL;
13272 }
13273
13274 Py_RETURN_NONE;
13275}
13276
13277#endif
Larry Hastings31826802013-10-19 00:09:25 -070013278
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013279static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013280
13281 OS_STAT_METHODDEF
13282 OS_ACCESS_METHODDEF
13283 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013284 OS_CHDIR_METHODDEF
13285 OS_CHFLAGS_METHODDEF
13286 OS_CHMOD_METHODDEF
13287 OS_FCHMOD_METHODDEF
13288 OS_LCHMOD_METHODDEF
13289 OS_CHOWN_METHODDEF
13290 OS_FCHOWN_METHODDEF
13291 OS_LCHOWN_METHODDEF
13292 OS_LCHFLAGS_METHODDEF
13293 OS_CHROOT_METHODDEF
13294 OS_CTERMID_METHODDEF
13295 OS_GETCWD_METHODDEF
13296 OS_GETCWDB_METHODDEF
13297 OS_LINK_METHODDEF
13298 OS_LISTDIR_METHODDEF
13299 OS_LSTAT_METHODDEF
13300 OS_MKDIR_METHODDEF
13301 OS_NICE_METHODDEF
13302 OS_GETPRIORITY_METHODDEF
13303 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013304 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013305 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013306 OS_READLINK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013307 OS_RENAME_METHODDEF
13308 OS_REPLACE_METHODDEF
13309 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013310 OS_SYMLINK_METHODDEF
13311 OS_SYSTEM_METHODDEF
13312 OS_UMASK_METHODDEF
13313 OS_UNAME_METHODDEF
13314 OS_UNLINK_METHODDEF
13315 OS_REMOVE_METHODDEF
13316 OS_UTIME_METHODDEF
13317 OS_TIMES_METHODDEF
13318 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013319 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013320 OS_EXECV_METHODDEF
13321 OS_EXECVE_METHODDEF
13322 OS_SPAWNV_METHODDEF
13323 OS_SPAWNVE_METHODDEF
13324 OS_FORK1_METHODDEF
13325 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013326 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013327 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13328 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13329 OS_SCHED_GETPARAM_METHODDEF
13330 OS_SCHED_GETSCHEDULER_METHODDEF
13331 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13332 OS_SCHED_SETPARAM_METHODDEF
13333 OS_SCHED_SETSCHEDULER_METHODDEF
13334 OS_SCHED_YIELD_METHODDEF
13335 OS_SCHED_SETAFFINITY_METHODDEF
13336 OS_SCHED_GETAFFINITY_METHODDEF
13337 OS_OPENPTY_METHODDEF
13338 OS_FORKPTY_METHODDEF
13339 OS_GETEGID_METHODDEF
13340 OS_GETEUID_METHODDEF
13341 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013342#ifdef HAVE_GETGROUPLIST
13343 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13344#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013345 OS_GETGROUPS_METHODDEF
13346 OS_GETPID_METHODDEF
13347 OS_GETPGRP_METHODDEF
13348 OS_GETPPID_METHODDEF
13349 OS_GETUID_METHODDEF
13350 OS_GETLOGIN_METHODDEF
13351 OS_KILL_METHODDEF
13352 OS_KILLPG_METHODDEF
13353 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013354#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013355 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013356#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013357 OS_SETUID_METHODDEF
13358 OS_SETEUID_METHODDEF
13359 OS_SETREUID_METHODDEF
13360 OS_SETGID_METHODDEF
13361 OS_SETEGID_METHODDEF
13362 OS_SETREGID_METHODDEF
13363 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013364#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013365 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013366#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013367 OS_GETPGID_METHODDEF
13368 OS_SETPGRP_METHODDEF
13369 OS_WAIT_METHODDEF
13370 OS_WAIT3_METHODDEF
13371 OS_WAIT4_METHODDEF
13372 OS_WAITID_METHODDEF
13373 OS_WAITPID_METHODDEF
13374 OS_GETSID_METHODDEF
13375 OS_SETSID_METHODDEF
13376 OS_SETPGID_METHODDEF
13377 OS_TCGETPGRP_METHODDEF
13378 OS_TCSETPGRP_METHODDEF
13379 OS_OPEN_METHODDEF
13380 OS_CLOSE_METHODDEF
13381 OS_CLOSERANGE_METHODDEF
13382 OS_DEVICE_ENCODING_METHODDEF
13383 OS_DUP_METHODDEF
13384 OS_DUP2_METHODDEF
13385 OS_LOCKF_METHODDEF
13386 OS_LSEEK_METHODDEF
13387 OS_READ_METHODDEF
13388 OS_READV_METHODDEF
13389 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013390 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013391 OS_WRITE_METHODDEF
13392 OS_WRITEV_METHODDEF
13393 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013394 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013395#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013396 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013397 posix_sendfile__doc__},
13398#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013399 OS_FSTAT_METHODDEF
13400 OS_ISATTY_METHODDEF
13401 OS_PIPE_METHODDEF
13402 OS_PIPE2_METHODDEF
13403 OS_MKFIFO_METHODDEF
13404 OS_MKNOD_METHODDEF
13405 OS_MAJOR_METHODDEF
13406 OS_MINOR_METHODDEF
13407 OS_MAKEDEV_METHODDEF
13408 OS_FTRUNCATE_METHODDEF
13409 OS_TRUNCATE_METHODDEF
13410 OS_POSIX_FALLOCATE_METHODDEF
13411 OS_POSIX_FADVISE_METHODDEF
13412 OS_PUTENV_METHODDEF
13413 OS_UNSETENV_METHODDEF
13414 OS_STRERROR_METHODDEF
13415 OS_FCHDIR_METHODDEF
13416 OS_FSYNC_METHODDEF
13417 OS_SYNC_METHODDEF
13418 OS_FDATASYNC_METHODDEF
13419 OS_WCOREDUMP_METHODDEF
13420 OS_WIFCONTINUED_METHODDEF
13421 OS_WIFSTOPPED_METHODDEF
13422 OS_WIFSIGNALED_METHODDEF
13423 OS_WIFEXITED_METHODDEF
13424 OS_WEXITSTATUS_METHODDEF
13425 OS_WTERMSIG_METHODDEF
13426 OS_WSTOPSIG_METHODDEF
13427 OS_FSTATVFS_METHODDEF
13428 OS_STATVFS_METHODDEF
13429 OS_CONFSTR_METHODDEF
13430 OS_SYSCONF_METHODDEF
13431 OS_FPATHCONF_METHODDEF
13432 OS_PATHCONF_METHODDEF
13433 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013434 OS__GETFULLPATHNAME_METHODDEF
13435 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013436 OS__GETDISKUSAGE_METHODDEF
13437 OS__GETFINALPATHNAME_METHODDEF
13438 OS__GETVOLUMEPATHNAME_METHODDEF
13439 OS_GETLOADAVG_METHODDEF
13440 OS_URANDOM_METHODDEF
13441 OS_SETRESUID_METHODDEF
13442 OS_SETRESGID_METHODDEF
13443 OS_GETRESUID_METHODDEF
13444 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013445
Larry Hastings2f936352014-08-05 14:04:04 +100013446 OS_GETXATTR_METHODDEF
13447 OS_SETXATTR_METHODDEF
13448 OS_REMOVEXATTR_METHODDEF
13449 OS_LISTXATTR_METHODDEF
13450
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013451#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13452 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13453#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013454 OS_CPU_COUNT_METHODDEF
13455 OS_GET_INHERITABLE_METHODDEF
13456 OS_SET_INHERITABLE_METHODDEF
13457 OS_GET_HANDLE_INHERITABLE_METHODDEF
13458 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013459#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013460 OS_GET_BLOCKING_METHODDEF
13461 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013462#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013463 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013464 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013465 OS_GETRANDOM_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070013466#ifdef MS_WINDOWS
13467 OS__ADD_DLL_DIRECTORY_METHODDEF
13468 OS__REMOVE_DLL_DIRECTORY_METHODDEF
13469#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013470 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013471};
13472
Barry Warsaw4a342091996-12-19 23:50:02 +000013473static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013474all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013475{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013476#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013477 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013478#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013479#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013480 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013481#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013482#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013483 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013484#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013485#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013486 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013487#endif
Fred Drakec9680921999-12-13 16:37:25 +000013488#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013489 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013490#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013491#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013492 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013493#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013494#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013495 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013496#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013497#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013498 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013499#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013500#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013501 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013502#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013503#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013504 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013505#endif
13506#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013507 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013508#endif
13509#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013510 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013511#endif
13512#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013513 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013514#endif
13515#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013516 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013517#endif
13518#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013519 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013520#endif
13521#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013522 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013523#endif
13524#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013525 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013526#endif
13527#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013528 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013529#endif
13530#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013531 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013532#endif
13533#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013534 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013535#endif
13536#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013537 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013538#endif
13539#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013540 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013541#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013542#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013543 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013544#endif
13545#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013546 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013547#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013548#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013549 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013550#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013551#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013552 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013553#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013554#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013555#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013556 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013557#endif
13558#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013559 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013560#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013561#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013562#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013563 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013564#endif
13565#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013566 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013567#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013568#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013569 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013570#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013571#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013572 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013573#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013574#ifdef O_TMPFILE
13575 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13576#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013577#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013578 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013579#endif
13580#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013581 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013582#endif
13583#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013584 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013585#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013586#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013587 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013588#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013589#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013590 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013591#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013592
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013593
Jesus Cea94363612012-06-22 18:32:07 +020013594#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013595 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013596#endif
13597#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013598 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013599#endif
13600
Tim Peters5aa91602002-01-30 05:46:57 +000013601/* MS Windows */
13602#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013603 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013604 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013605#endif
13606#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013607 /* Optimize for short life (keep in memory). */
13608 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013609 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013610#endif
13611#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013612 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013613 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013614#endif
13615#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013616 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013617 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013618#endif
13619#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013620 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013621 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013622#endif
13623
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013624/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013625#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013626 /* Send a SIGIO signal whenever input or output
13627 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013628 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013629#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013630#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013631 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013632 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013633#endif
13634#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013635 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013636 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013637#endif
13638#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013639 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013640 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013641#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013642#ifdef O_NOLINKS
13643 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013644 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013645#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013646#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013647 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013648 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013649#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013650
Victor Stinner8c62be82010-05-06 00:08:46 +000013651 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013652#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013653 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013654#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013655#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013656 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013657#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013658#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013659 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013660#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013661#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013662 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013663#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013664#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013665 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013666#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013667#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013668 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013669#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013670#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013671 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013672#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013673#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013674 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013675#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013676#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013677 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013678#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013679#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013680 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013681#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013682#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013683 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013684#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013685#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013686 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013687#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013688#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013689 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013690#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013691#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013692 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013693#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013694#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013695 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013696#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013697#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013698 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013699#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013700#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013701 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013702#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013703
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013704 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013705#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013706 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013707#endif /* ST_RDONLY */
13708#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013709 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013710#endif /* ST_NOSUID */
13711
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013712 /* GNU extensions */
13713#ifdef ST_NODEV
13714 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13715#endif /* ST_NODEV */
13716#ifdef ST_NOEXEC
13717 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13718#endif /* ST_NOEXEC */
13719#ifdef ST_SYNCHRONOUS
13720 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13721#endif /* ST_SYNCHRONOUS */
13722#ifdef ST_MANDLOCK
13723 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13724#endif /* ST_MANDLOCK */
13725#ifdef ST_WRITE
13726 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13727#endif /* ST_WRITE */
13728#ifdef ST_APPEND
13729 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13730#endif /* ST_APPEND */
13731#ifdef ST_NOATIME
13732 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13733#endif /* ST_NOATIME */
13734#ifdef ST_NODIRATIME
13735 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13736#endif /* ST_NODIRATIME */
13737#ifdef ST_RELATIME
13738 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13739#endif /* ST_RELATIME */
13740
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013741 /* FreeBSD sendfile() constants */
13742#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013743 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013744#endif
13745#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013746 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013747#endif
13748#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013749 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013750#endif
13751
Ross Lagerwall7807c352011-03-17 20:20:30 +020013752 /* constants for posix_fadvise */
13753#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013754 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013755#endif
13756#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013757 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013758#endif
13759#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013760 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013761#endif
13762#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013763 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013764#endif
13765#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013766 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013767#endif
13768#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013769 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013770#endif
13771
13772 /* constants for waitid */
13773#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013774 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13775 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13776 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013777#endif
13778#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013779 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013780#endif
13781#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013782 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013783#endif
13784#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013785 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013786#endif
13787#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013788 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013789#endif
13790#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013791 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013792#endif
13793#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013794 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013795#endif
13796#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013797 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013798#endif
13799
13800 /* constants for lockf */
13801#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013802 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013803#endif
13804#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013805 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013806#endif
13807#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013808 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013809#endif
13810#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013811 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013812#endif
13813
Pablo Galindo4defba32018-01-27 16:16:37 +000013814#ifdef RWF_DSYNC
13815 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13816#endif
13817#ifdef RWF_HIPRI
13818 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13819#endif
13820#ifdef RWF_SYNC
13821 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13822#endif
13823#ifdef RWF_NOWAIT
13824 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13825#endif
13826
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013827/* constants for posix_spawn */
13828#ifdef HAVE_POSIX_SPAWN
13829 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
13830 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
13831 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
13832#endif
13833
Guido van Rossum246bc171999-02-01 23:54:31 +000013834#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013835 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13836 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13837 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13838 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13839 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013840#endif
13841
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013842#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013843#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013844 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013845#endif
13846#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013847 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013848#endif
13849#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013850 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013851#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013852#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013853 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013854#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013855#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013856 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013857#endif
13858#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013859 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013860#endif
13861#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013862 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013863#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013864#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013865 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013866#endif
13867#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013868 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013869#endif
13870#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013871 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013872#endif
13873#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013874 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013875#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013876#endif
13877
Benjamin Peterson9428d532011-09-14 11:45:52 -040013878#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013879 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13880 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13881 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013882#endif
13883
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013884#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013885 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013886#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013887#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013888 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013889#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013890#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013891 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013892#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013893#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013894 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013895#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013896#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013897 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013898#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013899#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013900 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013901#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013902#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013903 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013904#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013905#if HAVE_DECL_RTLD_MEMBER
13906 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13907#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013908
Victor Stinner9b1f4742016-09-06 16:18:52 -070013909#ifdef HAVE_GETRANDOM_SYSCALL
13910 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13911 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13912#endif
13913
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013914#if defined(__APPLE__)
13915 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
13916#endif
13917
Steve Dower2438cdf2019-03-29 16:37:16 -070013918#ifdef MS_WINDOWS
13919 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
13920 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
13921 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
13922 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
13923 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
13924#endif
13925
Victor Stinner8c62be82010-05-06 00:08:46 +000013926 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013927}
13928
13929
Martin v. Löwis1a214512008-06-11 05:26:20 +000013930static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013931 PyModuleDef_HEAD_INIT,
13932 MODNAME,
13933 posix__doc__,
13934 -1,
13935 posix_methods,
13936 NULL,
13937 NULL,
13938 NULL,
13939 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013940};
13941
13942
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013943static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013944
13945#ifdef HAVE_FACCESSAT
13946 "HAVE_FACCESSAT",
13947#endif
13948
13949#ifdef HAVE_FCHDIR
13950 "HAVE_FCHDIR",
13951#endif
13952
13953#ifdef HAVE_FCHMOD
13954 "HAVE_FCHMOD",
13955#endif
13956
13957#ifdef HAVE_FCHMODAT
13958 "HAVE_FCHMODAT",
13959#endif
13960
13961#ifdef HAVE_FCHOWN
13962 "HAVE_FCHOWN",
13963#endif
13964
Larry Hastings00964ed2013-08-12 13:49:30 -040013965#ifdef HAVE_FCHOWNAT
13966 "HAVE_FCHOWNAT",
13967#endif
13968
Larry Hastings9cf065c2012-06-22 16:30:09 -070013969#ifdef HAVE_FEXECVE
13970 "HAVE_FEXECVE",
13971#endif
13972
13973#ifdef HAVE_FDOPENDIR
13974 "HAVE_FDOPENDIR",
13975#endif
13976
Georg Brandl306336b2012-06-24 12:55:33 +020013977#ifdef HAVE_FPATHCONF
13978 "HAVE_FPATHCONF",
13979#endif
13980
Larry Hastings9cf065c2012-06-22 16:30:09 -070013981#ifdef HAVE_FSTATAT
13982 "HAVE_FSTATAT",
13983#endif
13984
13985#ifdef HAVE_FSTATVFS
13986 "HAVE_FSTATVFS",
13987#endif
13988
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013989#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013990 "HAVE_FTRUNCATE",
13991#endif
13992
Larry Hastings9cf065c2012-06-22 16:30:09 -070013993#ifdef HAVE_FUTIMENS
13994 "HAVE_FUTIMENS",
13995#endif
13996
13997#ifdef HAVE_FUTIMES
13998 "HAVE_FUTIMES",
13999#endif
14000
14001#ifdef HAVE_FUTIMESAT
14002 "HAVE_FUTIMESAT",
14003#endif
14004
14005#ifdef HAVE_LINKAT
14006 "HAVE_LINKAT",
14007#endif
14008
14009#ifdef HAVE_LCHFLAGS
14010 "HAVE_LCHFLAGS",
14011#endif
14012
14013#ifdef HAVE_LCHMOD
14014 "HAVE_LCHMOD",
14015#endif
14016
14017#ifdef HAVE_LCHOWN
14018 "HAVE_LCHOWN",
14019#endif
14020
14021#ifdef HAVE_LSTAT
14022 "HAVE_LSTAT",
14023#endif
14024
14025#ifdef HAVE_LUTIMES
14026 "HAVE_LUTIMES",
14027#endif
14028
14029#ifdef HAVE_MKDIRAT
14030 "HAVE_MKDIRAT",
14031#endif
14032
14033#ifdef HAVE_MKFIFOAT
14034 "HAVE_MKFIFOAT",
14035#endif
14036
14037#ifdef HAVE_MKNODAT
14038 "HAVE_MKNODAT",
14039#endif
14040
14041#ifdef HAVE_OPENAT
14042 "HAVE_OPENAT",
14043#endif
14044
14045#ifdef HAVE_READLINKAT
14046 "HAVE_READLINKAT",
14047#endif
14048
14049#ifdef HAVE_RENAMEAT
14050 "HAVE_RENAMEAT",
14051#endif
14052
14053#ifdef HAVE_SYMLINKAT
14054 "HAVE_SYMLINKAT",
14055#endif
14056
14057#ifdef HAVE_UNLINKAT
14058 "HAVE_UNLINKAT",
14059#endif
14060
14061#ifdef HAVE_UTIMENSAT
14062 "HAVE_UTIMENSAT",
14063#endif
14064
14065#ifdef MS_WINDOWS
14066 "MS_WINDOWS",
14067#endif
14068
14069 NULL
14070};
14071
14072
Mark Hammondfe51c6d2002-08-02 02:27:13 +000014073PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000014074INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014075{
Victor Stinner8c62be82010-05-06 00:08:46 +000014076 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014077 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014078 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000014079
Victor Stinner8c62be82010-05-06 00:08:46 +000014080 m = PyModule_Create(&posixmodule);
14081 if (m == NULL)
14082 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000014083
Victor Stinner8c62be82010-05-06 00:08:46 +000014084 /* Initialize environ dictionary */
14085 v = convertenviron();
14086 Py_XINCREF(v);
14087 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
14088 return NULL;
14089 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014090
Victor Stinner8c62be82010-05-06 00:08:46 +000014091 if (all_ins(m))
14092 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000014093
Victor Stinner8c62be82010-05-06 00:08:46 +000014094 if (setup_confname_tables(m))
14095 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000014096
Victor Stinner8c62be82010-05-06 00:08:46 +000014097 Py_INCREF(PyExc_OSError);
14098 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014099
Guido van Rossumb3d39562000-01-31 18:41:26 +000014100#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000014101 if (posix_putenv_garbage == NULL)
14102 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000014103#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000014104
Victor Stinner8c62be82010-05-06 00:08:46 +000014105 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020014106#if defined(HAVE_WAITID) && !defined(__APPLE__)
14107 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014108 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
14109 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014110 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014111 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014112#endif
14113
Christian Heimes25827622013-10-12 01:27:08 +020014114 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000014115 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14116 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14117 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014118 StatResultType = PyStructSequence_NewType(&stat_result_desc);
14119 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014120 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014121 }
14122 structseq_new = StatResultType->tp_new;
14123 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014124
Christian Heimes25827622013-10-12 01:27:08 +020014125 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014126 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
14127 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014128 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014129 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014130#ifdef NEED_TICKS_PER_SECOND
14131# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000014132 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014133# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000014134 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014135# else
Victor Stinner8c62be82010-05-06 00:08:46 +000014136 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014137# endif
14138#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014139
William Orr81574b82018-10-01 22:19:56 -070014140#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014141 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014142 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
14143 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014144 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014145 }
14146 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014147#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014148
14149 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014150 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
14151 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014152 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014153 }
Victor Stinner6036e442015-03-08 01:58:04 +010014154
14155 /* initialize scandir types */
14156 if (PyType_Ready(&ScandirIteratorType) < 0)
14157 return NULL;
14158 if (PyType_Ready(&DirEntryType) < 0)
14159 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014160 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014161#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014162 Py_INCREF((PyObject*) WaitidResultType);
14163 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020014164#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014165 Py_INCREF((PyObject*) StatResultType);
14166 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
14167 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000014168 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014169 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014170
14171#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014172 Py_INCREF(SchedParamType);
14173 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014174#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014175
Larry Hastings605a62d2012-06-24 04:33:36 -070014176 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014177 TimesResultType = PyStructSequence_NewType(&times_result_desc);
14178 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014179 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014180 }
14181 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014182
14183 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014184 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
14185 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014186 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014187 }
14188 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014189
Thomas Wouters477c8d52006-05-27 19:21:47 +000014190#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014191 /*
14192 * Step 2 of weak-linking support on Mac OS X.
14193 *
14194 * The code below removes functions that are not available on the
14195 * currently active platform.
14196 *
14197 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014198 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014199 * OSX 10.4.
14200 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014201#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014202 if (fstatvfs == NULL) {
14203 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14204 return NULL;
14205 }
14206 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014207#endif /* HAVE_FSTATVFS */
14208
14209#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014210 if (statvfs == NULL) {
14211 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14212 return NULL;
14213 }
14214 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014215#endif /* HAVE_STATVFS */
14216
14217# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014218 if (lchown == NULL) {
14219 if (PyObject_DelAttrString(m, "lchown") == -1) {
14220 return NULL;
14221 }
14222 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014223#endif /* HAVE_LCHOWN */
14224
14225
14226#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014227
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014228 Py_INCREF(TerminalSizeType);
14229 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014230
Larry Hastings6fe20b32012-04-19 15:07:49 -070014231 billion = PyLong_FromLong(1000000000);
14232 if (!billion)
14233 return NULL;
14234
Larry Hastings9cf065c2012-06-22 16:30:09 -070014235 /* suppress "function not used" warnings */
14236 {
14237 int ignored;
14238 fd_specified("", -1);
14239 follow_symlinks_specified("", 1);
14240 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14241 dir_fd_converter(Py_None, &ignored);
14242 dir_fd_unavailable(Py_None, &ignored);
14243 }
14244
14245 /*
14246 * provide list of locally available functions
14247 * so os.py can populate support_* lists
14248 */
14249 list = PyList_New(0);
14250 if (!list)
14251 return NULL;
14252 for (trace = have_functions; *trace; trace++) {
14253 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14254 if (!unicode)
14255 return NULL;
14256 if (PyList_Append(list, unicode))
14257 return NULL;
14258 Py_DECREF(unicode);
14259 }
14260 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014261
14262 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014263 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014264
14265 initialized = 1;
14266
Victor Stinner8c62be82010-05-06 00:08:46 +000014267 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014268}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014269
14270#ifdef __cplusplus
14271}
14272#endif